3 __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.10.4
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
31 #define INCLUDE_NLOHMANN_JSON_HPP_
33 #define NLOHMANN_JSON_VERSION_MAJOR 3
34 #define NLOHMANN_JSON_VERSION_MINOR 10
35 #define NLOHMANN_JSON_VERSION_PATCH 4
37 #include <algorithm> // all_of, find, for_each
38 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
39 #include <functional> // hash, less
40 #include <initializer_list> // initializer_list
42 #include <iosfwd> // istream, ostream
44 #include <iterator> // random_access_iterator_tag
45 #include <memory> // unique_ptr
46 #include <numeric> // accumulate
47 #include <string> // string, stoi, to_string
48 #include <utility> // declval, forward, move, pair, swap
49 #include <vector> // vector
51 // #include <nlohmann/adl_serializer.hpp>
54 #include <type_traits>
57 // #include <nlohmann/detail/conversions/from_json.hpp>
60 #include <algorithm> // transform
61 #include <array> // array
62 #include <forward_list> // forward_list
63 #include <iterator> // inserter, front_inserter, end
65 #include <string> // string
66 #include <tuple> // tuple, make_tuple
67 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
68 #include <unordered_map> // unordered_map
69 #include <utility> // pair, declval
70 #include <valarray> // valarray
72 // #include <nlohmann/detail/exceptions.hpp>
75 #include <exception> // exception
76 #include <stdexcept> // runtime_error
77 #include <string> // to_string
78 #include <vector> // vector
80 // #include <nlohmann/detail/value_t.hpp>
83 #include <array> // array
84 #include <cstddef> // size_t
85 #include <cstdint> // uint8_t
86 #include <string> // string
92 ///////////////////////////
93 // JSON type enumeration //
94 ///////////////////////////
97 @brief the JSON type enumeration
99 This enumeration collects the different JSON types. It is internally used to
100 distinguish the stored values, and the functions @ref basic_json::is_null(),
101 @ref basic_json::is_object(), @ref basic_json::is_array(),
102 @ref basic_json::is_string(), @ref basic_json::is_boolean(),
103 @ref basic_json::is_number() (with @ref basic_json::is_number_integer(),
104 @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()),
105 @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and
106 @ref basic_json::is_structured() rely on it.
108 @note There are three enumeration entries (number_integer, number_unsigned, and
109 number_float), because the library distinguishes these three types for numbers:
110 @ref basic_json::number_unsigned_t is used for unsigned integers,
111 @ref basic_json::number_integer_t is used for signed integers, and
112 @ref basic_json::number_float_t is used for floating-point numbers or to
113 approximate integers which do not fit in the limits of their respective type.
115 @sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON
116 value with the default value for a given type
120 enum class value_t : std::uint8_t
122 null, ///< null value
123 object, ///< object (unordered set of name/value pairs)
124 array, ///< array (ordered collection of values)
125 string, ///< string value
126 boolean, ///< boolean value
127 number_integer, ///< number value (signed integer)
128 number_unsigned, ///< number value (unsigned integer)
129 number_float, ///< number value (floating-point)
130 binary, ///< binary array (ordered collection of bytes)
131 discarded ///< discarded by the parser callback function
135 @brief comparison operator for JSON types
137 Returns an ordering that is similar to Python:
138 - order: null < boolean < number < object < array < string < binary
139 - furthermore, each type is not smaller than itself
140 - discarded values are not comparable
141 - binary is represented as a b"" string in python and directly comparable to a
142 string; however, making a binary array directly comparable with a string would
143 be surprising behavior in a JSON file.
147 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
149 static constexpr std::array<std::uint8_t, 9> order = {{
150 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
151 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
156 const auto l_index = static_cast<std::size_t>(lhs);
157 const auto r_index = static_cast<std::size_t>(rhs);
158 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
160 } // namespace detail
161 } // namespace nlohmann
163 // #include <nlohmann/detail/string_escape.hpp>
167 // #include <nlohmann/detail/macro_scope.hpp>
170 #include <utility> // declval, pair
171 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
174 /* Hedley - https://nemequ.github.io/hedley
175 * Created by Evan Nemerson <evan@nemerson.com>
177 * To the extent possible under law, the author(s) have dedicated all
178 * copyright and related and neighboring rights to this software to
179 * the public domain worldwide. This software is distributed without
182 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
183 * SPDX-License-Identifier: CC0-1.0
186 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
187 #if defined(JSON_HEDLEY_VERSION)
188 #undef JSON_HEDLEY_VERSION
190 #define JSON_HEDLEY_VERSION 15
192 #if defined(JSON_HEDLEY_STRINGIFY_EX)
193 #undef JSON_HEDLEY_STRINGIFY_EX
195 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
197 #if defined(JSON_HEDLEY_STRINGIFY)
198 #undef JSON_HEDLEY_STRINGIFY
200 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
202 #if defined(JSON_HEDLEY_CONCAT_EX)
203 #undef JSON_HEDLEY_CONCAT_EX
205 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
207 #if defined(JSON_HEDLEY_CONCAT)
208 #undef JSON_HEDLEY_CONCAT
210 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
212 #if defined(JSON_HEDLEY_CONCAT3_EX)
213 #undef JSON_HEDLEY_CONCAT3_EX
215 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
217 #if defined(JSON_HEDLEY_CONCAT3)
218 #undef JSON_HEDLEY_CONCAT3
220 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
222 #if defined(JSON_HEDLEY_VERSION_ENCODE)
223 #undef JSON_HEDLEY_VERSION_ENCODE
225 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
227 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
228 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
230 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
232 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
233 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
235 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
237 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
238 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
240 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
242 #if defined(JSON_HEDLEY_GNUC_VERSION)
243 #undef JSON_HEDLEY_GNUC_VERSION
245 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
246 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
247 #elif defined(__GNUC__)
248 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
251 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
252 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
254 #if defined(JSON_HEDLEY_GNUC_VERSION)
255 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
257 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
260 #if defined(JSON_HEDLEY_MSVC_VERSION)
261 #undef JSON_HEDLEY_MSVC_VERSION
263 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
264 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
265 #elif defined(_MSC_FULL_VER) && !defined(__ICL)
266 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
267 #elif defined(_MSC_VER) && !defined(__ICL)
268 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
271 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
272 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
274 #if !defined(JSON_HEDLEY_MSVC_VERSION)
275 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
276 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
277 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
278 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
279 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
281 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
284 #if defined(JSON_HEDLEY_INTEL_VERSION)
285 #undef JSON_HEDLEY_INTEL_VERSION
287 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
288 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
289 #elif defined(__INTEL_COMPILER) && !defined(__ICL)
290 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
293 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
294 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
296 #if defined(JSON_HEDLEY_INTEL_VERSION)
297 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
299 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
302 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
303 #undef JSON_HEDLEY_INTEL_CL_VERSION
305 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
306 #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
309 #if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
310 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
312 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
313 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
315 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
318 #if defined(JSON_HEDLEY_PGI_VERSION)
319 #undef JSON_HEDLEY_PGI_VERSION
321 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
322 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
325 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
326 #undef JSON_HEDLEY_PGI_VERSION_CHECK
328 #if defined(JSON_HEDLEY_PGI_VERSION)
329 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
331 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
334 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
335 #undef JSON_HEDLEY_SUNPRO_VERSION
337 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
338 #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)
339 #elif defined(__SUNPRO_C)
340 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
341 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
342 #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)
343 #elif defined(__SUNPRO_CC)
344 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
347 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
348 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
350 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
351 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
353 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
356 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
357 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
359 #if defined(__EMSCRIPTEN__)
360 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
363 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
364 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
366 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
367 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
369 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
372 #if defined(JSON_HEDLEY_ARM_VERSION)
373 #undef JSON_HEDLEY_ARM_VERSION
375 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
376 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
377 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
378 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
381 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
382 #undef JSON_HEDLEY_ARM_VERSION_CHECK
384 #if defined(JSON_HEDLEY_ARM_VERSION)
385 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
387 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
390 #if defined(JSON_HEDLEY_IBM_VERSION)
391 #undef JSON_HEDLEY_IBM_VERSION
393 #if defined(__ibmxl__)
394 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
395 #elif defined(__xlC__) && defined(__xlC_ver__)
396 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
397 #elif defined(__xlC__)
398 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
401 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
402 #undef JSON_HEDLEY_IBM_VERSION_CHECK
404 #if defined(JSON_HEDLEY_IBM_VERSION)
405 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
407 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
410 #if defined(JSON_HEDLEY_TI_VERSION)
411 #undef JSON_HEDLEY_TI_VERSION
414 defined(__TI_COMPILER_VERSION__) && \
416 defined(__TMS470__) || defined(__TI_ARM__) || \
417 defined(__MSP430__) || \
418 defined(__TMS320C2000__) \
420 #if (__TI_COMPILER_VERSION__ >= 16000000)
421 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
425 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
426 #undef JSON_HEDLEY_TI_VERSION_CHECK
428 #if defined(JSON_HEDLEY_TI_VERSION)
429 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
431 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
434 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
435 #undef JSON_HEDLEY_TI_CL2000_VERSION
437 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
438 #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
441 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
442 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
444 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
445 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
447 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
450 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
451 #undef JSON_HEDLEY_TI_CL430_VERSION
453 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
454 #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
457 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
458 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
460 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
461 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
463 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
466 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
467 #undef JSON_HEDLEY_TI_ARMCL_VERSION
469 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
470 #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
473 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
474 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
476 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
477 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
479 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
482 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
483 #undef JSON_HEDLEY_TI_CL6X_VERSION
485 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
486 #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
489 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
490 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
492 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
493 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
495 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
498 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
499 #undef JSON_HEDLEY_TI_CL7X_VERSION
501 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
502 #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
505 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
506 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
508 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
509 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
511 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
514 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
515 #undef JSON_HEDLEY_TI_CLPRU_VERSION
517 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
518 #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
521 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
522 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
524 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
525 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
527 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
530 #if defined(JSON_HEDLEY_CRAY_VERSION)
531 #undef JSON_HEDLEY_CRAY_VERSION
534 #if defined(_RELEASE_PATCHLEVEL)
535 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
537 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
541 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
542 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
544 #if defined(JSON_HEDLEY_CRAY_VERSION)
545 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
547 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
550 #if defined(JSON_HEDLEY_IAR_VERSION)
551 #undef JSON_HEDLEY_IAR_VERSION
553 #if defined(__IAR_SYSTEMS_ICC__)
555 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
557 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
561 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
562 #undef JSON_HEDLEY_IAR_VERSION_CHECK
564 #if defined(JSON_HEDLEY_IAR_VERSION)
565 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
567 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
570 #if defined(JSON_HEDLEY_TINYC_VERSION)
571 #undef JSON_HEDLEY_TINYC_VERSION
573 #if defined(__TINYC__)
574 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
577 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
578 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
580 #if defined(JSON_HEDLEY_TINYC_VERSION)
581 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
583 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
586 #if defined(JSON_HEDLEY_DMC_VERSION)
587 #undef JSON_HEDLEY_DMC_VERSION
590 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
593 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
594 #undef JSON_HEDLEY_DMC_VERSION_CHECK
596 #if defined(JSON_HEDLEY_DMC_VERSION)
597 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
599 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
602 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
603 #undef JSON_HEDLEY_COMPCERT_VERSION
605 #if defined(__COMPCERT_VERSION__)
606 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
609 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
610 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
612 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
613 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
615 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
618 #if defined(JSON_HEDLEY_PELLES_VERSION)
619 #undef JSON_HEDLEY_PELLES_VERSION
621 #if defined(__POCC__)
622 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
625 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
626 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
628 #if defined(JSON_HEDLEY_PELLES_VERSION)
629 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
631 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
634 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
635 #undef JSON_HEDLEY_MCST_LCC_VERSION
637 #if defined(__LCC__) && defined(__LCC_MINOR__)
638 #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
641 #if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
642 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
644 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
645 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
647 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
650 #if defined(JSON_HEDLEY_GCC_VERSION)
651 #undef JSON_HEDLEY_GCC_VERSION
654 defined(JSON_HEDLEY_GNUC_VERSION) && \
655 !defined(__clang__) && \
656 !defined(JSON_HEDLEY_INTEL_VERSION) && \
657 !defined(JSON_HEDLEY_PGI_VERSION) && \
658 !defined(JSON_HEDLEY_ARM_VERSION) && \
659 !defined(JSON_HEDLEY_CRAY_VERSION) && \
660 !defined(JSON_HEDLEY_TI_VERSION) && \
661 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
662 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
663 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
664 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
665 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
666 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
667 !defined(__COMPCERT__) && \
668 !defined(JSON_HEDLEY_MCST_LCC_VERSION)
669 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
672 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
673 #undef JSON_HEDLEY_GCC_VERSION_CHECK
675 #if defined(JSON_HEDLEY_GCC_VERSION)
676 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
678 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
681 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
682 #undef JSON_HEDLEY_HAS_ATTRIBUTE
685 defined(__has_attribute) && \
687 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
689 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
691 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
694 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
695 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
697 #if defined(__has_attribute)
698 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
700 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
703 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
704 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
706 #if defined(__has_attribute)
707 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
709 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
712 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
713 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
716 defined(__has_cpp_attribute) && \
717 defined(__cplusplus) && \
718 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
719 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
721 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
724 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
725 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
727 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
728 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
730 !defined(JSON_HEDLEY_PGI_VERSION) && \
731 !defined(JSON_HEDLEY_IAR_VERSION) && \
732 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
733 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
734 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
736 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
739 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
740 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
742 #if defined(__has_cpp_attribute) && defined(__cplusplus)
743 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
745 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
748 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
749 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
751 #if defined(__has_cpp_attribute) && defined(__cplusplus)
752 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
754 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
757 #if defined(JSON_HEDLEY_HAS_BUILTIN)
758 #undef JSON_HEDLEY_HAS_BUILTIN
760 #if defined(__has_builtin)
761 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
763 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
766 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
767 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
769 #if defined(__has_builtin)
770 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
772 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
775 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
776 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
778 #if defined(__has_builtin)
779 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
781 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
784 #if defined(JSON_HEDLEY_HAS_FEATURE)
785 #undef JSON_HEDLEY_HAS_FEATURE
787 #if defined(__has_feature)
788 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
790 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
793 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
794 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
796 #if defined(__has_feature)
797 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
799 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
802 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
803 #undef JSON_HEDLEY_GCC_HAS_FEATURE
805 #if defined(__has_feature)
806 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
808 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
811 #if defined(JSON_HEDLEY_HAS_EXTENSION)
812 #undef JSON_HEDLEY_HAS_EXTENSION
814 #if defined(__has_extension)
815 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
817 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
820 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
821 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
823 #if defined(__has_extension)
824 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
826 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
829 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
830 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
832 #if defined(__has_extension)
833 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
835 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
838 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
839 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
841 #if defined(__has_declspec_attribute)
842 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
844 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
847 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
848 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
850 #if defined(__has_declspec_attribute)
851 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
853 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
856 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
857 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
859 #if defined(__has_declspec_attribute)
860 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
862 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
865 #if defined(JSON_HEDLEY_HAS_WARNING)
866 #undef JSON_HEDLEY_HAS_WARNING
868 #if defined(__has_warning)
869 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
871 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
874 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
875 #undef JSON_HEDLEY_GNUC_HAS_WARNING
877 #if defined(__has_warning)
878 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
880 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
883 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
884 #undef JSON_HEDLEY_GCC_HAS_WARNING
886 #if defined(__has_warning)
887 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
889 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
893 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
894 defined(__clang__) || \
895 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
896 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
897 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
898 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
899 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
900 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
901 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
902 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
903 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
904 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
905 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
906 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
907 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
908 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
909 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
910 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
911 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
912 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
913 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
915 #define JSON_HEDLEY_PRAGMA(value)
918 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
919 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
921 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
922 #undef JSON_HEDLEY_DIAGNOSTIC_POP
924 #if defined(__clang__)
925 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
926 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
927 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
928 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
929 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
930 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
931 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
932 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
934 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
935 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
936 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
937 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
938 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
939 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
940 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
942 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
943 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
944 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
945 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
946 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
947 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
948 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
949 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
950 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
951 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
952 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
954 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
955 #define JSON_HEDLEY_DIAGNOSTIC_POP
958 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
959 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
960 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
961 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
963 #if defined(__cplusplus)
964 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
965 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
966 # if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
967 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
968 JSON_HEDLEY_DIAGNOSTIC_PUSH \
969 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
970 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
971 _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
973 JSON_HEDLEY_DIAGNOSTIC_POP
975 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
976 JSON_HEDLEY_DIAGNOSTIC_PUSH \
977 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
978 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
980 JSON_HEDLEY_DIAGNOSTIC_POP
983 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
984 JSON_HEDLEY_DIAGNOSTIC_PUSH \
985 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
987 JSON_HEDLEY_DIAGNOSTIC_POP
991 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
992 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
995 #if defined(JSON_HEDLEY_CONST_CAST)
996 #undef JSON_HEDLEY_CONST_CAST
998 #if defined(__cplusplus)
999 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1001 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1002 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1003 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1004 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1005 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1006 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1008 JSON_HEDLEY_DIAGNOSTIC_POP \
1011 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1014 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
1015 #undef JSON_HEDLEY_REINTERPRET_CAST
1017 #if defined(__cplusplus)
1018 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1020 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1023 #if defined(JSON_HEDLEY_STATIC_CAST)
1024 #undef JSON_HEDLEY_STATIC_CAST
1026 #if defined(__cplusplus)
1027 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1029 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1032 #if defined(JSON_HEDLEY_CPP_CAST)
1033 #undef JSON_HEDLEY_CPP_CAST
1035 #if defined(__cplusplus)
1036 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1037 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1038 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1039 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1041 JSON_HEDLEY_DIAGNOSTIC_POP
1042 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1043 # define JSON_HEDLEY_CPP_CAST(T, expr) \
1044 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1045 _Pragma("diag_suppress=Pe137") \
1046 JSON_HEDLEY_DIAGNOSTIC_POP
1048 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1051 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1054 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1055 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1057 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1058 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1059 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1060 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1061 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1062 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1063 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1064 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1065 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1066 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1067 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1068 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1069 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1070 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1071 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1072 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1074 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1075 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1076 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1077 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1078 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1079 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1080 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1081 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1082 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1083 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1084 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1085 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1086 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1087 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1088 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1089 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1090 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1091 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1092 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1093 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1095 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1098 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1099 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1101 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1102 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1103 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1104 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1105 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1106 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1107 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1108 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1109 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1110 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1111 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1112 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1114 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1115 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1116 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1117 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1118 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1119 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1120 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1121 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1122 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1123 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1124 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1126 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1129 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1130 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1132 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1133 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1134 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1135 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1136 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1137 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1138 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1139 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1140 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1141 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1142 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1143 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1144 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1145 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1146 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1147 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1149 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1150 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1151 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1152 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1153 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1154 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1155 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1156 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1158 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1161 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1162 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1164 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1165 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1166 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1167 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1168 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1169 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1171 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1174 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1175 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1177 #if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1178 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1179 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1180 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1181 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1182 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1183 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1184 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1186 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1189 #if defined(JSON_HEDLEY_DEPRECATED)
1190 #undef JSON_HEDLEY_DEPRECATED
1192 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1193 #undef JSON_HEDLEY_DEPRECATED_FOR
1196 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1197 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1198 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1199 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1201 (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1202 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1203 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1204 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1205 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1206 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1207 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1208 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1209 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1210 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1211 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1212 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1213 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1214 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1215 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1216 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1217 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1219 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1220 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1221 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1222 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1223 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1225 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1227 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1229 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1230 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1231 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1232 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1233 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1234 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1235 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1236 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1238 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1239 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1240 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1241 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1242 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1243 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1244 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1245 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1247 #define JSON_HEDLEY_DEPRECATED(since)
1248 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1251 #if defined(JSON_HEDLEY_UNAVAILABLE)
1252 #undef JSON_HEDLEY_UNAVAILABLE
1255 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1256 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1257 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1258 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1259 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1261 #define JSON_HEDLEY_UNAVAILABLE(available_since)
1264 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1265 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1267 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1268 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1271 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1272 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1273 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1274 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1275 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1276 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1277 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1278 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1279 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1280 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1281 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1282 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1283 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1284 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1285 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1286 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1287 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1288 #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1289 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1290 #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1291 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1292 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1293 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1294 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1295 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1296 #elif defined(_Check_return_) /* SAL */
1297 #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1298 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1300 #define JSON_HEDLEY_WARN_UNUSED_RESULT
1301 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1304 #if defined(JSON_HEDLEY_SENTINEL)
1305 #undef JSON_HEDLEY_SENTINEL
1308 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1309 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1310 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1311 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1312 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1313 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1315 #define JSON_HEDLEY_SENTINEL(position)
1318 #if defined(JSON_HEDLEY_NO_RETURN)
1319 #undef JSON_HEDLEY_NO_RETURN
1321 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1322 #define JSON_HEDLEY_NO_RETURN __noreturn
1324 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1325 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1326 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1327 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1328 #define JSON_HEDLEY_NO_RETURN _Noreturn
1329 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1330 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1332 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1333 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1334 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1335 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1336 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1337 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1338 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1339 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1340 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1341 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1342 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1343 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1344 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1345 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1346 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1347 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1348 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1349 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1350 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1351 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1353 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1354 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1355 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1356 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1357 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1358 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1359 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1360 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1361 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1363 #define JSON_HEDLEY_NO_RETURN
1366 #if defined(JSON_HEDLEY_NO_ESCAPE)
1367 #undef JSON_HEDLEY_NO_ESCAPE
1369 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1370 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1372 #define JSON_HEDLEY_NO_ESCAPE
1375 #if defined(JSON_HEDLEY_UNREACHABLE)
1376 #undef JSON_HEDLEY_UNREACHABLE
1378 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1379 #undef JSON_HEDLEY_UNREACHABLE_RETURN
1381 #if defined(JSON_HEDLEY_ASSUME)
1382 #undef JSON_HEDLEY_ASSUME
1385 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1386 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1387 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1388 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1389 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1390 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1392 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1393 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1394 #if defined(__cplusplus)
1395 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1397 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1401 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1402 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1403 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1404 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1405 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1406 JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1407 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1408 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1409 #elif defined(JSON_HEDLEY_ASSUME)
1410 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1412 #if !defined(JSON_HEDLEY_ASSUME)
1413 #if defined(JSON_HEDLEY_UNREACHABLE)
1414 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1416 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1419 #if defined(JSON_HEDLEY_UNREACHABLE)
1421 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1422 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1423 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1425 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1428 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1430 #if !defined(JSON_HEDLEY_UNREACHABLE)
1431 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1434 JSON_HEDLEY_DIAGNOSTIC_PUSH
1435 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1436 #pragma clang diagnostic ignored "-Wpedantic"
1438 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1439 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1441 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1442 #if defined(__clang__)
1443 #pragma clang diagnostic ignored "-Wvariadic-macros"
1444 #elif defined(JSON_HEDLEY_GCC_VERSION)
1445 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1448 #if defined(JSON_HEDLEY_NON_NULL)
1449 #undef JSON_HEDLEY_NON_NULL
1452 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1453 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1454 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1455 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1456 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1458 #define JSON_HEDLEY_NON_NULL(...)
1460 JSON_HEDLEY_DIAGNOSTIC_POP
1462 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1463 #undef JSON_HEDLEY_PRINTF_FORMAT
1465 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1466 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1467 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1468 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1470 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1471 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1472 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1473 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1474 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1475 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1476 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1477 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1478 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1479 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1480 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1481 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1482 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1483 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1484 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1485 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1486 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1487 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1488 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1489 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1491 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1494 #if defined(JSON_HEDLEY_CONSTEXPR)
1495 #undef JSON_HEDLEY_CONSTEXPR
1497 #if defined(__cplusplus)
1498 #if __cplusplus >= 201103L
1499 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1502 #if !defined(JSON_HEDLEY_CONSTEXPR)
1503 #define JSON_HEDLEY_CONSTEXPR
1506 #if defined(JSON_HEDLEY_PREDICT)
1507 #undef JSON_HEDLEY_PREDICT
1509 #if defined(JSON_HEDLEY_LIKELY)
1510 #undef JSON_HEDLEY_LIKELY
1512 #if defined(JSON_HEDLEY_UNLIKELY)
1513 #undef JSON_HEDLEY_UNLIKELY
1515 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1516 #undef JSON_HEDLEY_UNPREDICTABLE
1518 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1519 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1522 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1523 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1524 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1525 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1526 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1527 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1528 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1529 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1531 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1532 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1533 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1534 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1535 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1536 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1537 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1538 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1539 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1540 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1541 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1542 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1543 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1544 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1545 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1546 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1547 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1548 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1549 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1551 double hedley_probability_ = (probability); \
1552 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1554 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1556 double hedley_probability_ = (probability); \
1557 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1559 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1560 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1562 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1563 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1564 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1565 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1566 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1568 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1569 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1572 #if defined(JSON_HEDLEY_MALLOC)
1573 #undef JSON_HEDLEY_MALLOC
1576 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1577 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1578 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1579 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1580 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1581 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1582 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1583 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1584 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1585 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1586 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1587 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1588 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1589 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1590 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1591 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1592 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1593 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1594 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1595 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1596 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1598 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1599 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1600 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1602 #define JSON_HEDLEY_MALLOC
1605 #if defined(JSON_HEDLEY_PURE)
1606 #undef JSON_HEDLEY_PURE
1609 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1610 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1611 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1612 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1613 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1614 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1615 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1616 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1617 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1618 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1619 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1620 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1621 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1622 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1623 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1624 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1625 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1626 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1627 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1628 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1629 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1630 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1631 #elif defined(__cplusplus) && \
1633 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1634 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1635 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1637 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1639 # define JSON_HEDLEY_PURE
1642 #if defined(JSON_HEDLEY_CONST)
1643 #undef JSON_HEDLEY_CONST
1646 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1647 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1648 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1649 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1650 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1651 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1652 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1653 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1654 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1655 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1656 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1657 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1658 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1659 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1660 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1661 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1662 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1663 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1664 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1665 #define JSON_HEDLEY_CONST __attribute__((__const__))
1667 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1668 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1670 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1673 #if defined(JSON_HEDLEY_RESTRICT)
1674 #undef JSON_HEDLEY_RESTRICT
1676 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1677 #define JSON_HEDLEY_RESTRICT restrict
1679 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1680 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1681 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1682 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1683 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1684 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1685 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1686 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1687 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1688 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1689 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1690 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1691 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1692 defined(__clang__) || \
1693 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1694 #define JSON_HEDLEY_RESTRICT __restrict
1695 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1696 #define JSON_HEDLEY_RESTRICT _Restrict
1698 #define JSON_HEDLEY_RESTRICT
1701 #if defined(JSON_HEDLEY_INLINE)
1702 #undef JSON_HEDLEY_INLINE
1705 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1706 (defined(__cplusplus) && (__cplusplus >= 199711L))
1707 #define JSON_HEDLEY_INLINE inline
1709 defined(JSON_HEDLEY_GCC_VERSION) || \
1710 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1711 #define JSON_HEDLEY_INLINE __inline__
1713 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1714 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1715 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1716 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1717 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1718 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1719 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1720 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1721 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1722 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1723 #define JSON_HEDLEY_INLINE __inline
1725 #define JSON_HEDLEY_INLINE
1728 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1729 #undef JSON_HEDLEY_ALWAYS_INLINE
1732 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1733 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1734 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1735 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1736 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1737 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1738 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1739 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1740 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1741 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1742 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1743 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1744 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1745 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1746 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1747 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1748 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1749 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1750 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1751 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1753 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1754 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1755 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1756 #elif defined(__cplusplus) && \
1758 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1759 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1760 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1761 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1762 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1763 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1765 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1766 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1767 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1769 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1772 #if defined(JSON_HEDLEY_NEVER_INLINE)
1773 #undef JSON_HEDLEY_NEVER_INLINE
1776 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1777 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1778 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1779 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1780 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1781 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1782 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1783 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1784 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1785 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1786 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1787 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1788 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1789 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1790 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1791 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1792 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1793 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1794 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1795 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1797 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1798 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1799 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1800 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1801 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1802 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1803 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1804 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1805 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1806 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1807 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1808 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1809 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1811 #define JSON_HEDLEY_NEVER_INLINE
1814 #if defined(JSON_HEDLEY_PRIVATE)
1815 #undef JSON_HEDLEY_PRIVATE
1817 #if defined(JSON_HEDLEY_PUBLIC)
1818 #undef JSON_HEDLEY_PUBLIC
1820 #if defined(JSON_HEDLEY_IMPORT)
1821 #undef JSON_HEDLEY_IMPORT
1823 #if defined(_WIN32) || defined(__CYGWIN__)
1824 # define JSON_HEDLEY_PRIVATE
1825 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1826 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1829 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1830 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1831 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1832 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1833 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1834 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1836 defined(__TI_EABI__) && \
1838 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1839 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1842 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1843 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1844 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1846 # define JSON_HEDLEY_PRIVATE
1847 # define JSON_HEDLEY_PUBLIC
1849 # define JSON_HEDLEY_IMPORT extern
1852 #if defined(JSON_HEDLEY_NO_THROW)
1853 #undef JSON_HEDLEY_NO_THROW
1856 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1857 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1858 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1859 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1860 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1862 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1863 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1864 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1865 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1867 #define JSON_HEDLEY_NO_THROW
1870 #if defined(JSON_HEDLEY_FALL_THROUGH)
1871 #undef JSON_HEDLEY_FALL_THROUGH
1874 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1875 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
1876 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1877 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1878 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1879 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1880 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1881 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1882 #elif defined(__fallthrough) /* SAL */
1883 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1885 #define JSON_HEDLEY_FALL_THROUGH
1888 #if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1889 #undef JSON_HEDLEY_RETURNS_NON_NULL
1892 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1893 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1894 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1895 #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1896 #elif defined(_Ret_notnull_) /* SAL */
1897 #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1899 #define JSON_HEDLEY_RETURNS_NON_NULL
1902 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1903 #undef JSON_HEDLEY_ARRAY_PARAM
1906 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1907 !defined(__STDC_NO_VLA__) && \
1908 !defined(__cplusplus) && \
1909 !defined(JSON_HEDLEY_PGI_VERSION) && \
1910 !defined(JSON_HEDLEY_TINYC_VERSION)
1911 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1913 #define JSON_HEDLEY_ARRAY_PARAM(name)
1916 #if defined(JSON_HEDLEY_IS_CONSTANT)
1917 #undef JSON_HEDLEY_IS_CONSTANT
1919 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1920 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1922 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
1923 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1924 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1925 #undef JSON_HEDLEY_IS_CONSTEXPR_
1928 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1929 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1930 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1931 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1932 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1933 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1934 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1935 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1936 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1937 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1938 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1940 #if !defined(__cplusplus)
1942 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1943 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1944 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1945 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1946 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1947 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1948 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1949 #if defined(__INTPTR_TYPE__)
1950 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1953 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1957 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1958 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1959 !defined(JSON_HEDLEY_PGI_VERSION) && \
1960 !defined(JSON_HEDLEY_IAR_VERSION)) || \
1961 (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1962 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1963 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1964 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1965 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1966 #if defined(__INTPTR_TYPE__)
1967 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1970 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1973 defined(JSON_HEDLEY_GCC_VERSION) || \
1974 defined(JSON_HEDLEY_INTEL_VERSION) || \
1975 defined(JSON_HEDLEY_TINYC_VERSION) || \
1976 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1977 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1978 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1979 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1980 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1981 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1983 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1987 ((void*) ((expr) * 0L) ) : \
1988 ((struct { char v[sizeof(void) * 2]; } *) 1) \
1994 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1995 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1996 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1998 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
2000 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2001 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2003 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2006 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2007 #undef JSON_HEDLEY_BEGIN_C_DECLS
2009 #if defined(JSON_HEDLEY_END_C_DECLS)
2010 #undef JSON_HEDLEY_END_C_DECLS
2012 #if defined(JSON_HEDLEY_C_DECL)
2013 #undef JSON_HEDLEY_C_DECL
2015 #if defined(__cplusplus)
2016 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2017 #define JSON_HEDLEY_END_C_DECLS }
2018 #define JSON_HEDLEY_C_DECL extern "C"
2020 #define JSON_HEDLEY_BEGIN_C_DECLS
2021 #define JSON_HEDLEY_END_C_DECLS
2022 #define JSON_HEDLEY_C_DECL
2025 #if defined(JSON_HEDLEY_STATIC_ASSERT)
2026 #undef JSON_HEDLEY_STATIC_ASSERT
2029 !defined(__cplusplus) && ( \
2030 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2031 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2032 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2033 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2034 defined(_Static_assert) \
2036 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2038 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2039 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2040 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2041 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2043 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2046 #if defined(JSON_HEDLEY_NULL)
2047 #undef JSON_HEDLEY_NULL
2049 #if defined(__cplusplus)
2050 #if __cplusplus >= 201103L
2051 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2053 #define JSON_HEDLEY_NULL NULL
2055 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2058 #define JSON_HEDLEY_NULL NULL
2060 #define JSON_HEDLEY_NULL ((void*) 0)
2063 #if defined(JSON_HEDLEY_MESSAGE)
2064 #undef JSON_HEDLEY_MESSAGE
2066 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2067 # define JSON_HEDLEY_MESSAGE(msg) \
2068 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2069 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2070 JSON_HEDLEY_PRAGMA(message msg) \
2071 JSON_HEDLEY_DIAGNOSTIC_POP
2073 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2074 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2075 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2076 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2077 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2078 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2079 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2080 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2081 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2083 # define JSON_HEDLEY_MESSAGE(msg)
2086 #if defined(JSON_HEDLEY_WARNING)
2087 #undef JSON_HEDLEY_WARNING
2089 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2090 # define JSON_HEDLEY_WARNING(msg) \
2091 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2092 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2093 JSON_HEDLEY_PRAGMA(clang warning msg) \
2094 JSON_HEDLEY_DIAGNOSTIC_POP
2096 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2097 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2098 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2099 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2101 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2102 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2103 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2105 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2108 #if defined(JSON_HEDLEY_REQUIRE)
2109 #undef JSON_HEDLEY_REQUIRE
2111 #if defined(JSON_HEDLEY_REQUIRE_MSG)
2112 #undef JSON_HEDLEY_REQUIRE_MSG
2114 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2115 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2116 # define JSON_HEDLEY_REQUIRE(expr) \
2117 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2118 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2119 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2120 JSON_HEDLEY_DIAGNOSTIC_POP
2121 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2122 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2123 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2124 __attribute__((diagnose_if(!(expr), msg, "error"))) \
2125 JSON_HEDLEY_DIAGNOSTIC_POP
2127 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2128 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2131 # define JSON_HEDLEY_REQUIRE(expr)
2132 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2135 #if defined(JSON_HEDLEY_FLAGS)
2136 #undef JSON_HEDLEY_FLAGS
2138 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2139 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2141 #define JSON_HEDLEY_FLAGS
2144 #if defined(JSON_HEDLEY_FLAGS_CAST)
2145 #undef JSON_HEDLEY_FLAGS_CAST
2147 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2148 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2149 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2150 _Pragma("warning(disable:188)") \
2152 JSON_HEDLEY_DIAGNOSTIC_POP \
2155 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2158 #if defined(JSON_HEDLEY_EMPTY_BASES)
2159 #undef JSON_HEDLEY_EMPTY_BASES
2162 (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2163 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2164 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2166 #define JSON_HEDLEY_EMPTY_BASES
2169 /* Remaining macros are deprecated. */
2171 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2172 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2174 #if defined(__clang__)
2175 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2177 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2180 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2181 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2183 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2185 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2186 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2188 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2190 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2191 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2193 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2195 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2196 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2198 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2200 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2201 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2203 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2205 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2206 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2208 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2210 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2211 #undef JSON_HEDLEY_CLANG_HAS_WARNING
2213 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2215 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2217 // #include <nlohmann/detail/meta/detected.hpp>
2220 #include <type_traits>
2222 // #include <nlohmann/detail/meta/void_t.hpp>
2229 template<typename ...Ts> struct make_void
2233 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2234 } // namespace detail
2235 } // namespace nlohmann
2238 // https://en.cppreference.com/w/cpp/experimental/is_detected
2245 nonesuch() = delete;
2246 ~nonesuch() = delete;
2247 nonesuch(nonesuch const&) = delete;
2248 nonesuch(nonesuch const&&) = delete;
2249 void operator=(nonesuch const&) = delete;
2250 void operator=(nonesuch&&) = delete;
2253 template<class Default,
2255 template<class...> class Op,
2259 using value_t = std::false_type;
2260 using type = Default;
2263 template<class Default, template<class...> class Op, class... Args>
2264 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2266 using value_t = std::true_type;
2267 using type = Op<Args...>;
2270 template<template<class...> class Op, class... Args>
2271 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2273 template<template<class...> class Op, class... Args>
2274 struct is_detected_lazy : is_detected<Op, Args...> { };
2276 template<template<class...> class Op, class... Args>
2277 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2279 template<class Default, template<class...> class Op, class... Args>
2280 using detected_or = detector<Default, void, Op, Args...>;
2282 template<class Default, template<class...> class Op, class... Args>
2283 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2285 template<class Expected, template<class...> class Op, class... Args>
2286 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2288 template<class To, template<class...> class Op, class... Args>
2289 using is_detected_convertible =
2290 std::is_convertible<detected_t<Op, Args...>, To>;
2291 } // namespace detail
2292 } // namespace nlohmann
2295 // This file contains all internal macro definitions
2296 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2298 // exclude unsupported compilers
2299 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2300 #if defined(__clang__)
2301 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2302 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2304 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2305 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2306 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2311 // C++ language standard detection
2312 // if the user manually specified the used c++ version this is skipped
2313 #if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2314 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2315 #define JSON_HAS_CPP_20
2316 #define JSON_HAS_CPP_17
2317 #define JSON_HAS_CPP_14
2318 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2319 #define JSON_HAS_CPP_17
2320 #define JSON_HAS_CPP_14
2321 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2322 #define JSON_HAS_CPP_14
2324 // the cpp 11 flag is always specified because it is the minimal required version
2325 #define JSON_HAS_CPP_11
2328 // disable documentation warnings on clang
2329 #if defined(__clang__)
2330 #pragma clang diagnostic push
2331 #pragma clang diagnostic ignored "-Wdocumentation"
2332 #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2335 // allow to disable exceptions
2336 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2337 #define JSON_THROW(exception) throw exception
2338 #define JSON_TRY try
2339 #define JSON_CATCH(exception) catch(exception)
2340 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2343 #define JSON_THROW(exception) std::abort()
2344 #define JSON_TRY if(true)
2345 #define JSON_CATCH(exception) if(false)
2346 #define JSON_INTERNAL_CATCH(exception) if(false)
2349 // override exception macros
2350 #if defined(JSON_THROW_USER)
2352 #define JSON_THROW JSON_THROW_USER
2354 #if defined(JSON_TRY_USER)
2356 #define JSON_TRY JSON_TRY_USER
2358 #if defined(JSON_CATCH_USER)
2360 #define JSON_CATCH JSON_CATCH_USER
2361 #undef JSON_INTERNAL_CATCH
2362 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2364 #if defined(JSON_INTERNAL_CATCH_USER)
2365 #undef JSON_INTERNAL_CATCH
2366 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2369 // allow to override assert
2370 #if !defined(JSON_ASSERT)
2371 #include <cassert> // assert
2372 #define JSON_ASSERT(x) assert(x)
2375 // allow to access some private functions (needed by the test suite)
2376 #if defined(JSON_TESTS_PRIVATE)
2377 #define JSON_PRIVATE_UNLESS_TESTED public
2379 #define JSON_PRIVATE_UNLESS_TESTED private
2383 @brief macro to briefly define a mapping between an enum and JSON
2384 @def NLOHMANN_JSON_SERIALIZE_ENUM
2385 @since version 3.4.0
2387 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2388 template<typename BasicJsonType> \
2389 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2391 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2392 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2393 auto it = std::find_if(std::begin(m), std::end(m), \
2394 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2396 return ej_pair.first == e; \
2398 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2400 template<typename BasicJsonType> \
2401 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2403 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2404 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2405 auto it = std::find_if(std::begin(m), std::end(m), \
2406 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2408 return ej_pair.second == j; \
2410 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2413 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2414 // may be removed in the future once the class is split.
2416 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2417 template<template<typename, typename, typename...> class ObjectType, \
2418 template<typename, typename...> class ArrayType, \
2419 class StringType, class BooleanType, class NumberIntegerType, \
2420 class NumberUnsignedType, class NumberFloatType, \
2421 template<typename> class AllocatorType, \
2422 template<typename, typename = void> class JSONSerializer, \
2425 #define NLOHMANN_BASIC_JSON_TPL \
2426 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2427 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2428 AllocatorType, JSONSerializer, BinaryType>
2430 // Macros to simplify conversion from/to types
2432 #define NLOHMANN_JSON_EXPAND( x ) x
2433 #define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2434 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2435 NLOHMANN_JSON_PASTE64, \
2436 NLOHMANN_JSON_PASTE63, \
2437 NLOHMANN_JSON_PASTE62, \
2438 NLOHMANN_JSON_PASTE61, \
2439 NLOHMANN_JSON_PASTE60, \
2440 NLOHMANN_JSON_PASTE59, \
2441 NLOHMANN_JSON_PASTE58, \
2442 NLOHMANN_JSON_PASTE57, \
2443 NLOHMANN_JSON_PASTE56, \
2444 NLOHMANN_JSON_PASTE55, \
2445 NLOHMANN_JSON_PASTE54, \
2446 NLOHMANN_JSON_PASTE53, \
2447 NLOHMANN_JSON_PASTE52, \
2448 NLOHMANN_JSON_PASTE51, \
2449 NLOHMANN_JSON_PASTE50, \
2450 NLOHMANN_JSON_PASTE49, \
2451 NLOHMANN_JSON_PASTE48, \
2452 NLOHMANN_JSON_PASTE47, \
2453 NLOHMANN_JSON_PASTE46, \
2454 NLOHMANN_JSON_PASTE45, \
2455 NLOHMANN_JSON_PASTE44, \
2456 NLOHMANN_JSON_PASTE43, \
2457 NLOHMANN_JSON_PASTE42, \
2458 NLOHMANN_JSON_PASTE41, \
2459 NLOHMANN_JSON_PASTE40, \
2460 NLOHMANN_JSON_PASTE39, \
2461 NLOHMANN_JSON_PASTE38, \
2462 NLOHMANN_JSON_PASTE37, \
2463 NLOHMANN_JSON_PASTE36, \
2464 NLOHMANN_JSON_PASTE35, \
2465 NLOHMANN_JSON_PASTE34, \
2466 NLOHMANN_JSON_PASTE33, \
2467 NLOHMANN_JSON_PASTE32, \
2468 NLOHMANN_JSON_PASTE31, \
2469 NLOHMANN_JSON_PASTE30, \
2470 NLOHMANN_JSON_PASTE29, \
2471 NLOHMANN_JSON_PASTE28, \
2472 NLOHMANN_JSON_PASTE27, \
2473 NLOHMANN_JSON_PASTE26, \
2474 NLOHMANN_JSON_PASTE25, \
2475 NLOHMANN_JSON_PASTE24, \
2476 NLOHMANN_JSON_PASTE23, \
2477 NLOHMANN_JSON_PASTE22, \
2478 NLOHMANN_JSON_PASTE21, \
2479 NLOHMANN_JSON_PASTE20, \
2480 NLOHMANN_JSON_PASTE19, \
2481 NLOHMANN_JSON_PASTE18, \
2482 NLOHMANN_JSON_PASTE17, \
2483 NLOHMANN_JSON_PASTE16, \
2484 NLOHMANN_JSON_PASTE15, \
2485 NLOHMANN_JSON_PASTE14, \
2486 NLOHMANN_JSON_PASTE13, \
2487 NLOHMANN_JSON_PASTE12, \
2488 NLOHMANN_JSON_PASTE11, \
2489 NLOHMANN_JSON_PASTE10, \
2490 NLOHMANN_JSON_PASTE9, \
2491 NLOHMANN_JSON_PASTE8, \
2492 NLOHMANN_JSON_PASTE7, \
2493 NLOHMANN_JSON_PASTE6, \
2494 NLOHMANN_JSON_PASTE5, \
2495 NLOHMANN_JSON_PASTE4, \
2496 NLOHMANN_JSON_PASTE3, \
2497 NLOHMANN_JSON_PASTE2, \
2498 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2499 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2500 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2501 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2502 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2503 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2504 #define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2505 #define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2506 #define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2507 #define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2508 #define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2509 #define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2510 #define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2511 #define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2512 #define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2513 #define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2514 #define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2515 #define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2516 #define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2517 #define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2518 #define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2519 #define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2520 #define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2521 #define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2522 #define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2523 #define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2524 #define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2525 #define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2526 #define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2527 #define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2528 #define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2529 #define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2530 #define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2531 #define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2532 #define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2533 #define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2534 #define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2535 #define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2536 #define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2537 #define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2538 #define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2539 #define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2540 #define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2541 #define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2542 #define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2543 #define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2544 #define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2545 #define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2546 #define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2547 #define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2548 #define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2549 #define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2550 #define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2551 #define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2552 #define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2553 #define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2554 #define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2555 #define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2556 #define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2557 #define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2558 #define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2559 #define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2560 #define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2561 #define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2563 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2564 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2568 @def NLOHMANN_DEFINE_TYPE_INTRUSIVE
2569 @since version 3.9.0
2571 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2572 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2573 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2577 @def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
2578 @since version 3.9.0
2580 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2581 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2582 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2585 // inspired from https://stackoverflow.com/a/26745591
2586 // allows to call any std function as if (e.g. with begin):
2587 // using std::begin; begin(x);
2589 // it allows using the detected idiom to retrieve the return type
2590 // of such an expression
2591 #define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2592 namespace detail { \
2593 using std::std_name; \
2595 template<typename... T> \
2596 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2599 namespace detail2 { \
2600 struct std_name##_tag \
2604 template<typename... T> \
2605 std_name##_tag std_name(T&&...); \
2607 template<typename... T> \
2608 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2610 template<typename... T> \
2611 struct would_call_std_##std_name \
2613 static constexpr auto const value = ::nlohmann::detail:: \
2614 is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2616 } /* namespace detail2 */ \
2618 template<typename... T> \
2619 struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2623 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2624 #define JSON_USE_IMPLICIT_CONVERSIONS 1
2627 #if JSON_USE_IMPLICIT_CONVERSIONS
2628 #define JSON_EXPLICIT
2630 #define JSON_EXPLICIT explicit
2633 #ifndef JSON_DIAGNOSTICS
2634 #define JSON_DIAGNOSTICS 0
2644 @brief replace all occurrences of a substring by another string
2646 @param[in,out] s the string to manipulate; changed so that all
2647 occurrences of @a f are replaced with @a t
2648 @param[in] f the substring to replace with @a t
2649 @param[in] t the string to replace @a f
2651 @pre The search string @a f must not be empty. **This precondition is
2652 enforced with an assertion.**
2654 @since version 2.0.0
2656 inline void replace_substring(std::string& s, const std::string& f,
2657 const std::string& t)
2659 JSON_ASSERT(!f.empty());
2660 for (auto pos = s.find(f); // find first occurrence of f
2661 pos != std::string::npos; // make sure f was found
2662 s.replace(pos, f.size(), t), // replace with t, and
2663 pos = s.find(f, pos + t.size())) // find next occurrence of f
2668 * @brief string escaping as described in RFC 6901 (Sect. 4)
2669 * @param[in] s string to escape
2670 * @return escaped string
2672 * Note the order of escaping "~" to "~0" and "/" to "~1" is important.
2674 inline std::string escape(std::string s)
2676 replace_substring(s, "~", "~0");
2677 replace_substring(s, "/", "~1");
2682 * @brief string unescaping as described in RFC 6901 (Sect. 4)
2683 * @param[in] s string to unescape
2684 * @return unescaped string
2686 * Note the order of escaping "~1" to "/" and "~0" to "~" is important.
2688 static void unescape(std::string& s)
2690 replace_substring(s, "~1", "/");
2691 replace_substring(s, "~0", "~");
2694 } // namespace detail
2695 } // namespace nlohmann
2697 // #include <nlohmann/detail/input/position_t.hpp>
2700 #include <cstddef> // size_t
2706 /// struct to capture the start position of the current token
2709 /// the total number of characters read
2710 std::size_t chars_read_total = 0;
2711 /// the number of characters read in the current line
2712 std::size_t chars_read_current_line = 0;
2713 /// the number of lines read
2714 std::size_t lines_read = 0;
2716 /// conversion to size_t to preserve SAX interface
2717 constexpr operator size_t() const
2719 return chars_read_total;
2723 } // namespace detail
2724 } // namespace nlohmann
2726 // #include <nlohmann/detail/macro_scope.hpp>
2738 @brief general exception of the @ref basic_json class
2740 This class is an extension of `std::exception` objects with a member @a id for
2741 exception ids. It is used as the base class for all exceptions thrown by the
2742 @ref basic_json class. This class can hence be used as "wildcard" to catch
2746 - @ref parse_error for exceptions indicating a parse error
2747 - @ref invalid_iterator for exceptions indicating errors with iterators
2748 - @ref type_error for exceptions indicating executing a member function with
2750 - @ref out_of_range for exceptions indicating access out of the defined range
2751 - @ref other_error for exceptions indicating other library errors
2754 @note To have nothrow-copy-constructible exceptions, we internally use
2755 `std::runtime_error` which can cope with arbitrary-length error messages.
2756 Intermediate strings are built with static functions and then passed to
2757 the actual constructor.
2760 @liveexample{The following code shows how arbitrary library exceptions can be
2763 @since version 3.0.0
2765 class exception : public std::exception
2768 /// returns the explanatory string
2769 const char* what() const noexcept override
2774 /// the id of the exception
2775 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
2778 JSON_HEDLEY_NON_NULL(3)
2779 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
2781 static std::string name(const std::string& ename, int id_)
2783 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2786 template<typename BasicJsonType>
2787 static std::string diagnostics(const BasicJsonType& leaf_element)
2789 #if JSON_DIAGNOSTICS
2790 std::vector<std::string> tokens;
2791 for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
2793 switch (current->m_parent->type())
2795 case value_t::array:
2797 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
2799 if (¤t->m_parent->m_value.array->operator[](i) == current)
2801 tokens.emplace_back(std::to_string(i));
2808 case value_t::object:
2810 for (const auto& element : *current->m_parent->m_value.object)
2812 if (&element.second == current)
2814 tokens.emplace_back(element.first.c_str());
2821 case value_t::null: // LCOV_EXCL_LINE
2822 case value_t::string: // LCOV_EXCL_LINE
2823 case value_t::boolean: // LCOV_EXCL_LINE
2824 case value_t::number_integer: // LCOV_EXCL_LINE
2825 case value_t::number_unsigned: // LCOV_EXCL_LINE
2826 case value_t::number_float: // LCOV_EXCL_LINE
2827 case value_t::binary: // LCOV_EXCL_LINE
2828 case value_t::discarded: // LCOV_EXCL_LINE
2829 default: // LCOV_EXCL_LINE
2830 break; // LCOV_EXCL_LINE
2839 return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
2840 [](const std::string & a, const std::string & b)
2842 return a + "/" + detail::escape(b);
2845 static_cast<void>(leaf_element);
2851 /// an exception object as storage for error messages
2852 std::runtime_error m;
2856 @brief exception indicating a parse error
2858 This exception is thrown by the library when a parse error occurs. Parse errors
2859 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
2860 as when using JSON Patch.
2862 Member @a byte holds the byte index of the last read character in the input
2865 Exceptions have ids 1xx.
2867 name / id | example message | description
2868 ------------------------------ | --------------- | -------------------------
2869 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.
2870 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.
2871 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.
2872 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.
2873 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.
2874 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`.
2875 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.
2876 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.
2877 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
2878 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.
2879 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.
2880 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.
2881 json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
2882 json.exception.parse_error.115 | parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A | A UBJSON high-precision number could not be parsed.
2884 @note For an input with n bytes, 1 is the index of the first character and n+1
2885 is the index of the terminating null byte or the end of file. This also
2886 holds true when reading a byte vector (CBOR or MessagePack).
2888 @liveexample{The following code shows how a `parse_error` exception can be
2889 caught.,parse_error}
2891 @sa - @ref exception for the base class of the library exceptions
2892 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2893 @sa - @ref type_error for exceptions indicating executing a member function with
2895 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2896 @sa - @ref other_error for exceptions indicating other library errors
2898 @since version 3.0.0
2900 class parse_error : public exception
2904 @brief create a parse error exception
2905 @param[in] id_ the id of the exception
2906 @param[in] pos the position where the error occurred (or with
2907 chars_read_total=0 if the position cannot be
2909 @param[in] what_arg the explanatory string
2910 @return parse_error object
2912 template<typename BasicJsonType>
2913 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
2915 std::string w = exception::name("parse_error", id_) + "parse error" +
2916 position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
2917 return {id_, pos.chars_read_total, w.c_str()};
2920 template<typename BasicJsonType>
2921 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
2923 std::string w = exception::name("parse_error", id_) + "parse error" +
2924 (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2925 ": " + exception::diagnostics(context) + what_arg;
2926 return {id_, byte_, w.c_str()};
2930 @brief byte index of the parse error
2932 The byte index of the last read character in the input file.
2934 @note For an input with n bytes, 1 is the index of the first character and
2935 n+1 is the index of the terminating null byte or the end of file.
2936 This also holds true when reading a byte vector (CBOR or MessagePack).
2938 const std::size_t byte;
2941 parse_error(int id_, std::size_t byte_, const char* what_arg)
2942 : exception(id_, what_arg), byte(byte_) {}
2944 static std::string position_string(const position_t& pos)
2946 return " at line " + std::to_string(pos.lines_read + 1) +
2947 ", column " + std::to_string(pos.chars_read_current_line);
2952 @brief exception indicating errors with iterators
2954 This exception is thrown if iterators passed to a library function do not match
2955 the expected semantics.
2957 Exceptions have ids 2xx.
2959 name / id | example message | description
2960 ----------------------------------- | --------------- | -------------------------
2961 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.
2962 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.
2963 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.
2964 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.
2965 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.
2966 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.
2967 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.
2968 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.
2969 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.
2970 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.
2971 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.
2972 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
2973 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
2974 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().
2976 @liveexample{The following code shows how an `invalid_iterator` exception can be
2977 caught.,invalid_iterator}
2979 @sa - @ref exception for the base class of the library exceptions
2980 @sa - @ref parse_error for exceptions indicating a parse error
2981 @sa - @ref type_error for exceptions indicating executing a member function with
2983 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2984 @sa - @ref other_error for exceptions indicating other library errors
2986 @since version 3.0.0
2988 class invalid_iterator : public exception
2991 template<typename BasicJsonType>
2992 static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
2994 std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
2995 return {id_, w.c_str()};
2999 JSON_HEDLEY_NON_NULL(3)
3000 invalid_iterator(int id_, const char* what_arg)
3001 : exception(id_, what_arg) {}
3005 @brief exception indicating executing a member function with a wrong type
3007 This exception is thrown in case of a type error; that is, a library function is
3008 executed on a JSON value whose type does not match the expected semantics.
3010 Exceptions have ids 3xx.
3012 name / id | example message | description
3013 ----------------------------- | --------------- | -------------------------
3014 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.
3015 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.
3016 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 &.
3017 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
3018 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
3019 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
3020 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
3021 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.
3022 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
3023 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
3024 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.
3025 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
3026 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.
3027 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
3028 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.
3029 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. |
3030 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) |
3032 @liveexample{The following code shows how a `type_error` exception can be
3035 @sa - @ref exception for the base class of the library exceptions
3036 @sa - @ref parse_error for exceptions indicating a parse error
3037 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
3038 @sa - @ref out_of_range for exceptions indicating access out of the defined range
3039 @sa - @ref other_error for exceptions indicating other library errors
3041 @since version 3.0.0
3043 class type_error : public exception
3046 template<typename BasicJsonType>
3047 static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3049 std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
3050 return {id_, w.c_str()};
3054 JSON_HEDLEY_NON_NULL(3)
3055 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3059 @brief exception indicating access out of the defined range
3061 This exception is thrown in case a library function is called on an input
3062 parameter that exceeds the expected range, for instance in case of array
3063 indices or nonexisting object keys.
3065 Exceptions have ids 4xx.
3067 name / id | example message | description
3068 ------------------------------- | --------------- | -------------------------
3069 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.
3070 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.
3071 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
3072 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
3073 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.
3074 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.
3075 json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. (until version 3.8.0) |
3076 json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
3077 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 |
3079 @liveexample{The following code shows how an `out_of_range` exception can be
3080 caught.,out_of_range}
3082 @sa - @ref exception for the base class of the library exceptions
3083 @sa - @ref parse_error for exceptions indicating a parse error
3084 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
3085 @sa - @ref type_error for exceptions indicating executing a member function with
3087 @sa - @ref other_error for exceptions indicating other library errors
3089 @since version 3.0.0
3091 class out_of_range : public exception
3094 template<typename BasicJsonType>
3095 static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
3097 std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
3098 return {id_, w.c_str()};
3102 JSON_HEDLEY_NON_NULL(3)
3103 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
3107 @brief exception indicating other library errors
3109 This exception is thrown in case of errors that cannot be classified with the
3110 other exception types.
3112 Exceptions have ids 5xx.
3114 name / id | example message | description
3115 ------------------------------ | --------------- | -------------------------
3116 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
3118 @sa - @ref exception for the base class of the library exceptions
3119 @sa - @ref parse_error for exceptions indicating a parse error
3120 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
3121 @sa - @ref type_error for exceptions indicating executing a member function with
3123 @sa - @ref out_of_range for exceptions indicating access out of the defined range
3125 @liveexample{The following code shows how an `other_error` exception can be
3126 caught.,other_error}
3128 @since version 3.0.0
3130 class other_error : public exception
3133 template<typename BasicJsonType>
3134 static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3136 std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
3137 return {id_, w.c_str()};
3141 JSON_HEDLEY_NON_NULL(3)
3142 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3144 } // namespace detail
3145 } // namespace nlohmann
3147 // #include <nlohmann/detail/macro_scope.hpp>
3149 // #include <nlohmann/detail/meta/cpp_future.hpp>
3152 #include <cstddef> // size_t
3153 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3154 #include <utility> // index_sequence, make_index_sequence, index_sequence_for
3156 // #include <nlohmann/detail/macro_scope.hpp>
3164 template<typename T>
3165 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3167 #ifdef JSON_HAS_CPP_14
3169 // the following utilities are natively available in C++14
3170 using std::enable_if_t;
3171 using std::index_sequence;
3172 using std::make_index_sequence;
3173 using std::index_sequence_for;
3177 // alias templates to reduce boilerplate
3178 template<bool B, typename T = void>
3179 using enable_if_t = typename std::enable_if<B, T>::type;
3181 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3182 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3184 //// START OF CODE FROM GOOGLE ABSEIL
3188 // Class template representing a compile-time integer sequence. An instantiation
3189 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3190 // type through its template arguments (which is a common need when
3191 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3192 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3196 // template< class T, T... Ints >
3197 // void user_function(integer_sequence<T, Ints...>);
3201 // // user_function's `T` will be deduced to `int` and `Ints...`
3202 // // will be deduced to `0, 1, 2, 3, 4`.
3203 // user_function(make_integer_sequence<int, 5>());
3205 template <typename T, T... Ints>
3206 struct integer_sequence
3208 using value_type = T;
3209 static constexpr std::size_t size() noexcept
3211 return sizeof...(Ints);
3217 // A helper template for an `integer_sequence` of `size_t`,
3218 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3219 // `std::index_sequence`.
3220 template <size_t... Ints>
3221 using index_sequence = integer_sequence<size_t, Ints...>;
3223 namespace utility_internal
3226 template <typename Seq, size_t SeqSize, size_t Rem>
3229 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3230 template <typename T, T... Ints, size_t SeqSize>
3231 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3233 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3236 template <typename T, T... Ints, size_t SeqSize>
3237 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3239 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3242 // Recursion helper for 'make_integer_sequence<T, N>'.
3243 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3244 template <typename T, size_t N>
3248 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3251 template <typename T>
3254 using type = integer_sequence<T>;
3257 } // namespace utility_internal
3259 // Compile-time sequences of integers
3261 // make_integer_sequence
3263 // This template alias is equivalent to
3264 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3265 // replacement for C++14's `std::make_integer_sequence`.
3266 template <typename T, T N>
3267 using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
3269 // make_index_sequence
3271 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3272 // and is designed to be a drop-in replacement for C++14's
3273 // `std::make_index_sequence`.
3275 using make_index_sequence = make_integer_sequence<size_t, N>;
3277 // index_sequence_for
3279 // Converts a typename pack into an index sequence of the same length, and
3280 // is designed to be a drop-in replacement for C++14's
3281 // `std::index_sequence_for()`
3282 template <typename... Ts>
3283 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
3285 //// END OF CODE FROM GOOGLE ABSEIL
3289 // dispatch utility (taken from ranges-v3)
3290 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3291 template<> struct priority_tag<0> {};
3293 // taken from ranges-v3
3294 template<typename T>
3297 static constexpr T value{};
3300 template<typename T>
3301 constexpr T static_const<T>::value;
3303 } // namespace detail
3304 } // namespace nlohmann
3306 // #include <nlohmann/detail/meta/identity_tag.hpp>
3313 // dispatching helper struct
3314 template <class T> struct identity_tag {};
3315 } // namespace detail
3316 } // namespace nlohmann
3318 // #include <nlohmann/detail/meta/type_traits.hpp>
3321 #include <limits> // numeric_limits
3322 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3323 #include <utility> // declval
3324 #include <tuple> // tuple
3326 // #include <nlohmann/detail/macro_scope.hpp>
3329 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3332 #include <iterator> // random_access_iterator_tag
3334 // #include <nlohmann/detail/meta/void_t.hpp>
3336 // #include <nlohmann/detail/meta/cpp_future.hpp>
3343 template<typename It, typename = void>
3344 struct iterator_types {};
3346 template<typename It>
3347 struct iterator_types <
3349 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3350 typename It::reference, typename It::iterator_category >>
3352 using difference_type = typename It::difference_type;
3353 using value_type = typename It::value_type;
3354 using pointer = typename It::pointer;
3355 using reference = typename It::reference;
3356 using iterator_category = typename It::iterator_category;
3359 // This is required as some compilers implement std::iterator_traits in a way that
3360 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3361 template<typename T, typename = void>
3362 struct iterator_traits
3366 template<typename T>
3367 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3372 template<typename T>
3373 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
3375 using iterator_category = std::random_access_iterator_tag;
3376 using value_type = T;
3377 using difference_type = ptrdiff_t;
3379 using reference = T&;
3381 } // namespace detail
3382 } // namespace nlohmann
3384 // #include <nlohmann/detail/meta/call_std/begin.hpp>
3387 // #include <nlohmann/detail/macro_scope.hpp>
3392 NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin);
3393 } // namespace nlohmann
3395 // #include <nlohmann/detail/meta/call_std/end.hpp>
3398 // #include <nlohmann/detail/macro_scope.hpp>
3403 NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end);
3404 } // namespace nlohmann
3406 // #include <nlohmann/detail/meta/cpp_future.hpp>
3408 // #include <nlohmann/detail/meta/detected.hpp>
3410 // #include <nlohmann/json_fwd.hpp>
3411 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3412 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3414 #include <cstdint> // int64_t, uint64_t
3415 #include <map> // map
3416 #include <memory> // allocator
3417 #include <string> // string
3418 #include <vector> // vector
3421 @brief namespace for Niels Lohmann
3422 @see https://github.com/nlohmann
3423 @since version 1.0.0
3428 @brief default JSONSerializer template argument
3430 This serializer ignores the template arguments and uses ADL
3431 ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
3434 template<typename T = void, typename SFINAE = void>
3435 struct adl_serializer;
3437 template<template<typename U, typename V, typename... Args> class ObjectType =
3439 template<typename U, typename... Args> class ArrayType = std::vector,
3440 class StringType = std::string, class BooleanType = bool,
3441 class NumberIntegerType = std::int64_t,
3442 class NumberUnsignedType = std::uint64_t,
3443 class NumberFloatType = double,
3444 template<typename U> class AllocatorType = std::allocator,
3445 template<typename T, typename SFINAE = void> class JSONSerializer =
3447 class BinaryType = std::vector<std::uint8_t>>
3453 A JSON pointer defines a string syntax for identifying a specific value
3454 within a JSON document. It can be used with functions `at` and
3455 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
3457 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
3459 @since version 2.0.0
3461 template<typename BasicJsonType>
3465 @brief default JSON class
3467 This type is the default specialization of the @ref basic_json class which
3468 uses the standard template types.
3470 @since version 1.0.0
3472 using json = basic_json<>;
3474 template<class Key, class T, class IgnoredLess, class Allocator>
3478 @brief ordered JSON class
3480 This type preserves the insertion order of object keys.
3482 @since version 3.9.0
3484 using ordered_json = basic_json<nlohmann::ordered_map>;
3486 } // namespace nlohmann
3488 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3494 @brief detail namespace with internal helper functions
3496 This namespace collects functions that should not be exposed,
3497 implementations of some @ref basic_json methods, and meta-programming helpers.
3499 @since version 2.1.0
3507 // Note to maintainers:
3509 // Every trait in this file expects a non CV-qualified type.
3510 // The only exceptions are in the 'aliases for detected' section
3511 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3513 // In this case, T has to be properly CV-qualified to constraint the function arguments
3514 // (e.g. to_json(BasicJsonType&, const T&))
3516 template<typename> struct is_basic_json : std::false_type {};
3518 NLOHMANN_BASIC_JSON_TPL_DECLARATION
3519 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3521 //////////////////////
3522 // json_ref helpers //
3523 //////////////////////
3529 struct is_json_ref : std::false_type {};
3531 template<typename T>
3532 struct is_json_ref<json_ref<T>> : std::true_type {};
3534 //////////////////////////
3535 // aliases for detected //
3536 //////////////////////////
3538 template<typename T>
3539 using mapped_type_t = typename T::mapped_type;
3541 template<typename T>
3542 using key_type_t = typename T::key_type;
3544 template<typename T>
3545 using value_type_t = typename T::value_type;
3547 template<typename T>
3548 using difference_type_t = typename T::difference_type;
3550 template<typename T>
3551 using pointer_t = typename T::pointer;
3553 template<typename T>
3554 using reference_t = typename T::reference;
3556 template<typename T>
3557 using iterator_category_t = typename T::iterator_category;
3559 template<typename T, typename... Args>
3560 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3562 template<typename T, typename... Args>
3563 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3565 template<typename T, typename U>
3566 using get_template_function = decltype(std::declval<T>().template get<U>());
3568 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3569 template<typename BasicJsonType, typename T, typename = void>
3570 struct has_from_json : std::false_type {};
3572 // trait checking if j.get<T> is valid
3573 // use this trait instead of std::is_constructible or std::is_convertible,
3574 // both rely on, or make use of implicit conversions, and thus fail when T
3575 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3576 template <typename BasicJsonType, typename T>
3579 static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3582 template<typename BasicJsonType, typename T>
3583 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3585 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3587 static constexpr bool value =
3588 is_detected_exact<void, from_json_function, serializer,
3589 const BasicJsonType&, T&>::value;
3592 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3593 // this overload is used for non-default-constructible user-defined-types
3594 template<typename BasicJsonType, typename T, typename = void>
3595 struct has_non_default_from_json : std::false_type {};
3597 template<typename BasicJsonType, typename T>
3598 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3600 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3602 static constexpr bool value =
3603 is_detected_exact<T, from_json_function, serializer,
3604 const BasicJsonType&>::value;
3607 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3608 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3609 template<typename BasicJsonType, typename T, typename = void>
3610 struct has_to_json : std::false_type {};
3612 template<typename BasicJsonType, typename T>
3613 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3615 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3617 static constexpr bool value =
3618 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3627 // https://en.cppreference.com/w/cpp/types/conjunction
3628 template<class...> struct conjunction : std::true_type { };
3629 template<class B1> struct conjunction<B1> : B1 { };
3630 template<class B1, class... Bn>
3631 struct conjunction<B1, Bn...>
3632 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3634 // https://en.cppreference.com/w/cpp/types/negation
3635 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3637 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3638 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3639 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3640 template <typename T>
3641 struct is_default_constructible : std::is_default_constructible<T> {};
3643 template <typename T1, typename T2>
3644 struct is_default_constructible<std::pair<T1, T2>>
3645 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3647 template <typename T1, typename T2>
3648 struct is_default_constructible<const std::pair<T1, T2>>
3649 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3651 template <typename... Ts>
3652 struct is_default_constructible<std::tuple<Ts...>>
3653 : conjunction<is_default_constructible<Ts>...> {};
3655 template <typename... Ts>
3656 struct is_default_constructible<const std::tuple<Ts...>>
3657 : conjunction<is_default_constructible<Ts>...> {};
3660 template <typename T, typename... Args>
3661 struct is_constructible : std::is_constructible<T, Args...> {};
3663 template <typename T1, typename T2>
3664 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3666 template <typename T1, typename T2>
3667 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3669 template <typename... Ts>
3670 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3672 template <typename... Ts>
3673 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3676 template<typename T, typename = void>
3677 struct is_iterator_traits : std::false_type {};
3679 template<typename T>
3680 struct is_iterator_traits<iterator_traits<T>>
3683 using traits = iterator_traits<T>;
3686 static constexpr auto value =
3687 is_detected<value_type_t, traits>::value &&
3688 is_detected<difference_type_t, traits>::value &&
3689 is_detected<pointer_t, traits>::value &&
3690 is_detected<iterator_category_t, traits>::value &&
3691 is_detected<reference_t, traits>::value;
3694 template<typename T>
3698 using t_ref = typename std::add_lvalue_reference<T>::type;
3700 using iterator = detected_t<result_of_begin, t_ref>;
3701 using sentinel = detected_t<result_of_end, t_ref>;
3703 // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3704 // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3705 // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3706 static constexpr auto is_iterator_begin =
3707 is_iterator_traits<iterator_traits<iterator>>::value;
3710 static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3713 template<typename R>
3714 using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3716 template<typename T>
3717 using range_value_t = value_type_t<iterator_traits<iterator_t<T>>>;
3719 // The following implementation of is_complete_type is taken from
3720 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3721 // and is written by Xiang Fan who agreed to using it in this library.
3723 template<typename T, typename = void>
3724 struct is_complete_type : std::false_type {};
3726 template<typename T>
3727 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3729 template<typename BasicJsonType, typename CompatibleObjectType,
3731 struct is_compatible_object_type_impl : std::false_type {};
3733 template<typename BasicJsonType, typename CompatibleObjectType>
3734 struct is_compatible_object_type_impl <
3735 BasicJsonType, CompatibleObjectType,
3736 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3737 is_detected<key_type_t, CompatibleObjectType>::value >>
3739 using object_t = typename BasicJsonType::object_t;
3741 // macOS's is_constructible does not play well with nonesuch...
3742 static constexpr bool value =
3743 is_constructible<typename object_t::key_type,
3744 typename CompatibleObjectType::key_type>::value &&
3745 is_constructible<typename object_t::mapped_type,
3746 typename CompatibleObjectType::mapped_type>::value;
3749 template<typename BasicJsonType, typename CompatibleObjectType>
3750 struct is_compatible_object_type
3751 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3753 template<typename BasicJsonType, typename ConstructibleObjectType,
3755 struct is_constructible_object_type_impl : std::false_type {};
3757 template<typename BasicJsonType, typename ConstructibleObjectType>
3758 struct is_constructible_object_type_impl <
3759 BasicJsonType, ConstructibleObjectType,
3760 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3761 is_detected<key_type_t, ConstructibleObjectType>::value >>
3763 using object_t = typename BasicJsonType::object_t;
3765 static constexpr bool value =
3766 (is_default_constructible<ConstructibleObjectType>::value &&
3767 (std::is_move_assignable<ConstructibleObjectType>::value ||
3768 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3769 (is_constructible<typename ConstructibleObjectType::key_type,
3770 typename object_t::key_type>::value &&
3772 typename object_t::mapped_type,
3773 typename ConstructibleObjectType::mapped_type >::value)) ||
3774 (has_from_json<BasicJsonType,
3775 typename ConstructibleObjectType::mapped_type>::value ||
3776 has_non_default_from_json <
3778 typename ConstructibleObjectType::mapped_type >::value);
3781 template<typename BasicJsonType, typename ConstructibleObjectType>
3782 struct is_constructible_object_type
3783 : is_constructible_object_type_impl<BasicJsonType,
3784 ConstructibleObjectType> {};
3786 template<typename BasicJsonType, typename CompatibleStringType>
3787 struct is_compatible_string_type
3789 static constexpr auto value =
3790 is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3793 template<typename BasicJsonType, typename ConstructibleStringType>
3794 struct is_constructible_string_type
3796 static constexpr auto value =
3797 is_constructible<ConstructibleStringType,
3798 typename BasicJsonType::string_t>::value;
3801 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3802 struct is_compatible_array_type_impl : std::false_type {};
3804 template<typename BasicJsonType, typename CompatibleArrayType>
3805 struct is_compatible_array_type_impl <
3806 BasicJsonType, CompatibleArrayType,
3808 is_detected<iterator_t, CompatibleArrayType>::value&&
3809 is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
3810 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3811 // c.f. https://github.com/nlohmann/json/pull/3073
3812 !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3814 static constexpr bool value =
3815 is_constructible<BasicJsonType,
3816 range_value_t<CompatibleArrayType>>::value;
3819 template<typename BasicJsonType, typename CompatibleArrayType>
3820 struct is_compatible_array_type
3821 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3823 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3824 struct is_constructible_array_type_impl : std::false_type {};
3826 template<typename BasicJsonType, typename ConstructibleArrayType>
3827 struct is_constructible_array_type_impl <
3828 BasicJsonType, ConstructibleArrayType,
3829 enable_if_t<std::is_same<ConstructibleArrayType,
3830 typename BasicJsonType::value_type>::value >>
3831 : std::true_type {};
3833 template<typename BasicJsonType, typename ConstructibleArrayType>
3834 struct is_constructible_array_type_impl <
3835 BasicJsonType, ConstructibleArrayType,
3836 enable_if_t < !std::is_same<ConstructibleArrayType,
3837 typename BasicJsonType::value_type>::value&&
3838 !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3839 is_default_constructible<ConstructibleArrayType>::value&&
3840 (std::is_move_assignable<ConstructibleArrayType>::value ||
3841 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3842 is_detected<iterator_t, ConstructibleArrayType>::value&&
3843 is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3844 is_detected<range_value_t, ConstructibleArrayType>::value&&
3845 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3846 // c.f. https://github.com/nlohmann/json/pull/3073
3847 !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3849 detected_t<range_value_t, ConstructibleArrayType >>::value >>
3851 using value_type = range_value_t<ConstructibleArrayType>;
3853 static constexpr bool value =
3854 std::is_same<value_type,
3855 typename BasicJsonType::array_t::value_type>::value ||
3856 has_from_json<BasicJsonType,
3857 value_type>::value ||
3858 has_non_default_from_json <
3860 value_type >::value;
3863 template<typename BasicJsonType, typename ConstructibleArrayType>
3864 struct is_constructible_array_type
3865 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3867 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3869 struct is_compatible_integer_type_impl : std::false_type {};
3871 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3872 struct is_compatible_integer_type_impl <
3873 RealIntegerType, CompatibleNumberIntegerType,
3874 enable_if_t < std::is_integral<RealIntegerType>::value&&
3875 std::is_integral<CompatibleNumberIntegerType>::value&&
3876 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3878 // is there an assert somewhere on overflows?
3879 using RealLimits = std::numeric_limits<RealIntegerType>;
3880 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3882 static constexpr auto value =
3883 is_constructible<RealIntegerType,
3884 CompatibleNumberIntegerType>::value &&
3885 CompatibleLimits::is_integer &&
3886 RealLimits::is_signed == CompatibleLimits::is_signed;
3889 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3890 struct is_compatible_integer_type
3891 : is_compatible_integer_type_impl<RealIntegerType,
3892 CompatibleNumberIntegerType> {};
3894 template<typename BasicJsonType, typename CompatibleType, typename = void>
3895 struct is_compatible_type_impl: std::false_type {};
3897 template<typename BasicJsonType, typename CompatibleType>
3898 struct is_compatible_type_impl <
3899 BasicJsonType, CompatibleType,
3900 enable_if_t<is_complete_type<CompatibleType>::value >>
3902 static constexpr bool value =
3903 has_to_json<BasicJsonType, CompatibleType>::value;
3906 template<typename BasicJsonType, typename CompatibleType>
3907 struct is_compatible_type
3908 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3910 template<typename T1, typename T2>
3911 struct is_constructible_tuple : std::false_type {};
3913 template<typename T1, typename... Args>
3914 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3916 // a naive helper to check if a type is an ordered_map (exploits the fact that
3917 // ordered_map inherits capacity() from std::vector)
3918 template <typename T>
3919 struct is_ordered_map
3925 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3928 template <typename C> static one test( decltype(&C::capacity) ) ;
3929 template <typename C> static two test(...);
3931 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3934 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3935 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3936 T conditional_static_cast(U value)
3938 return static_cast<T>(value);
3941 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3942 T conditional_static_cast(U value)
3947 } // namespace detail
3948 } // namespace nlohmann
3950 // #include <nlohmann/detail/value_t.hpp>
3953 #ifdef JSON_HAS_CPP_17
3954 #include <filesystem>
3961 template<typename BasicJsonType>
3962 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3964 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3966 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
3971 // overloads for basic_json template parameters
3972 template < typename BasicJsonType, typename ArithmeticType,
3973 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3974 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3976 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3978 switch (static_cast<value_t>(j))
3980 case value_t::number_unsigned:
3982 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3985 case value_t::number_integer:
3987 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3990 case value_t::number_float:
3992 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3997 case value_t::object:
3998 case value_t::array:
3999 case value_t::string:
4000 case value_t::boolean:
4001 case value_t::binary:
4002 case value_t::discarded:
4004 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4008 template<typename BasicJsonType>
4009 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4011 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4013 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
4015 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4018 template<typename BasicJsonType>
4019 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4021 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4023 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4025 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4029 typename BasicJsonType, typename ConstructibleStringType,
4031 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
4032 !std::is_same<typename BasicJsonType::string_t,
4033 ConstructibleStringType>::value,
4035 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
4037 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4039 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4042 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4045 template<typename BasicJsonType>
4046 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4048 get_arithmetic_value(j, val);
4051 template<typename BasicJsonType>
4052 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4054 get_arithmetic_value(j, val);
4057 template<typename BasicJsonType>
4058 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4060 get_arithmetic_value(j, val);
4063 template<typename BasicJsonType, typename EnumType,
4064 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4065 void from_json(const BasicJsonType& j, EnumType& e)
4067 typename std::underlying_type<EnumType>::type val;
4068 get_arithmetic_value(j, val);
4069 e = static_cast<EnumType>(val);
4072 // forward_list doesn't have an insert method
4073 template<typename BasicJsonType, typename T, typename Allocator,
4074 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4075 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4077 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4079 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4082 std::transform(j.rbegin(), j.rend(),
4083 std::front_inserter(l), [](const BasicJsonType & i)
4085 return i.template get<T>();
4089 // valarray doesn't have an insert method
4090 template<typename BasicJsonType, typename T,
4091 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4092 void from_json(const BasicJsonType& j, std::valarray<T>& l)
4094 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4096 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4099 std::transform(j.begin(), j.end(), std::begin(l),
4100 [](const BasicJsonType & elem)
4102 return elem.template get<T>();
4106 template<typename BasicJsonType, typename T, std::size_t N>
4107 auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4108 -> decltype(j.template get<T>(), void())
4110 for (std::size_t i = 0; i < N; ++i)
4112 arr[i] = j.at(i).template get<T>();
4116 template<typename BasicJsonType>
4117 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4119 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4122 template<typename BasicJsonType, typename T, std::size_t N>
4123 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4124 priority_tag<2> /*unused*/)
4125 -> decltype(j.template get<T>(), void())
4127 for (std::size_t i = 0; i < N; ++i)
4129 arr[i] = j.at(i).template get<T>();
4133 template<typename BasicJsonType, typename ConstructibleArrayType,
4135 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4137 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4139 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4140 j.template get<typename ConstructibleArrayType::value_type>(),
4145 ConstructibleArrayType ret;
4146 ret.reserve(j.size());
4147 std::transform(j.begin(), j.end(),
4148 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4150 // get<BasicJsonType>() returns *this, this won't call a from_json
4151 // method when value_type is BasicJsonType
4152 return i.template get<typename ConstructibleArrayType::value_type>();
4154 arr = std::move(ret);
4157 template<typename BasicJsonType, typename ConstructibleArrayType,
4159 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4161 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4162 priority_tag<0> /*unused*/)
4166 ConstructibleArrayType ret;
4168 j.begin(), j.end(), std::inserter(ret, end(ret)),
4169 [](const BasicJsonType & i)
4171 // get<BasicJsonType>() returns *this, this won't call a from_json
4172 // method when value_type is BasicJsonType
4173 return i.template get<typename ConstructibleArrayType::value_type>();
4175 arr = std::move(ret);
4178 template < typename BasicJsonType, typename ConstructibleArrayType,
4180 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4181 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4182 !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
4183 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4184 !is_basic_json<ConstructibleArrayType>::value,
4186 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4187 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4188 j.template get<typename ConstructibleArrayType::value_type>(),
4191 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4193 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4196 from_json_array_impl(j, arr, priority_tag<3> {});
4199 template < typename BasicJsonType, typename T, std::size_t... Idx >
4200 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4201 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4203 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4206 template < typename BasicJsonType, typename T, std::size_t N >
4207 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4208 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4210 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4212 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4215 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4218 template<typename BasicJsonType>
4219 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4221 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4223 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
4226 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4229 template<typename BasicJsonType, typename ConstructibleObjectType,
4230 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4231 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4233 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4235 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
4238 ConstructibleObjectType ret;
4239 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4240 using value_type = typename ConstructibleObjectType::value_type;
4242 inner_object->begin(), inner_object->end(),
4243 std::inserter(ret, ret.begin()),
4244 [](typename BasicJsonType::object_t::value_type const & p)
4246 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4248 obj = std::move(ret);
4251 // overload for arithmetic types, not chosen for basic_json template arguments
4252 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4253 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4254 // an arithmetic type?
4255 template < typename BasicJsonType, typename ArithmeticType,
4257 std::is_arithmetic<ArithmeticType>::value&&
4258 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4259 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4260 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4261 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4263 void from_json(const BasicJsonType& j, ArithmeticType& val)
4265 switch (static_cast<value_t>(j))
4267 case value_t::number_unsigned:
4269 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4272 case value_t::number_integer:
4274 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4277 case value_t::number_float:
4279 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4282 case value_t::boolean:
4284 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4289 case value_t::object:
4290 case value_t::array:
4291 case value_t::string:
4292 case value_t::binary:
4293 case value_t::discarded:
4295 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4299 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4300 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4302 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4305 template < typename BasicJsonType, class A1, class A2 >
4306 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4308 return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4309 std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4312 template<typename BasicJsonType, typename A1, typename A2>
4313 void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4315 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4318 template<typename BasicJsonType, typename... Args>
4319 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4321 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4324 template<typename BasicJsonType, typename... Args>
4325 void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4327 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4330 template<typename BasicJsonType, typename TupleRelated>
4331 auto from_json(BasicJsonType&& j, TupleRelated&& t)
4332 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4334 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4336 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4339 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4342 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4343 typename = enable_if_t < !std::is_constructible <
4344 typename BasicJsonType::string_t, Key >::value >>
4345 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4347 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4349 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4352 for (const auto& p : j)
4354 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4356 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4358 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4362 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4363 typename = enable_if_t < !std::is_constructible <
4364 typename BasicJsonType::string_t, Key >::value >>
4365 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4367 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4369 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4372 for (const auto& p : j)
4374 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4376 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4378 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4382 #ifdef JSON_HAS_CPP_17
4383 template<typename BasicJsonType>
4384 void from_json(const BasicJsonType& j, std::filesystem::path& p)
4386 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4388 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4390 p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4396 template<typename BasicJsonType, typename T>
4397 auto operator()(const BasicJsonType& j, T&& val) const
4398 noexcept(noexcept(from_json(j, std::forward<T>(val))))
4399 -> decltype(from_json(j, std::forward<T>(val)))
4401 return from_json(j, std::forward<T>(val));
4404 } // namespace detail
4406 /// namespace to hold default `from_json` function
4407 /// to see why this is required:
4408 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
4409 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4411 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4413 } // namespace nlohmann
4415 // #include <nlohmann/detail/conversions/to_json.hpp>
4418 #include <algorithm> // copy
4419 #include <iterator> // begin, end
4420 #include <string> // string
4421 #include <tuple> // tuple, get
4422 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4423 #include <utility> // move, forward, declval, pair
4424 #include <valarray> // valarray
4425 #include <vector> // vector
4427 // #include <nlohmann/detail/macro_scope.hpp>
4429 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4432 #include <cstddef> // size_t
4433 #include <iterator> // input_iterator_tag
4434 #include <string> // string, to_string
4435 #include <tuple> // tuple_size, get, tuple_element
4436 #include <utility> // move
4438 // #include <nlohmann/detail/meta/type_traits.hpp>
4440 // #include <nlohmann/detail/value_t.hpp>
4447 template<typename string_type>
4448 void int_to_string( string_type& target, std::size_t value )
4451 using std::to_string;
4452 target = to_string(value);
4454 template<typename IteratorType> class iteration_proxy_value
4457 using difference_type = std::ptrdiff_t;
4458 using value_type = iteration_proxy_value;
4459 using pointer = value_type * ;
4460 using reference = value_type & ;
4461 using iterator_category = std::input_iterator_tag;
4462 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4466 IteratorType anchor;
4467 /// an index for arrays (used to create key names)
4468 std::size_t array_index = 0;
4469 /// last stringified array index
4470 mutable std::size_t array_index_last = 0;
4471 /// a string representation of the array index
4472 mutable string_type array_index_str = "0";
4473 /// an empty string (to return a reference for primitive values)
4474 const string_type empty_str{};
4477 explicit iteration_proxy_value(IteratorType it) noexcept
4478 : anchor(std::move(it))
4481 /// dereference operator (needed for range-based for)
4482 iteration_proxy_value& operator*()
4487 /// increment operator (needed for range-based for)
4488 iteration_proxy_value& operator++()
4496 /// equality operator (needed for InputIterator)
4497 bool operator==(const iteration_proxy_value& o) const
4499 return anchor == o.anchor;
4502 /// inequality operator (needed for range-based for)
4503 bool operator!=(const iteration_proxy_value& o) const
4505 return anchor != o.anchor;
4508 /// return key of the iterator
4509 const string_type& key() const
4511 JSON_ASSERT(anchor.m_object != nullptr);
4513 switch (anchor.m_object->type())
4515 // use integer array index as key
4516 case value_t::array:
4518 if (array_index != array_index_last)
4520 int_to_string( array_index_str, array_index );
4521 array_index_last = array_index;
4523 return array_index_str;
4526 // use key from the object
4527 case value_t::object:
4528 return anchor.key();
4530 // use an empty key for all primitive types
4532 case value_t::string:
4533 case value_t::boolean:
4534 case value_t::number_integer:
4535 case value_t::number_unsigned:
4536 case value_t::number_float:
4537 case value_t::binary:
4538 case value_t::discarded:
4544 /// return value of the iterator
4545 typename IteratorType::reference value() const
4547 return anchor.value();
4551 /// proxy class for the items() function
4552 template<typename IteratorType> class iteration_proxy
4555 /// the container to iterate
4556 typename IteratorType::reference container;
4559 /// construct iteration proxy from a container
4560 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4561 : container(cont) {}
4563 /// return iterator begin (needed for range-based for)
4564 iteration_proxy_value<IteratorType> begin() noexcept
4566 return iteration_proxy_value<IteratorType>(container.begin());
4569 /// return iterator end (needed for range-based for)
4570 iteration_proxy_value<IteratorType> end() noexcept
4572 return iteration_proxy_value<IteratorType>(container.end());
4575 // Structured Bindings Support
4576 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4577 // And see https://github.com/nlohmann/json/pull/1391
4578 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4579 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
4583 // Structured Bindings Support
4584 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4585 // And see https://github.com/nlohmann/json/pull/1391
4586 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4587 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4591 } // namespace detail
4592 } // namespace nlohmann
4594 // The Addition to the STD Namespace is required to add
4595 // Structured Bindings Support to the iteration_proxy_value class
4596 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4597 // And see https://github.com/nlohmann/json/pull/1391
4600 #if defined(__clang__)
4601 // Fix: https://github.com/nlohmann/json/issues/1401
4602 #pragma clang diagnostic push
4603 #pragma clang diagnostic ignored "-Wmismatched-tags"
4605 template<typename IteratorType>
4606 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4607 : public std::integral_constant<std::size_t, 2> {};
4609 template<std::size_t N, typename IteratorType>
4610 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4613 using type = decltype(
4614 get<N>(std::declval <
4615 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
4617 #if defined(__clang__)
4618 #pragma clang diagnostic pop
4622 // #include <nlohmann/detail/meta/cpp_future.hpp>
4624 // #include <nlohmann/detail/meta/type_traits.hpp>
4626 // #include <nlohmann/detail/value_t.hpp>
4629 #ifdef JSON_HAS_CPP_17
4630 #include <filesystem>
4642 * Note all external_constructor<>::construct functions need to call
4643 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4644 * allocated value (e.g., a string). See bug issue
4645 * https://github.com/nlohmann/json/issues/2865 for more information.
4648 template<value_t> struct external_constructor;
4651 struct external_constructor<value_t::boolean>
4653 template<typename BasicJsonType>
4654 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4656 j.m_value.destroy(j.m_type);
4657 j.m_type = value_t::boolean;
4659 j.assert_invariant();
4664 struct external_constructor<value_t::string>
4666 template<typename BasicJsonType>
4667 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4669 j.m_value.destroy(j.m_type);
4670 j.m_type = value_t::string;
4672 j.assert_invariant();
4675 template<typename BasicJsonType>
4676 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4678 j.m_value.destroy(j.m_type);
4679 j.m_type = value_t::string;
4680 j.m_value = std::move(s);
4681 j.assert_invariant();
4684 template < typename BasicJsonType, typename CompatibleStringType,
4685 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4687 static void construct(BasicJsonType& j, const CompatibleStringType& str)
4689 j.m_value.destroy(j.m_type);
4690 j.m_type = value_t::string;
4691 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4692 j.assert_invariant();
4697 struct external_constructor<value_t::binary>
4699 template<typename BasicJsonType>
4700 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4702 j.m_value.destroy(j.m_type);
4703 j.m_type = value_t::binary;
4704 j.m_value = typename BasicJsonType::binary_t(b);
4705 j.assert_invariant();
4708 template<typename BasicJsonType>
4709 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4711 j.m_value.destroy(j.m_type);
4712 j.m_type = value_t::binary;
4713 j.m_value = typename BasicJsonType::binary_t(std::move(b));
4714 j.assert_invariant();
4719 struct external_constructor<value_t::number_float>
4721 template<typename BasicJsonType>
4722 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4724 j.m_value.destroy(j.m_type);
4725 j.m_type = value_t::number_float;
4727 j.assert_invariant();
4732 struct external_constructor<value_t::number_unsigned>
4734 template<typename BasicJsonType>
4735 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4737 j.m_value.destroy(j.m_type);
4738 j.m_type = value_t::number_unsigned;
4740 j.assert_invariant();
4745 struct external_constructor<value_t::number_integer>
4747 template<typename BasicJsonType>
4748 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4750 j.m_value.destroy(j.m_type);
4751 j.m_type = value_t::number_integer;
4753 j.assert_invariant();
4758 struct external_constructor<value_t::array>
4760 template<typename BasicJsonType>
4761 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4763 j.m_value.destroy(j.m_type);
4764 j.m_type = value_t::array;
4767 j.assert_invariant();
4770 template<typename BasicJsonType>
4771 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4773 j.m_value.destroy(j.m_type);
4774 j.m_type = value_t::array;
4775 j.m_value = std::move(arr);
4777 j.assert_invariant();
4780 template < typename BasicJsonType, typename CompatibleArrayType,
4781 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4783 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4788 j.m_value.destroy(j.m_type);
4789 j.m_type = value_t::array;
4790 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4792 j.assert_invariant();
4795 template<typename BasicJsonType>
4796 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4798 j.m_value.destroy(j.m_type);
4799 j.m_type = value_t::array;
4800 j.m_value = value_t::array;
4801 j.m_value.array->reserve(arr.size());
4802 for (const bool x : arr)
4804 j.m_value.array->push_back(x);
4805 j.set_parent(j.m_value.array->back());
4807 j.assert_invariant();
4810 template<typename BasicJsonType, typename T,
4811 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4812 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4814 j.m_value.destroy(j.m_type);
4815 j.m_type = value_t::array;
4816 j.m_value = value_t::array;
4817 j.m_value.array->resize(arr.size());
4820 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4823 j.assert_invariant();
4828 struct external_constructor<value_t::object>
4830 template<typename BasicJsonType>
4831 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4833 j.m_value.destroy(j.m_type);
4834 j.m_type = value_t::object;
4837 j.assert_invariant();
4840 template<typename BasicJsonType>
4841 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4843 j.m_value.destroy(j.m_type);
4844 j.m_type = value_t::object;
4845 j.m_value = std::move(obj);
4847 j.assert_invariant();
4850 template < typename BasicJsonType, typename CompatibleObjectType,
4851 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4852 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4857 j.m_value.destroy(j.m_type);
4858 j.m_type = value_t::object;
4859 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4861 j.assert_invariant();
4869 template<typename BasicJsonType, typename T,
4870 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4871 void to_json(BasicJsonType& j, T b) noexcept
4873 external_constructor<value_t::boolean>::construct(j, b);
4876 template<typename BasicJsonType, typename CompatibleString,
4877 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4878 void to_json(BasicJsonType& j, const CompatibleString& s)
4880 external_constructor<value_t::string>::construct(j, s);
4883 template<typename BasicJsonType>
4884 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4886 external_constructor<value_t::string>::construct(j, std::move(s));
4889 template<typename BasicJsonType, typename FloatType,
4890 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4891 void to_json(BasicJsonType& j, FloatType val) noexcept
4893 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4896 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4897 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4898 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4900 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4903 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4904 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4905 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4907 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4910 template<typename BasicJsonType, typename EnumType,
4911 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4912 void to_json(BasicJsonType& j, EnumType e) noexcept
4914 using underlying_type = typename std::underlying_type<EnumType>::type;
4915 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4918 template<typename BasicJsonType>
4919 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4921 external_constructor<value_t::array>::construct(j, e);
4924 template < typename BasicJsonType, typename CompatibleArrayType,
4925 enable_if_t < is_compatible_array_type<BasicJsonType,
4926 CompatibleArrayType>::value&&
4927 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4928 !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4929 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4930 !is_basic_json<CompatibleArrayType>::value,
4932 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4934 external_constructor<value_t::array>::construct(j, arr);
4937 template<typename BasicJsonType>
4938 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4940 external_constructor<value_t::binary>::construct(j, bin);
4943 template<typename BasicJsonType, typename T,
4944 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4945 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4947 external_constructor<value_t::array>::construct(j, std::move(arr));
4950 template<typename BasicJsonType>
4951 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4953 external_constructor<value_t::array>::construct(j, std::move(arr));
4956 template < typename BasicJsonType, typename CompatibleObjectType,
4957 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4958 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4960 external_constructor<value_t::object>::construct(j, obj);
4963 template<typename BasicJsonType>
4964 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4966 external_constructor<value_t::object>::construct(j, std::move(obj));
4970 typename BasicJsonType, typename T, std::size_t N,
4971 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4972 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4974 void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4976 external_constructor<value_t::array>::construct(j, arr);
4979 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4980 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4982 j = { p.first, p.second };
4985 // for https://github.com/nlohmann/json/pull/1134
4986 template<typename BasicJsonType, typename T,
4987 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4988 void to_json(BasicJsonType& j, const T& b)
4990 j = { {b.key(), b.value()} };
4993 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4994 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4996 j = { std::get<Idx>(t)... };
4999 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
5000 void to_json(BasicJsonType& j, const T& t)
5002 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5005 #ifdef JSON_HAS_CPP_17
5006 template<typename BasicJsonType>
5007 void to_json(BasicJsonType& j, const std::filesystem::path& p)
5015 template<typename BasicJsonType, typename T>
5016 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5017 -> decltype(to_json(j, std::forward<T>(val)), void())
5019 return to_json(j, std::forward<T>(val));
5022 } // namespace detail
5024 /// namespace to hold default `to_json` function
5025 /// to see why this is required:
5026 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
5027 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5029 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
5031 } // namespace nlohmann
5033 // #include <nlohmann/detail/meta/identity_tag.hpp>
5035 // #include <nlohmann/detail/meta/type_traits.hpp>
5041 template<typename ValueType, typename>
5042 struct adl_serializer
5045 @brief convert a JSON value to any value type
5047 This function is usually called by the `get()` function of the
5048 @ref basic_json class (either explicit or via conversion operators).
5050 @note This function is chosen for default-constructible value types.
5052 @param[in] j JSON value to read from
5053 @param[in,out] val value to write to
5055 template<typename BasicJsonType, typename TargetType = ValueType>
5056 static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
5057 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5058 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5060 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5064 @brief convert a JSON value to any value type
5066 This function is usually called by the `get()` function of the
5067 @ref basic_json class (either explicit or via conversion operators).
5069 @note This function is chosen for value types which are not default-constructible.
5071 @param[in] j JSON value to read from
5073 @return copy of the JSON value, converted to @a ValueType
5075 template<typename BasicJsonType, typename TargetType = ValueType>
5076 static auto from_json(BasicJsonType && j) noexcept(
5077 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5078 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5080 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5084 @brief convert any value type to a JSON value
5086 This function is usually called by the constructors of the @ref basic_json
5089 @param[in,out] j JSON value to write to
5090 @param[in] val value to read from
5092 template<typename BasicJsonType, typename TargetType = ValueType>
5093 static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5094 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5095 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5097 ::nlohmann::to_json(j, std::forward<TargetType>(val));
5100 } // namespace nlohmann
5102 // #include <nlohmann/byte_container_with_subtype.hpp>
5105 #include <cstdint> // uint8_t, uint64_t
5106 #include <tuple> // tie
5107 #include <utility> // move
5113 @brief an internal type for a backed binary type
5115 This type extends the template parameter @a BinaryType provided to `basic_json`
5116 with a subtype used by BSON and MessagePack. This type exists so that the user
5117 does not have to specify a type themselves with a specific naming scheme in
5118 order to override the binary type.
5120 @tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by
5123 @since version 3.8.0; changed type of subtypes to std::uint64_t in 3.10.0.
5125 template<typename BinaryType>
5126 class byte_container_with_subtype : public BinaryType
5129 /// the type of the underlying container
5130 using container_type = BinaryType;
5131 /// the type of the subtype
5132 using subtype_type = std::uint64_t;
5134 byte_container_with_subtype() noexcept(noexcept(container_type()))
5138 byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
5142 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5143 : container_type(std::move(b))
5146 byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
5148 , m_subtype(subtype_)
5149 , m_has_subtype(true)
5152 byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5153 : container_type(std::move(b))
5154 , m_subtype(subtype_)
5155 , m_has_subtype(true)
5158 bool operator==(const byte_container_with_subtype& rhs) const
5160 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5161 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5164 bool operator!=(const byte_container_with_subtype& rhs) const
5166 return !(rhs == *this);
5170 @brief sets the binary subtype
5172 Sets the binary subtype of the value, also flags a binary JSON value as
5173 having a subtype, which has implications for serialization.
5175 @complexity Constant.
5177 @exceptionsafety No-throw guarantee: this member function never throws
5180 @sa see @ref subtype() -- return the binary subtype
5181 @sa see @ref clear_subtype() -- clears the binary subtype
5182 @sa see @ref has_subtype() -- returns whether or not the binary value has a
5185 @since version 3.8.0
5187 void set_subtype(subtype_type subtype_) noexcept
5189 m_subtype = subtype_;
5190 m_has_subtype = true;
5194 @brief return the binary subtype
5196 Returns the numerical subtype of the value if it has a subtype. If it does
5197 not have a subtype, this function will return subtype_type(-1) as a sentinel
5200 @return the numerical subtype of the binary value
5202 @complexity Constant.
5204 @exceptionsafety No-throw guarantee: this member function never throws
5207 @sa see @ref set_subtype() -- sets the binary subtype
5208 @sa see @ref clear_subtype() -- clears the binary subtype
5209 @sa see @ref has_subtype() -- returns whether or not the binary value has a
5212 @since version 3.8.0; fixed return value to properly return
5213 subtype_type(-1) as documented in version 3.10.0
5215 constexpr subtype_type subtype() const noexcept
5217 return m_has_subtype ? m_subtype : subtype_type(-1);
5221 @brief return whether the value has a subtype
5223 @return whether the value has a subtype
5225 @complexity Constant.
5227 @exceptionsafety No-throw guarantee: this member function never throws
5230 @sa see @ref subtype() -- return the binary subtype
5231 @sa see @ref set_subtype() -- sets the binary subtype
5232 @sa see @ref clear_subtype() -- clears the binary subtype
5234 @since version 3.8.0
5236 constexpr bool has_subtype() const noexcept
5238 return m_has_subtype;
5242 @brief clears the binary subtype
5244 Clears the binary subtype and flags the value as not having a subtype, which
5245 has implications for serialization; for instance MessagePack will prefer the
5246 bin family over the ext family.
5248 @complexity Constant.
5250 @exceptionsafety No-throw guarantee: this member function never throws
5253 @sa see @ref subtype() -- return the binary subtype
5254 @sa see @ref set_subtype() -- sets the binary subtype
5255 @sa see @ref has_subtype() -- returns whether or not the binary value has a
5258 @since version 3.8.0
5260 void clear_subtype() noexcept
5263 m_has_subtype = false;
5267 subtype_type m_subtype = 0;
5268 bool m_has_subtype = false;
5271 } // namespace nlohmann
5273 // #include <nlohmann/detail/conversions/from_json.hpp>
5275 // #include <nlohmann/detail/conversions/to_json.hpp>
5277 // #include <nlohmann/detail/exceptions.hpp>
5279 // #include <nlohmann/detail/hash.hpp>
5282 #include <cstdint> // uint8_t
5283 #include <cstddef> // size_t
5284 #include <functional> // hash
5286 // #include <nlohmann/detail/macro_scope.hpp>
5288 // #include <nlohmann/detail/value_t.hpp>
5296 // boost::hash_combine
5297 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5299 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5304 @brief hash a JSON value
5306 The hash function tries to rely on std::hash where possible. Furthermore, the
5307 type of the JSON value is taken into account to have different hash values for
5308 null, 0, 0U, and false, etc.
5310 @tparam BasicJsonType basic_json specialization
5311 @param j JSON value to hash
5312 @return hash value of j
5314 template<typename BasicJsonType>
5315 std::size_t hash(const BasicJsonType& j)
5317 using string_t = typename BasicJsonType::string_t;
5318 using number_integer_t = typename BasicJsonType::number_integer_t;
5319 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5320 using number_float_t = typename BasicJsonType::number_float_t;
5322 const auto type = static_cast<std::size_t>(j.type());
5325 case BasicJsonType::value_t::null:
5326 case BasicJsonType::value_t::discarded:
5328 return combine(type, 0);
5331 case BasicJsonType::value_t::object:
5333 auto seed = combine(type, j.size());
5334 for (const auto& element : j.items())
5336 const auto h = std::hash<string_t> {}(element.key());
5337 seed = combine(seed, h);
5338 seed = combine(seed, hash(element.value()));
5343 case BasicJsonType::value_t::array:
5345 auto seed = combine(type, j.size());
5346 for (const auto& element : j)
5348 seed = combine(seed, hash(element));
5353 case BasicJsonType::value_t::string:
5355 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5356 return combine(type, h);
5359 case BasicJsonType::value_t::boolean:
5361 const auto h = std::hash<bool> {}(j.template get<bool>());
5362 return combine(type, h);
5365 case BasicJsonType::value_t::number_integer:
5367 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5368 return combine(type, h);
5371 case BasicJsonType::value_t::number_unsigned:
5373 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5374 return combine(type, h);
5377 case BasicJsonType::value_t::number_float:
5379 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5380 return combine(type, h);
5383 case BasicJsonType::value_t::binary:
5385 auto seed = combine(type, j.get_binary().size());
5386 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5387 seed = combine(seed, h);
5388 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5389 for (const auto byte : j.get_binary())
5391 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5396 default: // LCOV_EXCL_LINE
5397 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5398 return 0; // LCOV_EXCL_LINE
5402 } // namespace detail
5403 } // namespace nlohmann
5405 // #include <nlohmann/detail/input/binary_reader.hpp>
5408 #include <algorithm> // generate_n
5409 #include <array> // array
5410 #include <cmath> // ldexp
5411 #include <cstddef> // size_t
5412 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5413 #include <cstdio> // snprintf
5414 #include <cstring> // memcpy
5415 #include <iterator> // back_inserter
5416 #include <limits> // numeric_limits
5417 #include <string> // char_traits, string
5418 #include <utility> // make_pair, move
5419 #include <vector> // vector
5421 // #include <nlohmann/detail/exceptions.hpp>
5423 // #include <nlohmann/detail/input/input_adapters.hpp>
5426 #include <array> // array
5427 #include <cstddef> // size_t
5428 #include <cstring> // strlen
5429 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5430 #include <memory> // shared_ptr, make_shared, addressof
5431 #include <numeric> // accumulate
5432 #include <string> // string, char_traits
5433 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5434 #include <utility> // pair, declval
5437 #include <cstdio> // FILE *
5438 #include <istream> // istream
5439 #endif // JSON_NO_IO
5441 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
5443 // #include <nlohmann/detail/macro_scope.hpp>
5450 /// the supported input formats
5451 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
5453 ////////////////////
5454 // input adapters //
5455 ////////////////////
5459 Input adapter for stdio file access. This adapter read only 1 byte and do not use any
5460 buffer. This adapter is a very low level adapter.
5462 class file_input_adapter
5465 using char_type = char;
5467 JSON_HEDLEY_NON_NULL(2)
5468 explicit file_input_adapter(std::FILE* f) noexcept
5472 // make class move-only
5473 file_input_adapter(const file_input_adapter&) = delete;
5474 file_input_adapter(file_input_adapter&&) noexcept = default;
5475 file_input_adapter& operator=(const file_input_adapter&) = delete;
5476 file_input_adapter& operator=(file_input_adapter&&) = delete;
5477 ~file_input_adapter() = default;
5479 std::char_traits<char>::int_type get_character() noexcept
5481 return std::fgetc(m_file);
5485 /// the file pointer to read from
5491 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
5492 beginning of input. Does not support changing the underlying std::streambuf
5493 in mid-input. Maintains underlying std::istream and std::streambuf to support
5494 subsequent use of standard std::istream operations to process any input
5495 characters following those used in parsing the JSON input. Clears the
5496 std::istream flags; any input errors (e.g., EOF) will be detected by the first
5497 subsequent call for input from the std::istream.
5499 class input_stream_adapter
5502 using char_type = char;
5504 ~input_stream_adapter()
5506 // clear stream flags; we use underlying streambuf I/O, do not
5507 // maintain ifstream flags, except eof
5510 is->clear(is->rdstate() & std::ios::eofbit);
5514 explicit input_stream_adapter(std::istream& i)
5515 : is(&i), sb(i.rdbuf())
5518 // delete because of pointer members
5519 input_stream_adapter(const input_stream_adapter&) = delete;
5520 input_stream_adapter& operator=(input_stream_adapter&) = delete;
5521 input_stream_adapter& operator=(input_stream_adapter&&) = delete;
5523 input_stream_adapter(input_stream_adapter&& rhs) noexcept
5524 : is(rhs.is), sb(rhs.sb)
5530 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5531 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5532 // end up as the same value, eg. 0xFFFFFFFF.
5533 std::char_traits<char>::int_type get_character()
5535 auto res = sb->sbumpc();
5536 // set eof manually, as we don't use the istream interface.
5537 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5539 is->clear(is->rdstate() | std::ios::eofbit);
5545 /// the associated input stream
5546 std::istream* is = nullptr;
5547 std::streambuf* sb = nullptr;
5549 #endif // JSON_NO_IO
5551 // General-purpose iterator-based adapter. It might not be as fast as
5552 // theoretically possible for some containers, but it is extremely versatile.
5553 template<typename IteratorType>
5554 class iterator_input_adapter
5557 using char_type = typename std::iterator_traits<IteratorType>::value_type;
5559 iterator_input_adapter(IteratorType first, IteratorType last)
5560 : current(std::move(first)), end(std::move(last))
5563 typename std::char_traits<char_type>::int_type get_character()
5565 if (JSON_HEDLEY_LIKELY(current != end))
5567 auto result = std::char_traits<char_type>::to_int_type(*current);
5568 std::advance(current, 1);
5572 return std::char_traits<char_type>::eof();
5576 IteratorType current;
5579 template<typename BaseInputAdapter, size_t T>
5580 friend struct wide_string_input_helper;
5584 return current == end;
5589 template<typename BaseInputAdapter, size_t T>
5590 struct wide_string_input_helper;
5592 template<typename BaseInputAdapter>
5593 struct wide_string_input_helper<BaseInputAdapter, 4>
5596 static void fill_buffer(BaseInputAdapter& input,
5597 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5598 size_t& utf8_bytes_index,
5599 size_t& utf8_bytes_filled)
5601 utf8_bytes_index = 0;
5603 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5605 utf8_bytes[0] = std::char_traits<char>::eof();
5606 utf8_bytes_filled = 1;
5610 // get the current character
5611 const auto wc = input.get_character();
5613 // UTF-32 to UTF-8 encoding
5616 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5617 utf8_bytes_filled = 1;
5619 else if (wc <= 0x7FF)
5621 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5622 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5623 utf8_bytes_filled = 2;
5625 else if (wc <= 0xFFFF)
5627 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5628 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5629 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5630 utf8_bytes_filled = 3;
5632 else if (wc <= 0x10FFFF)
5634 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5635 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5636 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5637 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5638 utf8_bytes_filled = 4;
5642 // unknown character
5643 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5644 utf8_bytes_filled = 1;
5650 template<typename BaseInputAdapter>
5651 struct wide_string_input_helper<BaseInputAdapter, 2>
5654 static void fill_buffer(BaseInputAdapter& input,
5655 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5656 size_t& utf8_bytes_index,
5657 size_t& utf8_bytes_filled)
5659 utf8_bytes_index = 0;
5661 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5663 utf8_bytes[0] = std::char_traits<char>::eof();
5664 utf8_bytes_filled = 1;
5668 // get the current character
5669 const auto wc = input.get_character();
5671 // UTF-16 to UTF-8 encoding
5674 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5675 utf8_bytes_filled = 1;
5677 else if (wc <= 0x7FF)
5679 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5680 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5681 utf8_bytes_filled = 2;
5683 else if (0xD800 > wc || wc >= 0xE000)
5685 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5686 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5687 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5688 utf8_bytes_filled = 3;
5692 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5694 const auto wc2 = static_cast<unsigned int>(input.get_character());
5695 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5696 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5697 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5698 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5699 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5700 utf8_bytes_filled = 4;
5704 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5705 utf8_bytes_filled = 1;
5712 // Wraps another input apdater to convert wide character types into individual bytes.
5713 template<typename BaseInputAdapter, typename WideCharType>
5714 class wide_string_input_adapter
5717 using char_type = char;
5719 wide_string_input_adapter(BaseInputAdapter base)
5720 : base_adapter(base) {}
5722 typename std::char_traits<char>::int_type get_character() noexcept
5724 // check if buffer needs to be filled
5725 if (utf8_bytes_index == utf8_bytes_filled)
5727 fill_buffer<sizeof(WideCharType)>();
5729 JSON_ASSERT(utf8_bytes_filled > 0);
5730 JSON_ASSERT(utf8_bytes_index == 0);
5734 JSON_ASSERT(utf8_bytes_filled > 0);
5735 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5736 return utf8_bytes[utf8_bytes_index++];
5740 BaseInputAdapter base_adapter;
5745 wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5748 /// a buffer for UTF-8 bytes
5749 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5751 /// index to the utf8_codes array for the next valid byte
5752 std::size_t utf8_bytes_index = 0;
5753 /// number of valid bytes in the utf8_codes array
5754 std::size_t utf8_bytes_filled = 0;
5758 template<typename IteratorType, typename Enable = void>
5759 struct iterator_input_adapter_factory
5761 using iterator_type = IteratorType;
5762 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5763 using adapter_type = iterator_input_adapter<iterator_type>;
5765 static adapter_type create(IteratorType first, IteratorType last)
5767 return adapter_type(std::move(first), std::move(last));
5771 template<typename T>
5772 struct is_iterator_of_multibyte
5774 using value_type = typename std::iterator_traits<T>::value_type;
5777 value = sizeof(value_type) > 1
5781 template<typename IteratorType>
5782 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5784 using iterator_type = IteratorType;
5785 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5786 using base_adapter_type = iterator_input_adapter<iterator_type>;
5787 using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5789 static adapter_type create(IteratorType first, IteratorType last)
5791 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5795 // General purpose iterator-based input
5796 template<typename IteratorType>
5797 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5799 using factory_type = iterator_input_adapter_factory<IteratorType>;
5800 return factory_type::create(first, last);
5803 // Convenience shorthand from container to iterator
5804 // Enables ADL on begin(container) and end(container)
5805 // Encloses the using declarations in namespace for not to leak them to outside scope
5807 namespace container_input_adapter_factory_impl
5813 template<typename ContainerType, typename Enable = void>
5814 struct container_input_adapter_factory {};
5816 template<typename ContainerType>
5817 struct container_input_adapter_factory< ContainerType,
5818 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5820 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5822 static adapter_type create(const ContainerType& container)
5824 return input_adapter(begin(container), end(container));
5828 } // namespace container_input_adapter_factory_impl
5830 template<typename ContainerType>
5831 typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
5833 return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
5837 // Special cases with fast paths
5838 inline file_input_adapter input_adapter(std::FILE* file)
5840 return file_input_adapter(file);
5843 inline input_stream_adapter input_adapter(std::istream& stream)
5845 return input_stream_adapter(stream);
5848 inline input_stream_adapter input_adapter(std::istream&& stream)
5850 return input_stream_adapter(stream);
5852 #endif // JSON_NO_IO
5854 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5856 // Null-delimited strings, and the like.
5857 template < typename CharT,
5858 typename std::enable_if <
5859 std::is_pointer<CharT>::value&&
5860 !std::is_array<CharT>::value&&
5861 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5862 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5864 contiguous_bytes_input_adapter input_adapter(CharT b)
5866 auto length = std::strlen(reinterpret_cast<const char*>(b));
5867 const auto* ptr = reinterpret_cast<const char*>(b);
5868 return input_adapter(ptr, ptr + length);
5871 template<typename T, std::size_t N>
5872 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5874 return input_adapter(array, array + N);
5877 // This class only handles inputs of input_buffer_adapter type.
5878 // It's required so that expressions like {ptr, len} can be implicitly casted
5879 // to the correct adapter.
5880 class span_input_adapter
5883 template < typename CharT,
5884 typename std::enable_if <
5885 std::is_pointer<CharT>::value&&
5886 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5887 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5889 span_input_adapter(CharT b, std::size_t l)
5890 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5892 template<class IteratorType,
5893 typename std::enable_if<
5894 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5896 span_input_adapter(IteratorType first, IteratorType last)
5897 : ia(input_adapter(first, last)) {}
5899 contiguous_bytes_input_adapter&& get()
5901 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5905 contiguous_bytes_input_adapter ia;
5907 } // namespace detail
5908 } // namespace nlohmann
5910 // #include <nlohmann/detail/input/json_sax.hpp>
5914 #include <string> // string
5915 #include <utility> // move
5916 #include <vector> // vector
5918 // #include <nlohmann/detail/exceptions.hpp>
5920 // #include <nlohmann/detail/macro_scope.hpp>
5927 @brief SAX interface
5929 This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
5930 Each function is called in different situations while the input is parsed. The
5931 boolean return value informs the parser whether to continue processing the
5934 template<typename BasicJsonType>
5937 using number_integer_t = typename BasicJsonType::number_integer_t;
5938 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5939 using number_float_t = typename BasicJsonType::number_float_t;
5940 using string_t = typename BasicJsonType::string_t;
5941 using binary_t = typename BasicJsonType::binary_t;
5944 @brief a null value was read
5945 @return whether parsing should proceed
5947 virtual bool null() = 0;
5950 @brief a boolean value was read
5951 @param[in] val boolean value
5952 @return whether parsing should proceed
5954 virtual bool boolean(bool val) = 0;
5957 @brief an integer number was read
5958 @param[in] val integer value
5959 @return whether parsing should proceed
5961 virtual bool number_integer(number_integer_t val) = 0;
5964 @brief an unsigned integer number was read
5965 @param[in] val unsigned integer value
5966 @return whether parsing should proceed
5968 virtual bool number_unsigned(number_unsigned_t val) = 0;
5971 @brief an floating-point number was read
5972 @param[in] val floating-point value
5973 @param[in] s raw token value
5974 @return whether parsing should proceed
5976 virtual bool number_float(number_float_t val, const string_t& s) = 0;
5979 @brief a string was read
5980 @param[in] val string value
5981 @return whether parsing should proceed
5982 @note It is safe to move the passed string.
5984 virtual bool string(string_t& val) = 0;
5987 @brief a binary string was read
5988 @param[in] val binary value
5989 @return whether parsing should proceed
5990 @note It is safe to move the passed binary.
5992 virtual bool binary(binary_t& val) = 0;
5995 @brief the beginning of an object was read
5996 @param[in] elements number of object elements or -1 if unknown
5997 @return whether parsing should proceed
5998 @note binary formats may report the number of elements
6000 virtual bool start_object(std::size_t elements) = 0;
6003 @brief an object key was read
6004 @param[in] val object key
6005 @return whether parsing should proceed
6006 @note It is safe to move the passed string.
6008 virtual bool key(string_t& val) = 0;
6011 @brief the end of an object was read
6012 @return whether parsing should proceed
6014 virtual bool end_object() = 0;
6017 @brief the beginning of an array was read
6018 @param[in] elements number of array elements or -1 if unknown
6019 @return whether parsing should proceed
6020 @note binary formats may report the number of elements
6022 virtual bool start_array(std::size_t elements) = 0;
6025 @brief the end of an array was read
6026 @return whether parsing should proceed
6028 virtual bool end_array() = 0;
6031 @brief a parse error occurred
6032 @param[in] position the position in the input where the error occurs
6033 @param[in] last_token the last read token
6034 @param[in] ex an exception object describing the error
6035 @return whether parsing should proceed (must return false)
6037 virtual bool parse_error(std::size_t position,
6038 const std::string& last_token,
6039 const detail::exception& ex) = 0;
6041 json_sax() = default;
6042 json_sax(const json_sax&) = default;
6043 json_sax(json_sax&&) noexcept = default;
6044 json_sax& operator=(const json_sax&) = default;
6045 json_sax& operator=(json_sax&&) noexcept = default;
6046 virtual ~json_sax() = default;
6053 @brief SAX implementation to create a JSON value from SAX events
6055 This class implements the @ref json_sax interface and processes the SAX events
6056 to create a JSON value which makes it basically a DOM parser. The structure or
6057 hierarchy of the JSON value is managed by the stack `ref_stack` which contains
6058 a pointer to the respective array or object for each recursion depth.
6060 After successful parsing, the value that is passed by reference to the
6061 constructor contains the parsed value.
6063 @tparam BasicJsonType the JSON type
6065 template<typename BasicJsonType>
6066 class json_sax_dom_parser
6069 using number_integer_t = typename BasicJsonType::number_integer_t;
6070 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6071 using number_float_t = typename BasicJsonType::number_float_t;
6072 using string_t = typename BasicJsonType::string_t;
6073 using binary_t = typename BasicJsonType::binary_t;
6076 @param[in,out] r reference to a JSON value that is manipulated while
6078 @param[in] allow_exceptions_ whether parse errors yield exceptions
6080 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6081 : root(r), allow_exceptions(allow_exceptions_)
6084 // make class move-only
6085 json_sax_dom_parser(const json_sax_dom_parser&) = delete;
6086 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6087 json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
6088 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6089 ~json_sax_dom_parser() = default;
6093 handle_value(nullptr);
6097 bool boolean(bool val)
6103 bool number_integer(number_integer_t val)
6109 bool number_unsigned(number_unsigned_t val)
6115 bool number_float(number_float_t val, const string_t& /*unused*/)
6121 bool string(string_t& val)
6127 bool binary(binary_t& val)
6129 handle_value(std::move(val));
6133 bool start_object(std::size_t len)
6135 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6137 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6139 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6145 bool key(string_t& val)
6147 // add null at given key and store the reference for later
6148 object_element = &(ref_stack.back()->m_value.object->operator[](val));
6154 ref_stack.back()->set_parents();
6155 ref_stack.pop_back();
6159 bool start_array(std::size_t len)
6161 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6163 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6165 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6173 ref_stack.back()->set_parents();
6174 ref_stack.pop_back();
6178 template<class Exception>
6179 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6180 const Exception& ex)
6183 static_cast<void>(ex);
6184 if (allow_exceptions)
6191 constexpr bool is_errored() const
6198 @invariant If the ref stack is empty, then the passed value will be the new
6200 @invariant If the ref stack contains a value, then it is an array or an
6201 object to which we can add elements
6203 template<typename Value>
6204 JSON_HEDLEY_RETURNS_NON_NULL
6205 BasicJsonType* handle_value(Value&& v)
6207 if (ref_stack.empty())
6209 root = BasicJsonType(std::forward<Value>(v));
6213 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6215 if (ref_stack.back()->is_array())
6217 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6218 return &(ref_stack.back()->m_value.array->back());
6221 JSON_ASSERT(ref_stack.back()->is_object());
6222 JSON_ASSERT(object_element);
6223 *object_element = BasicJsonType(std::forward<Value>(v));
6224 return object_element;
6227 /// the parsed JSON value
6228 BasicJsonType& root;
6229 /// stack to model hierarchy of values
6230 std::vector<BasicJsonType*> ref_stack {};
6231 /// helper to hold the reference for the next object element
6232 BasicJsonType* object_element = nullptr;
6233 /// whether a syntax error occurred
6234 bool errored = false;
6235 /// whether to throw exceptions in case of errors
6236 const bool allow_exceptions = true;
6239 template<typename BasicJsonType>
6240 class json_sax_dom_callback_parser
6243 using number_integer_t = typename BasicJsonType::number_integer_t;
6244 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6245 using number_float_t = typename BasicJsonType::number_float_t;
6246 using string_t = typename BasicJsonType::string_t;
6247 using binary_t = typename BasicJsonType::binary_t;
6248 using parser_callback_t = typename BasicJsonType::parser_callback_t;
6249 using parse_event_t = typename BasicJsonType::parse_event_t;
6251 json_sax_dom_callback_parser(BasicJsonType& r,
6252 const parser_callback_t cb,
6253 const bool allow_exceptions_ = true)
6254 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6256 keep_stack.push_back(true);
6259 // make class move-only
6260 json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
6261 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6262 json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
6263 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6264 ~json_sax_dom_callback_parser() = default;
6268 handle_value(nullptr);
6272 bool boolean(bool val)
6278 bool number_integer(number_integer_t val)
6284 bool number_unsigned(number_unsigned_t val)
6290 bool number_float(number_float_t val, const string_t& /*unused*/)
6296 bool string(string_t& val)
6302 bool binary(binary_t& val)
6304 handle_value(std::move(val));
6308 bool start_object(std::size_t len)
6310 // check callback for object start
6311 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6312 keep_stack.push_back(keep);
6314 auto val = handle_value(BasicJsonType::value_t::object, true);
6315 ref_stack.push_back(val.second);
6317 // check object limit
6318 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6320 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6326 bool key(string_t& val)
6328 BasicJsonType k = BasicJsonType(val);
6330 // check callback for key
6331 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6332 key_keep_stack.push_back(keep);
6334 // add discarded value at given key and store the reference for later
6335 if (keep && ref_stack.back())
6337 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6345 if (ref_stack.back())
6347 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6350 *ref_stack.back() = discarded;
6354 ref_stack.back()->set_parents();
6358 JSON_ASSERT(!ref_stack.empty());
6359 JSON_ASSERT(!keep_stack.empty());
6360 ref_stack.pop_back();
6361 keep_stack.pop_back();
6363 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6365 // remove discarded value
6366 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6368 if (it->is_discarded())
6370 ref_stack.back()->erase(it);
6379 bool start_array(std::size_t len)
6381 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6382 keep_stack.push_back(keep);
6384 auto val = handle_value(BasicJsonType::value_t::array, true);
6385 ref_stack.push_back(val.second);
6387 // check array limit
6388 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6390 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6400 if (ref_stack.back())
6402 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6405 ref_stack.back()->set_parents();
6410 *ref_stack.back() = discarded;
6414 JSON_ASSERT(!ref_stack.empty());
6415 JSON_ASSERT(!keep_stack.empty());
6416 ref_stack.pop_back();
6417 keep_stack.pop_back();
6419 // remove discarded value
6420 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6422 ref_stack.back()->m_value.array->pop_back();
6428 template<class Exception>
6429 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6430 const Exception& ex)
6433 static_cast<void>(ex);
6434 if (allow_exceptions)
6441 constexpr bool is_errored() const
6448 @param[in] v value to add to the JSON value we build during parsing
6449 @param[in] skip_callback whether we should skip calling the callback
6450 function; this is required after start_array() and
6451 start_object() SAX events, because otherwise we would call the
6452 callback function with an empty array or object, respectively.
6454 @invariant If the ref stack is empty, then the passed value will be the new
6456 @invariant If the ref stack contains a value, then it is an array or an
6457 object to which we can add elements
6459 @return pair of boolean (whether value should be kept) and pointer (to the
6460 passed value in the ref_stack hierarchy; nullptr if not kept)
6462 template<typename Value>
6463 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6465 JSON_ASSERT(!keep_stack.empty());
6467 // do not handle this value if we know it would be added to a discarded
6469 if (!keep_stack.back())
6471 return {false, nullptr};
6475 auto value = BasicJsonType(std::forward<Value>(v));
6478 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6480 // do not handle this value if we just learnt it shall be discarded
6483 return {false, nullptr};
6486 if (ref_stack.empty())
6488 root = std::move(value);
6489 return {true, &root};
6492 // skip this value if we already decided to skip the parent
6493 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6494 if (!ref_stack.back())
6496 return {false, nullptr};
6499 // we now only expect arrays and objects
6500 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6503 if (ref_stack.back()->is_array())
6505 ref_stack.back()->m_value.array->emplace_back(std::move(value));
6506 return {true, &(ref_stack.back()->m_value.array->back())};
6510 JSON_ASSERT(ref_stack.back()->is_object());
6511 // check if we should store an element for the current key
6512 JSON_ASSERT(!key_keep_stack.empty());
6513 const bool store_element = key_keep_stack.back();
6514 key_keep_stack.pop_back();
6518 return {false, nullptr};
6521 JSON_ASSERT(object_element);
6522 *object_element = std::move(value);
6523 return {true, object_element};
6526 /// the parsed JSON value
6527 BasicJsonType& root;
6528 /// stack to model hierarchy of values
6529 std::vector<BasicJsonType*> ref_stack {};
6530 /// stack to manage which values to keep
6531 std::vector<bool> keep_stack {};
6532 /// stack to manage which object keys to keep
6533 std::vector<bool> key_keep_stack {};
6534 /// helper to hold the reference for the next object element
6535 BasicJsonType* object_element = nullptr;
6536 /// whether a syntax error occurred
6537 bool errored = false;
6538 /// callback function
6539 const parser_callback_t callback = nullptr;
6540 /// whether to throw exceptions in case of errors
6541 const bool allow_exceptions = true;
6542 /// a discarded value for the callback
6543 BasicJsonType discarded = BasicJsonType::value_t::discarded;
6546 template<typename BasicJsonType>
6547 class json_sax_acceptor
6550 using number_integer_t = typename BasicJsonType::number_integer_t;
6551 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6552 using number_float_t = typename BasicJsonType::number_float_t;
6553 using string_t = typename BasicJsonType::string_t;
6554 using binary_t = typename BasicJsonType::binary_t;
6561 bool boolean(bool /*unused*/)
6566 bool number_integer(number_integer_t /*unused*/)
6571 bool number_unsigned(number_unsigned_t /*unused*/)
6576 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6581 bool string(string_t& /*unused*/)
6586 bool binary(binary_t& /*unused*/)
6591 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
6596 bool key(string_t& /*unused*/)
6606 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
6616 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6621 } // namespace detail
6623 } // namespace nlohmann
6625 // #include <nlohmann/detail/input/lexer.hpp>
6628 #include <array> // array
6629 #include <clocale> // localeconv
6630 #include <cstddef> // size_t
6631 #include <cstdio> // snprintf
6632 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6633 #include <initializer_list> // initializer_list
6634 #include <string> // char_traits, string
6635 #include <utility> // move
6636 #include <vector> // vector
6638 // #include <nlohmann/detail/input/input_adapters.hpp>
6640 // #include <nlohmann/detail/input/position_t.hpp>
6642 // #include <nlohmann/detail/macro_scope.hpp>
6653 template<typename BasicJsonType>
6657 /// token types for the parser
6658 enum class token_type
6660 uninitialized, ///< indicating the scanner is uninitialized
6661 literal_true, ///< the `true` literal
6662 literal_false, ///< the `false` literal
6663 literal_null, ///< the `null` literal
6664 value_string, ///< a string -- use get_string() for actual value
6665 value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value
6666 value_integer, ///< a signed integer -- use get_number_integer() for actual value
6667 value_float, ///< an floating point number -- use get_number_float() for actual value
6668 begin_array, ///< the character for array begin `[`
6669 begin_object, ///< the character for object begin `{`
6670 end_array, ///< the character for array end `]`
6671 end_object, ///< the character for object end `}`
6672 name_separator, ///< the name separator `:`
6673 value_separator, ///< the value separator `,`
6674 parse_error, ///< indicating a parse error
6675 end_of_input, ///< indicating the end of the input buffer
6676 literal_or_value ///< a literal or the begin of a value (only for diagnostics)
6679 /// return name of values of type token_type (only used for errors)
6680 JSON_HEDLEY_RETURNS_NON_NULL
6682 static const char* token_type_name(const token_type t) noexcept
6686 case token_type::uninitialized:
6687 return "<uninitialized>";
6688 case token_type::literal_true:
6689 return "true literal";
6690 case token_type::literal_false:
6691 return "false literal";
6692 case token_type::literal_null:
6693 return "null literal";
6694 case token_type::value_string:
6695 return "string literal";
6696 case token_type::value_unsigned:
6697 case token_type::value_integer:
6698 case token_type::value_float:
6699 return "number literal";
6700 case token_type::begin_array:
6702 case token_type::begin_object:
6704 case token_type::end_array:
6706 case token_type::end_object:
6708 case token_type::name_separator:
6710 case token_type::value_separator:
6712 case token_type::parse_error:
6713 return "<parse error>";
6714 case token_type::end_of_input:
6715 return "end of input";
6716 case token_type::literal_or_value:
6717 return "'[', '{', or a literal";
6719 default: // catch non-enum values
6720 return "unknown token";
6726 @brief lexical analysis
6728 This class organizes the lexical analysis during JSON deserialization.
6730 template<typename BasicJsonType, typename InputAdapterType>
6731 class lexer : public lexer_base<BasicJsonType>
6733 using number_integer_t = typename BasicJsonType::number_integer_t;
6734 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6735 using number_float_t = typename BasicJsonType::number_float_t;
6736 using string_t = typename BasicJsonType::string_t;
6737 using char_type = typename InputAdapterType::char_type;
6738 using char_int_type = typename std::char_traits<char_type>::int_type;
6741 using token_type = typename lexer_base<BasicJsonType>::token_type;
6743 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6744 : ia(std::move(adapter))
6745 , ignore_comments(ignore_comments_)
6746 , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6749 // delete because of pointer members
6750 lexer(const lexer&) = delete;
6751 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6752 lexer& operator=(lexer&) = delete;
6753 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6757 /////////////////////
6759 /////////////////////
6761 /// return the locale-dependent decimal point
6763 static char get_decimal_point() noexcept
6765 const auto* loc = localeconv();
6766 JSON_ASSERT(loc != nullptr);
6767 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6770 /////////////////////
6772 /////////////////////
6775 @brief get codepoint from 4 hex characters following `\u`
6777 For input "\u c1 c2 c3 c4" the codepoint is:
6778 (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
6779 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
6781 Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
6782 must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
6783 conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
6784 between the ASCII value of the character and the desired integer value.
6786 @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
6791 // this function only makes sense after reading `\u`
6792 JSON_ASSERT(current == 'u');
6795 const auto factors = { 12u, 8u, 4u, 0u };
6796 for (const auto factor : factors)
6800 if (current >= '0' && current <= '9')
6802 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6804 else if (current >= 'A' && current <= 'F')
6806 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6808 else if (current >= 'a' && current <= 'f')
6810 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6818 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6823 @brief check if the next byte(s) are inside a given range
6825 Adds the current byte and, for each passed range, reads a new byte and
6826 checks if it is inside the range. If a violation was detected, set up an
6827 error message and return false. Otherwise, return true.
6829 @param[in] ranges list of integers; interpreted as list of pairs of
6830 inclusive lower and upper bound, respectively
6832 @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
6833 1, 2, or 3 pairs. This precondition is enforced by an assertion.
6835 @return true if and only if no range violation was detected
6837 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6839 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6842 for (auto range = ranges.begin(); range != ranges.end(); ++range)
6845 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6851 error_message = "invalid string: ill-formed UTF-8 byte";
6860 @brief scan a string literal
6862 This function scans a string according to Sect. 7 of RFC 8259. While
6863 scanning, bytes are escaped and copied into buffer token_buffer. Then the
6864 function returns successfully, token_buffer is *not* null-terminated (as it
6865 may contain \0 bytes), and token_buffer.size() is the number of bytes in the
6868 @return token_type::value_string if string could be successfully scanned,
6869 token_type::parse_error otherwise
6871 @note In case of errors, variable error_message contains a textual
6874 token_type scan_string()
6876 // reset token_buffer (ignore opening quote)
6879 // we entered the function by reading an open quote
6880 JSON_ASSERT(current == '\"');
6884 // get next character
6887 // end of file while parsing string
6888 case std::char_traits<char_type>::eof():
6890 error_message = "invalid string: missing closing quote";
6891 return token_type::parse_error;
6897 return token_type::value_string;
6941 const int codepoint1 = get_codepoint();
6942 int codepoint = codepoint1; // start with codepoint1
6944 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6946 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6947 return token_type::parse_error;
6950 // check if code point is a high surrogate
6951 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6953 // expect next \uxxxx entry
6954 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6956 const int codepoint2 = get_codepoint();
6958 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6960 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6961 return token_type::parse_error;
6964 // check if codepoint2 is a low surrogate
6965 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6967 // overwrite codepoint
6968 codepoint = static_cast<int>(
6969 // high surrogate occupies the most significant 22 bits
6970 (static_cast<unsigned int>(codepoint1) << 10u)
6971 // low surrogate occupies the least significant 15 bits
6972 + static_cast<unsigned int>(codepoint2)
6973 // there is still the 0xD800, 0xDC00 and 0x10000 noise
6974 // in the result so we have to subtract with:
6975 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6980 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6981 return token_type::parse_error;
6986 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6987 return token_type::parse_error;
6992 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6994 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6995 return token_type::parse_error;
6999 // result of the above calculation yields a proper codepoint
7000 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7002 // translate codepoint into bytes
7003 if (codepoint < 0x80)
7005 // 1-byte characters: 0xxxxxxx (ASCII)
7006 add(static_cast<char_int_type>(codepoint));
7008 else if (codepoint <= 0x7FF)
7010 // 2-byte characters: 110xxxxx 10xxxxxx
7011 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7012 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7014 else if (codepoint <= 0xFFFF)
7016 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7017 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7018 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7019 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7023 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7024 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7025 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7026 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7027 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7033 // other characters after escape
7035 error_message = "invalid string: forbidden character after backslash";
7036 return token_type::parse_error;
7042 // invalid control characters
7045 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7046 return token_type::parse_error;
7051 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7052 return token_type::parse_error;
7057 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7058 return token_type::parse_error;
7063 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7064 return token_type::parse_error;
7069 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7070 return token_type::parse_error;
7075 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7076 return token_type::parse_error;
7081 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7082 return token_type::parse_error;
7087 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7088 return token_type::parse_error;
7093 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7094 return token_type::parse_error;
7099 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7100 return token_type::parse_error;
7105 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7106 return token_type::parse_error;
7111 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7112 return token_type::parse_error;
7117 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7118 return token_type::parse_error;
7123 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7124 return token_type::parse_error;
7129 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7130 return token_type::parse_error;
7135 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7136 return token_type::parse_error;
7141 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7142 return token_type::parse_error;
7147 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7148 return token_type::parse_error;
7153 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7154 return token_type::parse_error;
7159 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7160 return token_type::parse_error;
7165 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7166 return token_type::parse_error;
7171 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7172 return token_type::parse_error;
7177 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7178 return token_type::parse_error;
7183 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7184 return token_type::parse_error;
7189 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7190 return token_type::parse_error;
7195 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7196 return token_type::parse_error;
7201 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7202 return token_type::parse_error;
7207 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7208 return token_type::parse_error;
7213 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7214 return token_type::parse_error;
7219 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7220 return token_type::parse_error;
7225 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7226 return token_type::parse_error;
7231 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7232 return token_type::parse_error;
7235 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7335 // U+0080..U+07FF: bytes C2..DF 80..BF
7367 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7369 return token_type::parse_error;
7374 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7377 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7379 return token_type::parse_error;
7384 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7385 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7401 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7403 return token_type::parse_error;
7408 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7411 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7413 return token_type::parse_error;
7418 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7421 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7423 return token_type::parse_error;
7428 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7433 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7435 return token_type::parse_error;
7440 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7443 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7445 return token_type::parse_error;
7450 // remaining bytes (80..C1 and F5..FF) are ill-formed
7453 error_message = "invalid string: ill-formed UTF-8 byte";
7454 return token_type::parse_error;
7461 * @brief scan a comment
7462 * @return whether comment could be scanned successfully
7468 // single-line comments skip input until a newline or EOF is read
7477 case std::char_traits<char_type>::eof():
7487 // multi-line comments skip input until */ is read
7494 case std::char_traits<char_type>::eof():
7497 error_message = "invalid comment; missing closing '*/'";
7522 // unexpected character after reading '/'
7525 error_message = "invalid comment; expecting '/' or '*' after '/'";
7531 JSON_HEDLEY_NON_NULL(2)
7532 static void strtof(float& f, const char* str, char** endptr) noexcept
7534 f = std::strtof(str, endptr);
7537 JSON_HEDLEY_NON_NULL(2)
7538 static void strtof(double& f, const char* str, char** endptr) noexcept
7540 f = std::strtod(str, endptr);
7543 JSON_HEDLEY_NON_NULL(2)
7544 static void strtof(long double& f, const char* str, char** endptr) noexcept
7546 f = std::strtold(str, endptr);
7550 @brief scan a number literal
7552 This function scans a string according to Sect. 6 of RFC 8259.
7554 The function is realized with a deterministic finite state machine derived
7555 from the grammar described in RFC 8259. Starting in state "init", the
7556 input is read and used to determined the next state. Only state "done"
7557 accepts the number. State "error" is a trap state to model errors. In the
7558 table below, "anything" means any character but the ones listed before.
7560 state | 0 | 1-9 | e E | + | - | . | anything
7561 ---------|----------|----------|----------|---------|---------|----------|-----------
7562 init | zero | any1 | [error] | [error] | minus | [error] | [error]
7563 minus | zero | any1 | [error] | [error] | [error] | [error] | [error]
7564 zero | done | done | exponent | done | done | decimal1 | done
7565 any1 | any1 | any1 | exponent | done | done | decimal1 | done
7566 decimal1 | decimal2 | decimal2 | [error] | [error] | [error] | [error] | [error]
7567 decimal2 | decimal2 | decimal2 | exponent | done | done | done | done
7568 exponent | any2 | any2 | [error] | sign | sign | [error] | [error]
7569 sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]
7570 any2 | any2 | any2 | done | done | done | done | done
7572 The state machine is realized with one label per state (prefixed with
7573 "scan_number_") and `goto` statements between them. The state machine
7574 contains cycles, but any cycle can be left when EOF is read. Therefore,
7575 the function is guaranteed to terminate.
7577 During scanning, the read bytes are stored in token_buffer. This string is
7578 then converted to a signed integer, an unsigned integer, or a
7579 floating-point number.
7581 @return token_type::value_unsigned, token_type::value_integer, or
7582 token_type::value_float if number could be successfully scanned,
7583 token_type::parse_error otherwise
7585 @note The scanner is independent of the current locale. Internally, the
7586 locale's decimal point is used instead of `.` to work with the
7587 locale-dependent converters.
7589 token_type scan_number() // lgtm [cpp/use-of-goto]
7591 // reset token_buffer to store the number's bytes
7594 // the type of the parsed number; initially set to unsigned; will be
7595 // changed if minus sign, decimal point or exponent is read
7596 token_type number_type = token_type::value_unsigned;
7598 // state (init): we just found out we need to scan a number
7604 goto scan_number_minus;
7610 goto scan_number_zero;
7624 goto scan_number_any1;
7627 // all other characters are rejected outside scan_number()
7628 default: // LCOV_EXCL_LINE
7629 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7633 // state: we just parsed a leading minus sign
7634 number_type = token_type::value_integer;
7640 goto scan_number_zero;
7654 goto scan_number_any1;
7659 error_message = "invalid number; expected digit after '-'";
7660 return token_type::parse_error;
7665 // state: we just parse a zero (maybe with a leading minus sign)
7670 add(decimal_point_char);
7671 goto scan_number_decimal1;
7678 goto scan_number_exponent;
7682 goto scan_number_done;
7686 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7701 goto scan_number_any1;
7706 add(decimal_point_char);
7707 goto scan_number_decimal1;
7714 goto scan_number_exponent;
7718 goto scan_number_done;
7721 scan_number_decimal1:
7722 // state: we just parsed a decimal point
7723 number_type = token_type::value_float;
7738 goto scan_number_decimal2;
7743 error_message = "invalid number; expected digit after '.'";
7744 return token_type::parse_error;
7748 scan_number_decimal2:
7749 // we just parsed at least one number after a decimal point
7764 goto scan_number_decimal2;
7771 goto scan_number_exponent;
7775 goto scan_number_done;
7778 scan_number_exponent:
7779 // we just parsed an exponent
7780 number_type = token_type::value_float;
7787 goto scan_number_sign;
7802 goto scan_number_any2;
7808 "invalid number; expected '+', '-', or digit after exponent";
7809 return token_type::parse_error;
7814 // we just parsed an exponent sign
7829 goto scan_number_any2;
7834 error_message = "invalid number; expected digit after exponent sign";
7835 return token_type::parse_error;
7840 // we just parsed a number after the exponent or exponent sign
7855 goto scan_number_any2;
7859 goto scan_number_done;
7863 // unget the character after the number (we only read it to know that
7864 // we are done scanning a number)
7867 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7870 // try to parse integers first and fall back to floats
7871 if (number_type == token_type::value_unsigned)
7873 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7875 // we checked the number format before
7876 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7880 value_unsigned = static_cast<number_unsigned_t>(x);
7881 if (value_unsigned == x)
7883 return token_type::value_unsigned;
7887 else if (number_type == token_type::value_integer)
7889 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7891 // we checked the number format before
7892 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7896 value_integer = static_cast<number_integer_t>(x);
7897 if (value_integer == x)
7899 return token_type::value_integer;
7904 // this code is reached if we parse a floating-point number or if an
7905 // integer conversion above failed
7906 strtof(value_float, token_buffer.data(), &endptr);
7908 // we checked the number format before
7909 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7911 return token_type::value_float;
7915 @param[in] literal_text the literal text to expect
7916 @param[in] length the length of the passed literal text
7917 @param[in] return_type the token type to return on success
7919 JSON_HEDLEY_NON_NULL(2)
7920 token_type scan_literal(const char_type* literal_text, const std::size_t length,
7921 token_type return_type)
7923 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7924 for (std::size_t i = 1; i < length; ++i)
7926 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7928 error_message = "invalid literal";
7929 return token_type::parse_error;
7935 /////////////////////
7937 /////////////////////
7939 /// reset token_buffer; current character is beginning of token
7940 void reset() noexcept
7942 token_buffer.clear();
7943 token_string.clear();
7944 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7948 @brief get next character from the input
7950 This function provides the interface to the used input adapter. It does
7951 not throw in case the input reached EOF, but returns a
7952 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7953 for use in error messages.
7955 @return character read from the input
7959 ++position.chars_read_total;
7960 ++position.chars_read_current_line;
7964 // just reset the next_unget variable and work with current
7969 current = ia.get_character();
7972 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7974 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7977 if (current == '\n')
7979 ++position.lines_read;
7980 position.chars_read_current_line = 0;
7987 @brief unget current character (read it again on next get)
7989 We implement unget by setting variable next_unget to true. The input is not
7990 changed - we just simulate ungetting by modifying chars_read_total,
7991 chars_read_current_line, and token_string. The next call to get() will
7992 behave as if the unget character is read again.
7998 --position.chars_read_total;
8000 // in case we "unget" a newline, we have to also decrement the lines_read
8001 if (position.chars_read_current_line == 0)
8003 if (position.lines_read > 0)
8005 --position.lines_read;
8010 --position.chars_read_current_line;
8013 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8015 JSON_ASSERT(!token_string.empty());
8016 token_string.pop_back();
8020 /// add a character to token_buffer
8021 void add(char_int_type c)
8023 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8027 /////////////////////
8029 /////////////////////
8031 /// return integer value
8032 constexpr number_integer_t get_number_integer() const noexcept
8034 return value_integer;
8037 /// return unsigned integer value
8038 constexpr number_unsigned_t get_number_unsigned() const noexcept
8040 return value_unsigned;
8043 /// return floating-point value
8044 constexpr number_float_t get_number_float() const noexcept
8049 /// return current string value (implicitly resets the token; useful only once)
8050 string_t& get_string()
8052 return token_buffer;
8055 /////////////////////
8057 /////////////////////
8059 /// return position of last read token
8060 constexpr position_t get_position() const noexcept
8065 /// return the last read token (for errors only). Will never contain EOF
8066 /// (an arbitrary value that is not a valid char value, often -1), because
8067 /// 255 may legitimately occur. May contain NUL, which should be escaped.
8068 std::string get_token_string() const
8070 // escape control characters
8072 for (const auto c : token_string)
8074 if (static_cast<unsigned char>(c) <= '\x1F')
8076 // escape control characters
8077 std::array<char, 9> cs{{}};
8078 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8079 result += cs.data();
8083 // add character as is
8084 result.push_back(static_cast<std::string::value_type>(c));
8091 /// return syntax error message
8092 JSON_HEDLEY_RETURNS_NON_NULL
8093 constexpr const char* get_error_message() const noexcept
8095 return error_message;
8098 /////////////////////
8100 /////////////////////
8103 @brief skip the UTF-8 byte order mark
8104 @return true iff there is no BOM or the correct BOM has been skipped
8110 // check if we completely parse the BOM
8111 return get() == 0xBB && get() == 0xBF;
8114 // the first character is not the beginning of the BOM; unget it to
8120 void skip_whitespace()
8126 while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8131 // initially, skip the BOM
8132 if (position.chars_read_total == 0 && !skip_bom())
8134 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8135 return token_type::parse_error;
8138 // read next character and ignore whitespace
8142 while (ignore_comments && current == '/')
8144 if (!scan_comment())
8146 return token_type::parse_error;
8149 // skip following whitespace
8155 // structural characters
8157 return token_type::begin_array;
8159 return token_type::end_array;
8161 return token_type::begin_object;
8163 return token_type::end_object;
8165 return token_type::name_separator;
8167 return token_type::value_separator;
8172 std::array<char_type, 4> true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}};
8173 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8177 std::array<char_type, 5> false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}};
8178 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8182 std::array<char_type, 4> null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}};
8183 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8188 return scan_string();
8202 return scan_number();
8204 // end of input (the null byte is needed when parsing from
8207 case std::char_traits<char_type>::eof():
8208 return token_type::end_of_input;
8212 error_message = "invalid literal";
8213 return token_type::parse_error;
8219 InputAdapterType ia;
8221 /// whether comments should be ignored (true) or signaled as errors (false)
8222 const bool ignore_comments = false;
8224 /// the current character
8225 char_int_type current = std::char_traits<char_type>::eof();
8227 /// whether the next get() call should just return current
8228 bool next_unget = false;
8230 /// the start position of the current token
8231 position_t position {};
8233 /// raw input token string (for error messages)
8234 std::vector<char_type> token_string {};
8236 /// buffer for variable-length tokens (numbers, strings)
8237 string_t token_buffer {};
8239 /// a description of occurred lexer errors
8240 const char* error_message = "";
8243 number_integer_t value_integer = 0;
8244 number_unsigned_t value_unsigned = 0;
8245 number_float_t value_float = 0;
8247 /// the decimal point
8248 const char_int_type decimal_point_char = '.';
8250 } // namespace detail
8251 } // namespace nlohmann
8253 // #include <nlohmann/detail/macro_scope.hpp>
8255 // #include <nlohmann/detail/meta/is_sax.hpp>
8258 #include <cstdint> // size_t
8259 #include <utility> // declval
8260 #include <string> // string
8262 // #include <nlohmann/detail/meta/detected.hpp>
8264 // #include <nlohmann/detail/meta/type_traits.hpp>
8271 template<typename T>
8272 using null_function_t = decltype(std::declval<T&>().null());
8274 template<typename T>
8275 using boolean_function_t =
8276 decltype(std::declval<T&>().boolean(std::declval<bool>()));
8278 template<typename T, typename Integer>
8279 using number_integer_function_t =
8280 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8282 template<typename T, typename Unsigned>
8283 using number_unsigned_function_t =
8284 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8286 template<typename T, typename Float, typename String>
8287 using number_float_function_t = decltype(std::declval<T&>().number_float(
8288 std::declval<Float>(), std::declval<const String&>()));
8290 template<typename T, typename String>
8291 using string_function_t =
8292 decltype(std::declval<T&>().string(std::declval<String&>()));
8294 template<typename T, typename Binary>
8295 using binary_function_t =
8296 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8298 template<typename T>
8299 using start_object_function_t =
8300 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8302 template<typename T, typename String>
8303 using key_function_t =
8304 decltype(std::declval<T&>().key(std::declval<String&>()));
8306 template<typename T>
8307 using end_object_function_t = decltype(std::declval<T&>().end_object());
8309 template<typename T>
8310 using start_array_function_t =
8311 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8313 template<typename T>
8314 using end_array_function_t = decltype(std::declval<T&>().end_array());
8316 template<typename T, typename Exception>
8317 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8318 std::declval<std::size_t>(), std::declval<const std::string&>(),
8319 std::declval<const Exception&>()));
8321 template<typename SAX, typename BasicJsonType>
8325 static_assert(is_basic_json<BasicJsonType>::value,
8326 "BasicJsonType must be of type basic_json<...>");
8328 using number_integer_t = typename BasicJsonType::number_integer_t;
8329 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8330 using number_float_t = typename BasicJsonType::number_float_t;
8331 using string_t = typename BasicJsonType::string_t;
8332 using binary_t = typename BasicJsonType::binary_t;
8333 using exception_t = typename BasicJsonType::exception;
8336 static constexpr bool value =
8337 is_detected_exact<bool, null_function_t, SAX>::value &&
8338 is_detected_exact<bool, boolean_function_t, SAX>::value &&
8339 is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
8340 is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
8341 is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
8342 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
8343 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
8344 is_detected_exact<bool, start_object_function_t, SAX>::value &&
8345 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
8346 is_detected_exact<bool, end_object_function_t, SAX>::value &&
8347 is_detected_exact<bool, start_array_function_t, SAX>::value &&
8348 is_detected_exact<bool, end_array_function_t, SAX>::value &&
8349 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
8352 template<typename SAX, typename BasicJsonType>
8353 struct is_sax_static_asserts
8356 static_assert(is_basic_json<BasicJsonType>::value,
8357 "BasicJsonType must be of type basic_json<...>");
8359 using number_integer_t = typename BasicJsonType::number_integer_t;
8360 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8361 using number_float_t = typename BasicJsonType::number_float_t;
8362 using string_t = typename BasicJsonType::string_t;
8363 using binary_t = typename BasicJsonType::binary_t;
8364 using exception_t = typename BasicJsonType::exception;
8367 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
8368 "Missing/invalid function: bool null()");
8369 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8370 "Missing/invalid function: bool boolean(bool)");
8371 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8372 "Missing/invalid function: bool boolean(bool)");
8374 is_detected_exact<bool, number_integer_function_t, SAX,
8375 number_integer_t>::value,
8376 "Missing/invalid function: bool number_integer(number_integer_t)");
8378 is_detected_exact<bool, number_unsigned_function_t, SAX,
8379 number_unsigned_t>::value,
8380 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8381 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8382 number_float_t, string_t>::value,
8383 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8385 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
8386 "Missing/invalid function: bool string(string_t&)");
8388 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
8389 "Missing/invalid function: bool binary(binary_t&)");
8390 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
8391 "Missing/invalid function: bool start_object(std::size_t)");
8392 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
8393 "Missing/invalid function: bool key(string_t&)");
8394 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
8395 "Missing/invalid function: bool end_object()");
8396 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
8397 "Missing/invalid function: bool start_array(std::size_t)");
8398 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
8399 "Missing/invalid function: bool end_array()");
8401 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
8402 "Missing/invalid function: bool parse_error(std::size_t, const "
8403 "std::string&, const exception&)");
8405 } // namespace detail
8406 } // namespace nlohmann
8408 // #include <nlohmann/detail/meta/type_traits.hpp>
8410 // #include <nlohmann/detail/value_t.hpp>
8418 /// how to treat CBOR tags
8419 enum class cbor_tag_handler_t
8421 error, ///< throw a parse_error exception in case of a tag
8422 ignore, ///< ignore tags
8423 store ///< store tags as binary type
8427 @brief determine system byte order
8429 @return true if and only if system's byte order is little endian
8431 @note from https://stackoverflow.com/a/1001328/266378
8433 static inline bool little_endianness(int num = 1) noexcept
8435 return *reinterpret_cast<char*>(&num) == 1;
8444 @brief deserialization of CBOR, MessagePack, and UBJSON values
8446 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8449 using number_integer_t = typename BasicJsonType::number_integer_t;
8450 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8451 using number_float_t = typename BasicJsonType::number_float_t;
8452 using string_t = typename BasicJsonType::string_t;
8453 using binary_t = typename BasicJsonType::binary_t;
8454 using json_sax_t = SAX;
8455 using char_type = typename InputAdapterType::char_type;
8456 using char_int_type = typename std::char_traits<char_type>::int_type;
8460 @brief create a binary reader
8462 @param[in] adapter input adapter to read from
8464 explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
8466 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
8469 // make class move-only
8470 binary_reader(const binary_reader&) = delete;
8471 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8472 binary_reader& operator=(const binary_reader&) = delete;
8473 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8474 ~binary_reader() = default;
8477 @param[in] format the binary format to parse
8478 @param[in] sax_ a SAX event processor
8479 @param[in] strict whether to expect the input to be consumed completed
8480 @param[in] tag_handler how to treat CBOR tags
8482 @return whether parsing was successful
8484 JSON_HEDLEY_NON_NULL(3)
8485 bool sax_parse(const input_format_t format,
8487 const bool strict = true,
8488 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8491 bool result = false;
8495 case input_format_t::bson:
8496 result = parse_bson_internal();
8499 case input_format_t::cbor:
8500 result = parse_cbor_internal(true, tag_handler);
8503 case input_format_t::msgpack:
8504 result = parse_msgpack_internal();
8507 case input_format_t::ubjson:
8508 result = parse_ubjson_internal();
8511 case input_format_t::json: // LCOV_EXCL_LINE
8512 default: // LCOV_EXCL_LINE
8513 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8516 // strict mode: next byte must be EOF
8517 if (result && strict)
8519 if (format == input_format_t::ubjson)
8528 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8530 return sax->parse_error(chars_read, get_token_string(),
8531 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
8544 @brief Reads in a BSON-object and passes it to the SAX-parser.
8545 @return whether a valid BSON-value was passed to the SAX parser
8547 bool parse_bson_internal()
8549 std::int32_t document_size{};
8550 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8552 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
8557 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8562 return sax->end_object();
8566 @brief Parses a C-style string from the BSON input.
8567 @param[in,out] result A reference to the string variable where the read
8568 string is to be stored.
8569 @return `true` if the \x00-byte indicating the end of the string was
8570 encountered before the EOF; false` indicates an unexpected EOF.
8572 bool get_bson_cstr(string_t& result)
8574 auto out = std::back_inserter(result);
8578 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
8582 if (current == 0x00)
8586 *out++ = static_cast<typename string_t::value_type>(current);
8591 @brief Parses a zero-terminated string of length @a len from the BSON
8593 @param[in] len The length (including the zero-byte at the end) of the
8595 @param[in,out] result A reference to the string variable where the read
8596 string is to be stored.
8597 @tparam NumberType The type of the length @a len
8599 @return `true` if the string was successfully parsed
8601 template<typename NumberType>
8602 bool get_bson_string(const NumberType len, string_t& result)
8604 if (JSON_HEDLEY_UNLIKELY(len < 1))
8606 auto last_token = get_token_string();
8607 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string"), BasicJsonType()));
8610 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8614 @brief Parses a byte array input of length @a len from the BSON input.
8615 @param[in] len The length of the byte array to be read.
8616 @param[in,out] result A reference to the binary variable where the read
8617 array is to be stored.
8618 @tparam NumberType The type of the length @a len
8620 @return `true` if the byte array was successfully parsed
8622 template<typename NumberType>
8623 bool get_bson_binary(const NumberType len, binary_t& result)
8625 if (JSON_HEDLEY_UNLIKELY(len < 0))
8627 auto last_token = get_token_string();
8628 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary"), BasicJsonType()));
8631 // All BSON binary values have a subtype
8632 std::uint8_t subtype{};
8633 get_number<std::uint8_t>(input_format_t::bson, subtype);
8634 result.set_subtype(subtype);
8636 return get_binary(input_format_t::bson, len, result);
8640 @brief Read a BSON document element of the given @a element_type.
8641 @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
8642 @param[in] element_type_parse_position The position in the input stream,
8643 where the `element_type` was read.
8644 @warning Not all BSON element types are supported yet. An unsupported
8645 @a element_type will give rise to a parse_error.114:
8646 Unsupported BSON record type 0x...
8647 @return whether a valid BSON-object/array was passed to the SAX parser
8649 bool parse_bson_element_internal(const char_int_type element_type,
8650 const std::size_t element_type_parse_position)
8652 switch (element_type)
8654 case 0x01: // double
8657 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8660 case 0x02: // string
8664 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8667 case 0x03: // object
8669 return parse_bson_internal();
8674 return parse_bson_array();
8677 case 0x05: // binary
8681 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8684 case 0x08: // boolean
8686 return sax->boolean(get() != 0);
8696 std::int32_t value{};
8697 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8702 std::int64_t value{};
8703 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8706 default: // anything else not supported (yet)
8708 std::array<char, 3> cr{{}};
8709 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8710 return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data()), BasicJsonType()));
8716 @brief Read a BSON element list (as specified in the BSON-spec)
8718 The same binary layout is used for objects and arrays, hence it must be
8719 indicated with the argument @a is_array which one is expected
8720 (true --> array, false --> object).
8722 @param[in] is_array Determines if the element list being read is to be
8723 treated as an object (@a is_array == false), or as an
8724 array (@a is_array == true).
8725 @return whether a valid BSON-object/array was passed to the SAX parser
8727 bool parse_bson_element_list(const bool is_array)
8731 while (auto element_type = get())
8733 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8738 const std::size_t element_type_parse_position = chars_read;
8739 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8744 if (!is_array && !sax->key(key))
8749 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8754 // get_bson_cstr only appends
8762 @brief Reads an array from the BSON input and passes it to the SAX-parser.
8763 @return whether a valid BSON-array was passed to the SAX parser
8765 bool parse_bson_array()
8767 std::int32_t document_size{};
8768 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8770 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8775 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8780 return sax->end_array();
8788 @param[in] get_char whether a new character should be retrieved from the
8789 input (true) or whether the last read character should
8790 be considered instead (false)
8791 @param[in] tag_handler how CBOR tags should be treated
8793 @return whether a valid CBOR value was passed to the SAX parser
8795 bool parse_cbor_internal(const bool get_char,
8796 const cbor_tag_handler_t tag_handler)
8798 switch (get_char ? get() : current)
8801 case std::char_traits<char_type>::eof():
8802 return unexpect_eof(input_format_t::cbor, "value");
8804 // Integer 0x00..0x17 (0..23)
8829 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8831 case 0x18: // Unsigned integer (one-byte uint8_t follows)
8833 std::uint8_t number{};
8834 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8837 case 0x19: // Unsigned integer (two-byte uint16_t follows)
8839 std::uint16_t number{};
8840 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8843 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8845 std::uint32_t number{};
8846 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8849 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8851 std::uint64_t number{};
8852 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8855 // Negative integer -1-0x00..-1-0x17 (-1..-24)
8880 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8882 case 0x38: // Negative integer (one-byte uint8_t follows)
8884 std::uint8_t number{};
8885 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8888 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8890 std::uint16_t number{};
8891 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8894 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8896 std::uint32_t number{};
8897 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8900 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8902 std::uint64_t number{};
8903 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8904 - static_cast<number_integer_t>(number));
8907 // Binary data (0x00..0x17 bytes follow)
8932 case 0x58: // Binary data (one-byte uint8_t for n follows)
8933 case 0x59: // Binary data (two-byte uint16_t for n follow)
8934 case 0x5A: // Binary data (four-byte uint32_t for n follow)
8935 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8936 case 0x5F: // Binary data (indefinite length)
8939 return get_cbor_binary(b) && sax->binary(b);
8942 // UTF-8 string (0x00..0x17 bytes follow)
8967 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8968 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8969 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8970 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8971 case 0x7F: // UTF-8 string (indefinite length)
8974 return get_cbor_string(s) && sax->string(s);
8977 // array (0x00..0x17 data items follow)
9002 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9004 case 0x98: // array (one-byte uint8_t for n follows)
9007 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9010 case 0x99: // array (two-byte uint16_t for n follow)
9012 std::uint16_t len{};
9013 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9016 case 0x9A: // array (four-byte uint32_t for n follow)
9018 std::uint32_t len{};
9019 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9022 case 0x9B: // array (eight-byte uint64_t for n follow)
9024 std::uint64_t len{};
9025 return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9028 case 0x9F: // array (indefinite length)
9029 return get_cbor_array(std::size_t(-1), tag_handler);
9031 // map (0x00..0x17 pairs of data items follow)
9056 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9058 case 0xB8: // map (one-byte uint8_t for n follows)
9061 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9064 case 0xB9: // map (two-byte uint16_t for n follow)
9066 std::uint16_t len{};
9067 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9070 case 0xBA: // map (four-byte uint32_t for n follow)
9072 std::uint32_t len{};
9073 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9076 case 0xBB: // map (eight-byte uint64_t for n follow)
9078 std::uint64_t len{};
9079 return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9082 case 0xBF: // map (indefinite length)
9083 return get_cbor_object(std::size_t(-1), tag_handler);
9085 case 0xC6: // tagged item
9100 case 0xD8: // tagged item (1 bytes follow)
9101 case 0xD9: // tagged item (2 bytes follow)
9102 case 0xDA: // tagged item (4 bytes follow)
9103 case 0xDB: // tagged item (8 bytes follow)
9105 switch (tag_handler)
9107 case cbor_tag_handler_t::error:
9109 auto last_token = get_token_string();
9110 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9113 case cbor_tag_handler_t::ignore:
9115 // ignore binary subtype
9120 std::uint8_t subtype_to_ignore{};
9121 get_number(input_format_t::cbor, subtype_to_ignore);
9126 std::uint16_t subtype_to_ignore{};
9127 get_number(input_format_t::cbor, subtype_to_ignore);
9132 std::uint32_t subtype_to_ignore{};
9133 get_number(input_format_t::cbor, subtype_to_ignore);
9138 std::uint64_t subtype_to_ignore{};
9139 get_number(input_format_t::cbor, subtype_to_ignore);
9145 return parse_cbor_internal(true, tag_handler);
9148 case cbor_tag_handler_t::store:
9151 // use binary subtype and store in binary container
9156 std::uint8_t subtype{};
9157 get_number(input_format_t::cbor, subtype);
9158 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9163 std::uint16_t subtype{};
9164 get_number(input_format_t::cbor, subtype);
9165 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9170 std::uint32_t subtype{};
9171 get_number(input_format_t::cbor, subtype);
9172 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9177 std::uint64_t subtype{};
9178 get_number(input_format_t::cbor, subtype);
9179 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9183 return parse_cbor_internal(true, tag_handler);
9186 return get_cbor_binary(b) && sax->binary(b);
9189 default: // LCOV_EXCL_LINE
9190 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9191 return false; // LCOV_EXCL_LINE
9196 return sax->boolean(false);
9199 return sax->boolean(true);
9204 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9206 const auto byte1_raw = get();
9207 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9211 const auto byte2_raw = get();
9212 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9217 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9218 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9220 // code from RFC 7049, Appendix D, Figure 3:
9221 // As half-precision floating-point numbers were only added
9222 // to IEEE 754 in 2008, today's programming platforms often
9223 // still only have limited support for them. It is very
9224 // easy to include at least decoding support for them even
9225 // without such support. An example of a small decoder for
9226 // half-precision floating-point numbers in the C language
9227 // is shown in Fig. 3.
9228 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9229 const double val = [&half]
9231 const int exp = (half >> 10u) & 0x1Fu;
9232 const unsigned int mant = half & 0x3FFu;
9233 JSON_ASSERT(0 <= exp&& exp <= 32);
9234 JSON_ASSERT(mant <= 1024);
9238 return std::ldexp(mant, -24);
9241 ? std::numeric_limits<double>::infinity()
9242 : std::numeric_limits<double>::quiet_NaN();
9244 return std::ldexp(mant + 1024, exp - 25);
9247 return sax->number_float((half & 0x8000u) != 0
9248 ? static_cast<number_float_t>(-val)
9249 : static_cast<number_float_t>(val), "");
9252 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9255 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9258 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9261 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9264 default: // anything else (0xFF is handled inside the other types)
9266 auto last_token = get_token_string();
9267 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9273 @brief reads a CBOR string
9275 This function first reads starting bytes to determine the expected
9276 string length and then copies this number of bytes into a string.
9277 Additionally, CBOR's strings with indefinite lengths are supported.
9279 @param[out] result created string
9281 @return whether string creation completed
9283 bool get_cbor_string(string_t& result)
9285 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9292 // UTF-8 string (0x00..0x17 bytes follow)
9318 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9321 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9324 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9327 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9329 std::uint16_t len{};
9330 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9333 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9335 std::uint32_t len{};
9336 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9339 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9341 std::uint64_t len{};
9342 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9345 case 0x7F: // UTF-8 string (indefinite length)
9347 while (get() != 0xFF)
9350 if (!get_cbor_string(chunk))
9354 result.append(chunk);
9361 auto last_token = get_token_string();
9362 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string"), BasicJsonType()));
9368 @brief reads a CBOR byte array
9370 This function first reads starting bytes to determine the expected
9371 byte array length and then copies this number of bytes into the byte array.
9372 Additionally, CBOR's byte arrays with indefinite lengths are supported.
9374 @param[out] result created byte array
9376 @return whether byte array creation completed
9378 bool get_cbor_binary(binary_t& result)
9380 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
9387 // Binary data (0x00..0x17 bytes follow)
9413 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9416 case 0x58: // Binary data (one-byte uint8_t for n follows)
9419 return get_number(input_format_t::cbor, len) &&
9420 get_binary(input_format_t::cbor, len, result);
9423 case 0x59: // Binary data (two-byte uint16_t for n follow)
9425 std::uint16_t len{};
9426 return get_number(input_format_t::cbor, len) &&
9427 get_binary(input_format_t::cbor, len, result);
9430 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9432 std::uint32_t len{};
9433 return get_number(input_format_t::cbor, len) &&
9434 get_binary(input_format_t::cbor, len, result);
9437 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9439 std::uint64_t len{};
9440 return get_number(input_format_t::cbor, len) &&
9441 get_binary(input_format_t::cbor, len, result);
9444 case 0x5F: // Binary data (indefinite length)
9446 while (get() != 0xFF)
9449 if (!get_cbor_binary(chunk))
9453 result.insert(result.end(), chunk.begin(), chunk.end());
9460 auto last_token = get_token_string();
9461 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary"), BasicJsonType()));
9467 @param[in] len the length of the array or std::size_t(-1) for an
9468 array of indefinite size
9469 @param[in] tag_handler how CBOR tags should be treated
9470 @return whether array creation completed
9472 bool get_cbor_array(const std::size_t len,
9473 const cbor_tag_handler_t tag_handler)
9475 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9480 if (len != std::size_t(-1))
9482 for (std::size_t i = 0; i < len; ++i)
9484 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9492 while (get() != 0xFF)
9494 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9501 return sax->end_array();
9505 @param[in] len the length of the object or std::size_t(-1) for an
9506 object of indefinite size
9507 @param[in] tag_handler how CBOR tags should be treated
9508 @return whether object creation completed
9510 bool get_cbor_object(const std::size_t len,
9511 const cbor_tag_handler_t tag_handler)
9513 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9521 if (len != std::size_t(-1))
9523 for (std::size_t i = 0; i < len; ++i)
9526 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9531 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9540 while (get() != 0xFF)
9542 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9547 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9556 return sax->end_object();
9564 @return whether a valid MessagePack value was passed to the SAX parser
9566 bool parse_msgpack_internal()
9571 case std::char_traits<char_type>::eof():
9572 return unexpect_eof(input_format_t::msgpack, "value");
9703 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9722 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9741 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9777 case 0xDA: // str 16
9778 case 0xDB: // str 32
9781 return get_msgpack_string(s) && sax->string(s);
9788 return sax->boolean(false);
9791 return sax->boolean(true);
9794 case 0xC5: // bin 16
9795 case 0xC6: // bin 32
9797 case 0xC8: // ext 16
9798 case 0xC9: // ext 32
9799 case 0xD4: // fixext 1
9800 case 0xD5: // fixext 2
9801 case 0xD6: // fixext 4
9802 case 0xD7: // fixext 8
9803 case 0xD8: // fixext 16
9806 return get_msgpack_binary(b) && sax->binary(b);
9809 case 0xCA: // float 32
9812 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9815 case 0xCB: // float 64
9818 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9821 case 0xCC: // uint 8
9823 std::uint8_t number{};
9824 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9827 case 0xCD: // uint 16
9829 std::uint16_t number{};
9830 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9833 case 0xCE: // uint 32
9835 std::uint32_t number{};
9836 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9839 case 0xCF: // uint 64
9841 std::uint64_t number{};
9842 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9847 std::int8_t number{};
9848 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9851 case 0xD1: // int 16
9853 std::int16_t number{};
9854 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9857 case 0xD2: // int 32
9859 std::int32_t number{};
9860 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9863 case 0xD3: // int 64
9865 std::int64_t number{};
9866 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9869 case 0xDC: // array 16
9871 std::uint16_t len{};
9872 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9875 case 0xDD: // array 32
9877 std::uint32_t len{};
9878 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9881 case 0xDE: // map 16
9883 std::uint16_t len{};
9884 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9887 case 0xDF: // map 32
9889 std::uint32_t len{};
9890 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9926 return sax->number_integer(static_cast<std::int8_t>(current));
9928 default: // anything else
9930 auto last_token = get_token_string();
9931 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9937 @brief reads a MessagePack string
9939 This function first reads starting bytes to determine the expected
9940 string length and then copies this number of bytes into a string.
9942 @param[out] result created string
9944 @return whether string creation completed
9946 bool get_msgpack_string(string_t& result)
9948 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9989 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9995 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9998 case 0xDA: // str 16
10000 std::uint16_t len{};
10001 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10004 case 0xDB: // str 32
10006 std::uint32_t len{};
10007 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10012 auto last_token = get_token_string();
10013 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string"), BasicJsonType()));
10019 @brief reads a MessagePack byte array
10021 This function first reads starting bytes to determine the expected
10022 byte array length and then copies this number of bytes into a byte array.
10024 @param[out] result created byte array
10026 @return whether byte array creation completed
10028 bool get_msgpack_binary(binary_t& result)
10030 // helper function to set the subtype
10031 auto assign_and_return_true = [&result](std::int8_t subtype)
10033 result.set_subtype(static_cast<std::uint8_t>(subtype));
10039 case 0xC4: // bin 8
10041 std::uint8_t len{};
10042 return get_number(input_format_t::msgpack, len) &&
10043 get_binary(input_format_t::msgpack, len, result);
10046 case 0xC5: // bin 16
10048 std::uint16_t len{};
10049 return get_number(input_format_t::msgpack, len) &&
10050 get_binary(input_format_t::msgpack, len, result);
10053 case 0xC6: // bin 32
10055 std::uint32_t len{};
10056 return get_number(input_format_t::msgpack, len) &&
10057 get_binary(input_format_t::msgpack, len, result);
10060 case 0xC7: // ext 8
10062 std::uint8_t len{};
10063 std::int8_t subtype{};
10064 return get_number(input_format_t::msgpack, len) &&
10065 get_number(input_format_t::msgpack, subtype) &&
10066 get_binary(input_format_t::msgpack, len, result) &&
10067 assign_and_return_true(subtype);
10070 case 0xC8: // ext 16
10072 std::uint16_t len{};
10073 std::int8_t subtype{};
10074 return get_number(input_format_t::msgpack, len) &&
10075 get_number(input_format_t::msgpack, subtype) &&
10076 get_binary(input_format_t::msgpack, len, result) &&
10077 assign_and_return_true(subtype);
10080 case 0xC9: // ext 32
10082 std::uint32_t len{};
10083 std::int8_t subtype{};
10084 return get_number(input_format_t::msgpack, len) &&
10085 get_number(input_format_t::msgpack, subtype) &&
10086 get_binary(input_format_t::msgpack, len, result) &&
10087 assign_and_return_true(subtype);
10090 case 0xD4: // fixext 1
10092 std::int8_t subtype{};
10093 return get_number(input_format_t::msgpack, subtype) &&
10094 get_binary(input_format_t::msgpack, 1, result) &&
10095 assign_and_return_true(subtype);
10098 case 0xD5: // fixext 2
10100 std::int8_t subtype{};
10101 return get_number(input_format_t::msgpack, subtype) &&
10102 get_binary(input_format_t::msgpack, 2, result) &&
10103 assign_and_return_true(subtype);
10106 case 0xD6: // fixext 4
10108 std::int8_t subtype{};
10109 return get_number(input_format_t::msgpack, subtype) &&
10110 get_binary(input_format_t::msgpack, 4, result) &&
10111 assign_and_return_true(subtype);
10114 case 0xD7: // fixext 8
10116 std::int8_t subtype{};
10117 return get_number(input_format_t::msgpack, subtype) &&
10118 get_binary(input_format_t::msgpack, 8, result) &&
10119 assign_and_return_true(subtype);
10122 case 0xD8: // fixext 16
10124 std::int8_t subtype{};
10125 return get_number(input_format_t::msgpack, subtype) &&
10126 get_binary(input_format_t::msgpack, 16, result) &&
10127 assign_and_return_true(subtype);
10130 default: // LCOV_EXCL_LINE
10131 return false; // LCOV_EXCL_LINE
10136 @param[in] len the length of the array
10137 @return whether array creation completed
10139 bool get_msgpack_array(const std::size_t len)
10141 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10146 for (std::size_t i = 0; i < len; ++i)
10148 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10154 return sax->end_array();
10158 @param[in] len the length of the object
10159 @return whether object creation completed
10161 bool get_msgpack_object(const std::size_t len)
10163 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10169 for (std::size_t i = 0; i < len; ++i)
10172 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10177 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10184 return sax->end_object();
10192 @param[in] get_char whether a new character should be retrieved from the
10193 input (true, default) or whether the last read
10194 character should be considered instead
10196 @return whether a valid UBJSON value was passed to the SAX parser
10198 bool parse_ubjson_internal(const bool get_char = true)
10200 return get_ubjson_value(get_char ? get_ignore_noop() : current);
10204 @brief reads a UBJSON string
10206 This function is either called after reading the 'S' byte explicitly
10207 indicating a string, or in case of an object key where the 'S' byte can be
10210 @param[out] result created string
10211 @param[in] get_char whether a new character should be retrieved from the
10212 input (true, default) or whether the last read
10213 character should be considered instead
10215 @return whether string creation completed
10217 bool get_ubjson_string(string_t& result, const bool get_char = true)
10221 get(); // TODO(niels): may we ignore N here?
10224 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10233 std::uint8_t len{};
10234 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10240 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10245 std::int16_t len{};
10246 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10251 std::int32_t len{};
10252 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10257 std::int64_t len{};
10258 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10262 auto last_token = get_token_string();
10263 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"), BasicJsonType()));
10268 @param[out] result determined size
10269 @return whether size determination completed
10271 bool get_ubjson_size_value(std::size_t& result)
10273 switch (get_ignore_noop())
10277 std::uint8_t number{};
10278 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10282 result = static_cast<std::size_t>(number);
10288 std::int8_t number{};
10289 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10293 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10299 std::int16_t number{};
10300 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10304 result = static_cast<std::size_t>(number);
10310 std::int32_t number{};
10311 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10315 result = static_cast<std::size_t>(number);
10321 std::int64_t number{};
10322 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10326 result = static_cast<std::size_t>(number);
10332 auto last_token = get_token_string();
10333 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"), BasicJsonType()));
10339 @brief determine the type and size for a container
10341 In the optimized UBJSON format, a type and a size can be provided to allow
10342 for a more compact representation.
10344 @param[out] result pair of the size and the type
10346 @return whether pair creation completed
10348 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
10350 result.first = string_t::npos; // size
10351 result.second = 0; // type
10355 if (current == '$')
10357 result.second = get(); // must not ignore 'N', because 'N' maybe the type
10358 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
10364 if (JSON_HEDLEY_UNLIKELY(current != '#'))
10366 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10370 auto last_token = get_token_string();
10371 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size"), BasicJsonType()));
10374 return get_ubjson_size_value(result.first);
10377 if (current == '#')
10379 return get_ubjson_size_value(result.first);
10386 @param prefix the previously read or set type prefix
10387 @return whether value creation completed
10389 bool get_ubjson_value(const char_int_type prefix)
10393 case std::char_traits<char_type>::eof(): // EOF
10394 return unexpect_eof(input_format_t::ubjson, "value");
10397 return sax->boolean(true);
10399 return sax->boolean(false);
10402 return sax->null();
10406 std::uint8_t number{};
10407 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
10412 std::int8_t number{};
10413 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10418 std::int16_t number{};
10419 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10424 std::int32_t number{};
10425 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10430 std::int64_t number{};
10431 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10437 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10443 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10448 return get_ubjson_high_precision_number();
10454 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
10458 if (JSON_HEDLEY_UNLIKELY(current > 127))
10460 auto last_token = get_token_string();
10461 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char"), BasicJsonType()));
10463 string_t s(1, static_cast<typename string_t::value_type>(current));
10464 return sax->string(s);
10467 case 'S': // string
10470 return get_ubjson_string(s) && sax->string(s);
10474 return get_ubjson_array();
10476 case '{': // object
10477 return get_ubjson_object();
10479 default: // anything else
10481 auto last_token = get_token_string();
10482 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
10488 @return whether array creation completed
10490 bool get_ubjson_array()
10492 std::pair<std::size_t, char_int_type> size_and_type;
10493 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10498 if (size_and_type.first != string_t::npos)
10500 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
10505 if (size_and_type.second != 0)
10507 if (size_and_type.second != 'N')
10509 for (std::size_t i = 0; i < size_and_type.first; ++i)
10511 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10520 for (std::size_t i = 0; i < size_and_type.first; ++i)
10522 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10531 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10536 while (current != ']')
10538 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
10546 return sax->end_array();
10550 @return whether object creation completed
10552 bool get_ubjson_object()
10554 std::pair<std::size_t, char_int_type> size_and_type;
10555 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10561 if (size_and_type.first != string_t::npos)
10563 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
10568 if (size_and_type.second != 0)
10570 for (std::size_t i = 0; i < size_and_type.first; ++i)
10572 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10576 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10585 for (std::size_t i = 0; i < size_and_type.first; ++i)
10587 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10591 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10601 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10606 while (current != '}')
10608 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
10612 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10621 return sax->end_object();
10624 // Note, no reader for UBJSON binary types is implemented because they do
10627 bool get_ubjson_high_precision_number()
10629 // get size of following number string
10630 std::size_t size{};
10631 auto res = get_ubjson_size_value(size);
10632 if (JSON_HEDLEY_UNLIKELY(!res))
10637 // get number string
10638 std::vector<char> number_vector;
10639 for (std::size_t i = 0; i < size; ++i)
10642 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
10646 number_vector.push_back(static_cast<char>(current));
10649 // parse number string
10650 using ia_type = decltype(detail::input_adapter(number_vector));
10651 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
10652 const auto result_number = number_lexer.scan();
10653 const auto number_string = number_lexer.get_token_string();
10654 const auto result_remainder = number_lexer.scan();
10656 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
10658 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
10660 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
10663 switch (result_number)
10665 case token_type::value_integer:
10666 return sax->number_integer(number_lexer.get_number_integer());
10667 case token_type::value_unsigned:
10668 return sax->number_unsigned(number_lexer.get_number_unsigned());
10669 case token_type::value_float:
10670 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
10671 case token_type::uninitialized:
10672 case token_type::literal_true:
10673 case token_type::literal_false:
10674 case token_type::literal_null:
10675 case token_type::value_string:
10676 case token_type::begin_array:
10677 case token_type::begin_object:
10678 case token_type::end_array:
10679 case token_type::end_object:
10680 case token_type::name_separator:
10681 case token_type::value_separator:
10682 case token_type::parse_error:
10683 case token_type::end_of_input:
10684 case token_type::literal_or_value:
10686 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
10690 ///////////////////////
10691 // Utility functions //
10692 ///////////////////////
10695 @brief get next character from the input
10697 This function provides the interface to the used input adapter. It does
10698 not throw in case the input reached EOF, but returns a -'ve valued
10699 `std::char_traits<char_type>::eof()` in that case.
10701 @return character read from the input
10703 char_int_type get()
10706 return current = ia.get_character();
10710 @return character read from the input after ignoring all 'N' entries
10712 char_int_type get_ignore_noop()
10718 while (current == 'N');
10724 @brief read a number from the input
10726 @tparam NumberType the type of the number
10727 @param[in] format the current format (for diagnostics)
10728 @param[out] result number of type @a NumberType
10730 @return whether conversion completed
10732 @note This function needs to respect the system's endianness, because
10733 bytes in CBOR, MessagePack, and UBJSON are stored in network order
10734 (big endian) and therefore need reordering on little endian systems.
10736 template<typename NumberType, bool InputIsLittleEndian = false>
10737 bool get_number(const input_format_t format, NumberType& result)
10739 // step 1: read input into array with system's byte order
10740 std::array<std::uint8_t, sizeof(NumberType)> vec{};
10741 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
10744 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10749 // reverse byte order prior to conversion if necessary
10750 if (is_little_endian != InputIsLittleEndian)
10752 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10756 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10760 // step 2: convert array into number of type T and return
10761 std::memcpy(&result, vec.data(), sizeof(NumberType));
10766 @brief create a string by reading characters from the input
10768 @tparam NumberType the type of the number
10769 @param[in] format the current format (for diagnostics)
10770 @param[in] len number of characters to read
10771 @param[out] result string created by reading @a len bytes
10773 @return whether string creation completed
10775 @note We can not reserve @a len bytes for the result, because @a len
10776 may be too large. Usually, @ref unexpect_eof() detects the end of
10777 the input before we run out of string memory.
10779 template<typename NumberType>
10780 bool get_string(const input_format_t format,
10781 const NumberType len,
10784 bool success = true;
10785 for (NumberType i = 0; i < len; i++)
10788 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10793 result.push_back(static_cast<typename string_t::value_type>(current));
10799 @brief create a byte array by reading bytes from the input
10801 @tparam NumberType the type of the number
10802 @param[in] format the current format (for diagnostics)
10803 @param[in] len number of bytes to read
10804 @param[out] result byte array created by reading @a len bytes
10806 @return whether byte array creation completed
10808 @note We can not reserve @a len bytes for the result, because @a len
10809 may be too large. Usually, @ref unexpect_eof() detects the end of
10810 the input before we run out of memory.
10812 template<typename NumberType>
10813 bool get_binary(const input_format_t format,
10814 const NumberType len,
10817 bool success = true;
10818 for (NumberType i = 0; i < len; i++)
10821 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10826 result.push_back(static_cast<std::uint8_t>(current));
10832 @param[in] format the current format (for diagnostics)
10833 @param[in] context further context information (for diagnostics)
10834 @return whether the last read character is not EOF
10836 JSON_HEDLEY_NON_NULL(3)
10837 bool unexpect_eof(const input_format_t format, const char* context) const
10839 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10841 return sax->parse_error(chars_read, "<end of file>",
10842 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
10848 @return a string representation of the last read byte
10850 std::string get_token_string() const
10852 std::array<char, 3> cr{{}};
10853 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10854 return std::string{cr.data()};
10858 @param[in] format the current format
10859 @param[in] detail a detailed error message
10860 @param[in] context further context information
10861 @return a message string to use in the parse_error exceptions
10863 std::string exception_message(const input_format_t format,
10864 const std::string& detail,
10865 const std::string& context) const
10867 std::string error_msg = "syntax error while parsing ";
10871 case input_format_t::cbor:
10872 error_msg += "CBOR";
10875 case input_format_t::msgpack:
10876 error_msg += "MessagePack";
10879 case input_format_t::ubjson:
10880 error_msg += "UBJSON";
10883 case input_format_t::bson:
10884 error_msg += "BSON";
10887 case input_format_t::json: // LCOV_EXCL_LINE
10888 default: // LCOV_EXCL_LINE
10889 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10892 return error_msg + " " + context + ": " + detail;
10897 InputAdapterType ia;
10899 /// the current character
10900 char_int_type current = std::char_traits<char_type>::eof();
10902 /// the number of characters read
10903 std::size_t chars_read = 0;
10905 /// whether we can assume little endianness
10906 const bool is_little_endian = little_endianness();
10909 json_sax_t* sax = nullptr;
10911 } // namespace detail
10912 } // namespace nlohmann
10914 // #include <nlohmann/detail/input/input_adapters.hpp>
10916 // #include <nlohmann/detail/input/lexer.hpp>
10918 // #include <nlohmann/detail/input/parser.hpp>
10921 #include <cmath> // isfinite
10922 #include <cstdint> // uint8_t
10923 #include <functional> // function
10924 #include <string> // string
10925 #include <utility> // move
10926 #include <vector> // vector
10928 // #include <nlohmann/detail/exceptions.hpp>
10930 // #include <nlohmann/detail/input/input_adapters.hpp>
10932 // #include <nlohmann/detail/input/json_sax.hpp>
10934 // #include <nlohmann/detail/input/lexer.hpp>
10936 // #include <nlohmann/detail/macro_scope.hpp>
10938 // #include <nlohmann/detail/meta/is_sax.hpp>
10940 // #include <nlohmann/detail/value_t.hpp>
10951 enum class parse_event_t : std::uint8_t
10953 /// the parser read `{` and started to process a JSON object
10955 /// the parser read `}` and finished processing a JSON object
10957 /// the parser read `[` and started to process a JSON array
10959 /// the parser read `]` and finished processing a JSON array
10961 /// the parser read a key of a value in an object
10963 /// the parser finished reading a JSON value
10967 template<typename BasicJsonType>
10968 using parser_callback_t =
10969 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
10972 @brief syntax analysis
10974 This class implements a recursive descent parser.
10976 template<typename BasicJsonType, typename InputAdapterType>
10979 using number_integer_t = typename BasicJsonType::number_integer_t;
10980 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10981 using number_float_t = typename BasicJsonType::number_float_t;
10982 using string_t = typename BasicJsonType::string_t;
10983 using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10984 using token_type = typename lexer_t::token_type;
10987 /// a parser reading from an input adapter
10988 explicit parser(InputAdapterType&& adapter,
10989 const parser_callback_t<BasicJsonType> cb = nullptr,
10990 const bool allow_exceptions_ = true,
10991 const bool skip_comments = false)
10993 , m_lexer(std::move(adapter), skip_comments)
10994 , allow_exceptions(allow_exceptions_)
10996 // read first token
11001 @brief public parser interface
11003 @param[in] strict whether to expect the last token to be EOF
11004 @param[in,out] result parsed JSON value
11006 @throw parse_error.101 in case of an unexpected token
11007 @throw parse_error.102 if to_unicode fails or surrogate error
11008 @throw parse_error.103 if to_unicode fails
11010 void parse(const bool strict, BasicJsonType& result)
11014 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
11015 sax_parse_internal(&sdp);
11017 // in strict mode, input must be completely read
11018 if (strict && (get_token() != token_type::end_of_input))
11020 sdp.parse_error(m_lexer.get_position(),
11021 m_lexer.get_token_string(),
11022 parse_error::create(101, m_lexer.get_position(),
11023 exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11026 // in case of an error, return discarded value
11027 if (sdp.is_errored())
11029 result = value_t::discarded;
11033 // set top-level value to null if it was discarded by the callback
11035 if (result.is_discarded())
11042 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
11043 sax_parse_internal(&sdp);
11045 // in strict mode, input must be completely read
11046 if (strict && (get_token() != token_type::end_of_input))
11048 sdp.parse_error(m_lexer.get_position(),
11049 m_lexer.get_token_string(),
11050 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11053 // in case of an error, return discarded value
11054 if (sdp.is_errored())
11056 result = value_t::discarded;
11061 result.assert_invariant();
11065 @brief public accept interface
11067 @param[in] strict whether to expect the last token to be EOF
11068 @return whether the input is a proper JSON text
11070 bool accept(const bool strict = true)
11072 json_sax_acceptor<BasicJsonType> sax_acceptor;
11073 return sax_parse(&sax_acceptor, strict);
11076 template<typename SAX>
11077 JSON_HEDLEY_NON_NULL(2)
11078 bool sax_parse(SAX* sax, const bool strict = true)
11080 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
11081 const bool result = sax_parse_internal(sax);
11083 // strict mode: next byte must be EOF
11084 if (result && strict && (get_token() != token_type::end_of_input))
11086 return sax->parse_error(m_lexer.get_position(),
11087 m_lexer.get_token_string(),
11088 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11095 template<typename SAX>
11096 JSON_HEDLEY_NON_NULL(2)
11097 bool sax_parse_internal(SAX* sax)
11099 // stack to remember the hierarchy of structured values we are parsing
11100 // true = array; false = object
11101 std::vector<bool> states;
11102 // value to avoid a goto (see comment where set to true)
11103 bool skip_to_state_evaluation = false;
11107 if (!skip_to_state_evaluation)
11109 // invariant: get_token() was called before each iteration
11110 switch (last_token)
11112 case token_type::begin_object:
11114 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
11119 // closing } -> we are done
11120 if (get_token() == token_type::end_object)
11122 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11130 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11132 return sax->parse_error(m_lexer.get_position(),
11133 m_lexer.get_token_string(),
11134 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11136 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11141 // parse separator (:)
11142 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11144 return sax->parse_error(m_lexer.get_position(),
11145 m_lexer.get_token_string(),
11146 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11149 // remember we are now inside an object
11150 states.push_back(false);
11157 case token_type::begin_array:
11159 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
11164 // closing ] -> we are done
11165 if (get_token() == token_type::end_array)
11167 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11174 // remember we are now inside an array
11175 states.push_back(true);
11177 // parse values (no need to call get_token)
11181 case token_type::value_float:
11183 const auto res = m_lexer.get_number_float();
11185 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11187 return sax->parse_error(m_lexer.get_position(),
11188 m_lexer.get_token_string(),
11189 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
11192 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11200 case token_type::literal_false:
11202 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11209 case token_type::literal_null:
11211 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11218 case token_type::literal_true:
11220 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11227 case token_type::value_integer:
11229 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11236 case token_type::value_string:
11238 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11245 case token_type::value_unsigned:
11247 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11254 case token_type::parse_error:
11256 // using "uninitialized" to avoid "expected" message
11257 return sax->parse_error(m_lexer.get_position(),
11258 m_lexer.get_token_string(),
11259 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
11262 case token_type::uninitialized:
11263 case token_type::end_array:
11264 case token_type::end_object:
11265 case token_type::name_separator:
11266 case token_type::value_separator:
11267 case token_type::end_of_input:
11268 case token_type::literal_or_value:
11269 default: // the last token was unexpected
11271 return sax->parse_error(m_lexer.get_position(),
11272 m_lexer.get_token_string(),
11273 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
11279 skip_to_state_evaluation = false;
11282 // we reached this line after we successfully parsed a value
11283 if (states.empty())
11285 // empty stack: we reached the end of the hierarchy: done
11289 if (states.back()) // array
11291 // comma -> next value
11292 if (get_token() == token_type::value_separator)
11294 // parse a new value
11300 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11302 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11307 // We are done with this array. Before we can parse a
11308 // new value, we need to evaluate the new state first.
11309 // By setting skip_to_state_evaluation to false, we
11310 // are effectively jumping to the beginning of this if.
11311 JSON_ASSERT(!states.empty());
11313 skip_to_state_evaluation = true;
11317 return sax->parse_error(m_lexer.get_position(),
11318 m_lexer.get_token_string(),
11319 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11322 // states.back() is false -> object
11324 // comma -> next value
11325 if (get_token() == token_type::value_separator)
11328 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11330 return sax->parse_error(m_lexer.get_position(),
11331 m_lexer.get_token_string(),
11332 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11335 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11340 // parse separator (:)
11341 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11343 return sax->parse_error(m_lexer.get_position(),
11344 m_lexer.get_token_string(),
11345 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11354 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11356 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11361 // We are done with this object. Before we can parse a
11362 // new value, we need to evaluate the new state first.
11363 // By setting skip_to_state_evaluation to false, we
11364 // are effectively jumping to the beginning of this if.
11365 JSON_ASSERT(!states.empty());
11367 skip_to_state_evaluation = true;
11371 return sax->parse_error(m_lexer.get_position(),
11372 m_lexer.get_token_string(),
11373 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11377 /// get next token from lexer
11378 token_type get_token()
11380 return last_token = m_lexer.scan();
11383 std::string exception_message(const token_type expected, const std::string& context)
11385 std::string error_msg = "syntax error ";
11387 if (!context.empty())
11389 error_msg += "while parsing " + context + " ";
11394 if (last_token == token_type::parse_error)
11396 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
11397 m_lexer.get_token_string() + "'";
11401 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
11404 if (expected != token_type::uninitialized)
11406 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
11413 /// callback function
11414 const parser_callback_t<BasicJsonType> callback = nullptr;
11415 /// the type of the last read token
11416 token_type last_token = token_type::uninitialized;
11419 /// whether to throw exceptions in case of errors
11420 const bool allow_exceptions = true;
11423 } // namespace detail
11424 } // namespace nlohmann
11426 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
11429 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11432 #include <cstddef> // ptrdiff_t
11433 #include <limits> // numeric_limits
11435 // #include <nlohmann/detail/macro_scope.hpp>
11443 @brief an iterator for primitive JSON types
11445 This class models an iterator for primitive JSON types (boolean, number,
11446 string). It's only purpose is to allow the iterator/const_iterator classes
11447 to "iterate" over primitive values. Internally, the iterator is modeled by
11448 a `difference_type` variable. Value begin_value (`0`) models the begin,
11449 end_value (`1`) models past the end.
11451 class primitive_iterator_t
11454 using difference_type = std::ptrdiff_t;
11455 static constexpr difference_type begin_value = 0;
11456 static constexpr difference_type end_value = begin_value + 1;
11458 JSON_PRIVATE_UNLESS_TESTED:
11459 /// iterator as signed integer type
11460 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11463 constexpr difference_type get_value() const noexcept
11468 /// set iterator to a defined beginning
11469 void set_begin() noexcept
11471 m_it = begin_value;
11474 /// set iterator to a defined past the end
11475 void set_end() noexcept
11480 /// return whether the iterator can be dereferenced
11481 constexpr bool is_begin() const noexcept
11483 return m_it == begin_value;
11486 /// return whether the iterator is at end
11487 constexpr bool is_end() const noexcept
11489 return m_it == end_value;
11492 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11494 return lhs.m_it == rhs.m_it;
11497 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11499 return lhs.m_it < rhs.m_it;
11502 primitive_iterator_t operator+(difference_type n) noexcept
11504 auto result = *this;
11509 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11511 return lhs.m_it - rhs.m_it;
11514 primitive_iterator_t& operator++() noexcept
11520 primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
11522 auto result = *this;
11527 primitive_iterator_t& operator--() noexcept
11533 primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
11535 auto result = *this;
11540 primitive_iterator_t& operator+=(difference_type n) noexcept
11546 primitive_iterator_t& operator-=(difference_type n) noexcept
11552 } // namespace detail
11553 } // namespace nlohmann
11561 @brief an iterator value
11563 @note This structure could easily be a union, but MSVC currently does not allow
11564 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
11566 template<typename BasicJsonType> struct internal_iterator
11568 /// iterator for JSON objects
11569 typename BasicJsonType::object_t::iterator object_iterator {};
11570 /// iterator for JSON arrays
11571 typename BasicJsonType::array_t::iterator array_iterator {};
11572 /// generic iterator for all other types
11573 primitive_iterator_t primitive_iterator {};
11575 } // namespace detail
11576 } // namespace nlohmann
11578 // #include <nlohmann/detail/iterators/iter_impl.hpp>
11581 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
11582 #include <type_traits> // conditional, is_const, remove_const
11584 // #include <nlohmann/detail/exceptions.hpp>
11586 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
11588 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11590 // #include <nlohmann/detail/macro_scope.hpp>
11592 // #include <nlohmann/detail/meta/cpp_future.hpp>
11594 // #include <nlohmann/detail/meta/type_traits.hpp>
11596 // #include <nlohmann/detail/value_t.hpp>
11603 // forward declare, to be able to friend it later on
11604 template<typename IteratorType> class iteration_proxy;
11605 template<typename IteratorType> class iteration_proxy_value;
11608 @brief a template for a bidirectional iterator for the @ref basic_json class
11609 This class implements a both iterators (iterator and const_iterator) for the
11610 @ref basic_json class.
11611 @note An iterator is called *initialized* when a pointer to a JSON value has
11612 been set (e.g., by a constructor or a copy assignment). If the iterator is
11613 default-constructed, it is *uninitialized* and most methods are undefined.
11614 **The library uses assertions to detect calls on uninitialized iterators.**
11615 @requirement The class satisfies the following concept requirements:
11617 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
11618 The iterator that can be moved can be moved in both directions (i.e.
11619 incremented and decremented).
11620 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
11621 iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
11623 template<typename BasicJsonType>
11624 class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
11626 /// the iterator with BasicJsonType of different const-ness
11627 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
11628 /// allow basic_json to access private members
11629 friend other_iter_impl;
11630 friend BasicJsonType;
11631 friend iteration_proxy<iter_impl>;
11632 friend iteration_proxy_value<iter_impl>;
11634 using object_t = typename BasicJsonType::object_t;
11635 using array_t = typename BasicJsonType::array_t;
11636 // make sure BasicJsonType is basic_json or const basic_json
11637 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
11638 "iter_impl only accepts (const) basic_json");
11642 /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
11643 /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
11644 /// A user-defined iterator should provide publicly accessible typedefs named
11645 /// iterator_category, value_type, difference_type, pointer, and reference.
11646 /// Note that value_type is required to be non-const, even for constant iterators.
11647 using iterator_category = std::bidirectional_iterator_tag;
11649 /// the type of the values when the iterator is dereferenced
11650 using value_type = typename BasicJsonType::value_type;
11651 /// a type to represent differences between iterators
11652 using difference_type = typename BasicJsonType::difference_type;
11653 /// defines a pointer to the type iterated over (value_type)
11654 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
11655 typename BasicJsonType::const_pointer,
11656 typename BasicJsonType::pointer>::type;
11657 /// defines a reference to the type iterated over (value_type)
11659 typename std::conditional<std::is_const<BasicJsonType>::value,
11660 typename BasicJsonType::const_reference,
11661 typename BasicJsonType::reference>::type;
11663 iter_impl() = default;
11664 ~iter_impl() = default;
11665 iter_impl(iter_impl&&) noexcept = default;
11666 iter_impl& operator=(iter_impl&&) noexcept = default;
11669 @brief constructor for a given JSON instance
11670 @param[in] object pointer to a JSON object for this iterator
11671 @pre object != nullptr
11672 @post The iterator is initialized; i.e. `m_object != nullptr`.
11674 explicit iter_impl(pointer object) noexcept : m_object(object)
11676 JSON_ASSERT(m_object != nullptr);
11678 switch (m_object->m_type)
11680 case value_t::object:
11682 m_it.object_iterator = typename object_t::iterator();
11686 case value_t::array:
11688 m_it.array_iterator = typename array_t::iterator();
11692 case value_t::null:
11693 case value_t::string:
11694 case value_t::boolean:
11695 case value_t::number_integer:
11696 case value_t::number_unsigned:
11697 case value_t::number_float:
11698 case value_t::binary:
11699 case value_t::discarded:
11702 m_it.primitive_iterator = primitive_iterator_t();
11709 @note The conventional copy constructor and copy assignment are implicitly
11710 defined. Combined with the following converting constructor and
11711 assignment, they support: (1) copy from iterator to iterator, (2)
11712 copy from const iterator to const iterator, and (3) conversion from
11713 iterator to const iterator. However conversion from const iterator
11714 to iterator is not defined.
11718 @brief const copy constructor
11719 @param[in] other const iterator to copy from
11720 @note This copy constructor had to be defined explicitly to circumvent a bug
11721 occurring on msvc v19.0 compiler (VS 2015) debug build. For more
11722 information refer to: https://github.com/nlohmann/json/issues/1608
11724 iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
11725 : m_object(other.m_object), m_it(other.m_it)
11729 @brief converting assignment
11730 @param[in] other const iterator to copy from
11731 @return const/non-const iterator
11732 @note It is not checked whether @a other is initialized.
11734 iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
11736 if (&other != this)
11738 m_object = other.m_object;
11745 @brief converting constructor
11746 @param[in] other non-const iterator to copy from
11747 @note It is not checked whether @a other is initialized.
11749 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
11750 : m_object(other.m_object), m_it(other.m_it)
11754 @brief converting assignment
11755 @param[in] other non-const iterator to copy from
11756 @return const/non-const iterator
11757 @note It is not checked whether @a other is initialized.
11759 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
11761 m_object = other.m_object;
11766 JSON_PRIVATE_UNLESS_TESTED:
11768 @brief set the iterator to the first value
11769 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11771 void set_begin() noexcept
11773 JSON_ASSERT(m_object != nullptr);
11775 switch (m_object->m_type)
11777 case value_t::object:
11779 m_it.object_iterator = m_object->m_value.object->begin();
11783 case value_t::array:
11785 m_it.array_iterator = m_object->m_value.array->begin();
11789 case value_t::null:
11791 // set to end so begin()==end() is true: null is empty
11792 m_it.primitive_iterator.set_end();
11796 case value_t::string:
11797 case value_t::boolean:
11798 case value_t::number_integer:
11799 case value_t::number_unsigned:
11800 case value_t::number_float:
11801 case value_t::binary:
11802 case value_t::discarded:
11805 m_it.primitive_iterator.set_begin();
11812 @brief set the iterator past the last value
11813 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11815 void set_end() noexcept
11817 JSON_ASSERT(m_object != nullptr);
11819 switch (m_object->m_type)
11821 case value_t::object:
11823 m_it.object_iterator = m_object->m_value.object->end();
11827 case value_t::array:
11829 m_it.array_iterator = m_object->m_value.array->end();
11833 case value_t::null:
11834 case value_t::string:
11835 case value_t::boolean:
11836 case value_t::number_integer:
11837 case value_t::number_unsigned:
11838 case value_t::number_float:
11839 case value_t::binary:
11840 case value_t::discarded:
11843 m_it.primitive_iterator.set_end();
11851 @brief return a reference to the value pointed to by the iterator
11852 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11854 reference operator*() const
11856 JSON_ASSERT(m_object != nullptr);
11858 switch (m_object->m_type)
11860 case value_t::object:
11862 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11863 return m_it.object_iterator->second;
11866 case value_t::array:
11868 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11869 return *m_it.array_iterator;
11872 case value_t::null:
11873 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11875 case value_t::string:
11876 case value_t::boolean:
11877 case value_t::number_integer:
11878 case value_t::number_unsigned:
11879 case value_t::number_float:
11880 case value_t::binary:
11881 case value_t::discarded:
11884 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11889 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11895 @brief dereference the iterator
11896 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11898 pointer operator->() const
11900 JSON_ASSERT(m_object != nullptr);
11902 switch (m_object->m_type)
11904 case value_t::object:
11906 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11907 return &(m_it.object_iterator->second);
11910 case value_t::array:
11912 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11913 return &*m_it.array_iterator;
11916 case value_t::null:
11917 case value_t::string:
11918 case value_t::boolean:
11919 case value_t::number_integer:
11920 case value_t::number_unsigned:
11921 case value_t::number_float:
11922 case value_t::binary:
11923 case value_t::discarded:
11926 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11931 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11937 @brief post-increment (it++)
11938 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11940 iter_impl const operator++(int) // NOLINT(readability-const-return-type)
11942 auto result = *this;
11948 @brief pre-increment (++it)
11949 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11951 iter_impl& operator++()
11953 JSON_ASSERT(m_object != nullptr);
11955 switch (m_object->m_type)
11957 case value_t::object:
11959 std::advance(m_it.object_iterator, 1);
11963 case value_t::array:
11965 std::advance(m_it.array_iterator, 1);
11969 case value_t::null:
11970 case value_t::string:
11971 case value_t::boolean:
11972 case value_t::number_integer:
11973 case value_t::number_unsigned:
11974 case value_t::number_float:
11975 case value_t::binary:
11976 case value_t::discarded:
11979 ++m_it.primitive_iterator;
11988 @brief post-decrement (it--)
11989 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11991 iter_impl const operator--(int) // NOLINT(readability-const-return-type)
11993 auto result = *this;
11999 @brief pre-decrement (--it)
12000 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12002 iter_impl& operator--()
12004 JSON_ASSERT(m_object != nullptr);
12006 switch (m_object->m_type)
12008 case value_t::object:
12010 std::advance(m_it.object_iterator, -1);
12014 case value_t::array:
12016 std::advance(m_it.array_iterator, -1);
12020 case value_t::null:
12021 case value_t::string:
12022 case value_t::boolean:
12023 case value_t::number_integer:
12024 case value_t::number_unsigned:
12025 case value_t::number_float:
12026 case value_t::binary:
12027 case value_t::discarded:
12030 --m_it.primitive_iterator;
12039 @brief comparison: equal
12040 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12042 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
12043 bool operator==(const IterImpl& other) const
12045 // if objects are not the same, the comparison is undefined
12046 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12048 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12051 JSON_ASSERT(m_object != nullptr);
12053 switch (m_object->m_type)
12055 case value_t::object:
12056 return (m_it.object_iterator == other.m_it.object_iterator);
12058 case value_t::array:
12059 return (m_it.array_iterator == other.m_it.array_iterator);
12061 case value_t::null:
12062 case value_t::string:
12063 case value_t::boolean:
12064 case value_t::number_integer:
12065 case value_t::number_unsigned:
12066 case value_t::number_float:
12067 case value_t::binary:
12068 case value_t::discarded:
12070 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
12075 @brief comparison: not equal
12076 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12078 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
12079 bool operator!=(const IterImpl& other) const
12081 return !operator==(other);
12085 @brief comparison: smaller
12086 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12088 bool operator<(const iter_impl& other) const
12090 // if objects are not the same, the comparison is undefined
12091 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12093 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12096 JSON_ASSERT(m_object != nullptr);
12098 switch (m_object->m_type)
12100 case value_t::object:
12101 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
12103 case value_t::array:
12104 return (m_it.array_iterator < other.m_it.array_iterator);
12106 case value_t::null:
12107 case value_t::string:
12108 case value_t::boolean:
12109 case value_t::number_integer:
12110 case value_t::number_unsigned:
12111 case value_t::number_float:
12112 case value_t::binary:
12113 case value_t::discarded:
12115 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
12120 @brief comparison: less than or equal
12121 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12123 bool operator<=(const iter_impl& other) const
12125 return !other.operator < (*this);
12129 @brief comparison: greater than
12130 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12132 bool operator>(const iter_impl& other) const
12134 return !operator<=(other);
12138 @brief comparison: greater than or equal
12139 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12141 bool operator>=(const iter_impl& other) const
12143 return !operator<(other);
12147 @brief add to iterator
12148 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12150 iter_impl& operator+=(difference_type i)
12152 JSON_ASSERT(m_object != nullptr);
12154 switch (m_object->m_type)
12156 case value_t::object:
12157 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12159 case value_t::array:
12161 std::advance(m_it.array_iterator, i);
12165 case value_t::null:
12166 case value_t::string:
12167 case value_t::boolean:
12168 case value_t::number_integer:
12169 case value_t::number_unsigned:
12170 case value_t::number_float:
12171 case value_t::binary:
12172 case value_t::discarded:
12175 m_it.primitive_iterator += i;
12184 @brief subtract from iterator
12185 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12187 iter_impl& operator-=(difference_type i)
12189 return operator+=(-i);
12193 @brief add to iterator
12194 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12196 iter_impl operator+(difference_type i) const
12198 auto result = *this;
12204 @brief addition of distance and iterator
12205 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12207 friend iter_impl operator+(difference_type i, const iter_impl& it)
12215 @brief subtract from iterator
12216 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12218 iter_impl operator-(difference_type i) const
12220 auto result = *this;
12226 @brief return difference
12227 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12229 difference_type operator-(const iter_impl& other) const
12231 JSON_ASSERT(m_object != nullptr);
12233 switch (m_object->m_type)
12235 case value_t::object:
12236 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12238 case value_t::array:
12239 return m_it.array_iterator - other.m_it.array_iterator;
12241 case value_t::null:
12242 case value_t::string:
12243 case value_t::boolean:
12244 case value_t::number_integer:
12245 case value_t::number_unsigned:
12246 case value_t::number_float:
12247 case value_t::binary:
12248 case value_t::discarded:
12250 return m_it.primitive_iterator - other.m_it.primitive_iterator;
12255 @brief access to successor
12256 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12258 reference operator[](difference_type n) const
12260 JSON_ASSERT(m_object != nullptr);
12262 switch (m_object->m_type)
12264 case value_t::object:
12265 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
12267 case value_t::array:
12268 return *std::next(m_it.array_iterator, n);
12270 case value_t::null:
12271 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12273 case value_t::string:
12274 case value_t::boolean:
12275 case value_t::number_integer:
12276 case value_t::number_unsigned:
12277 case value_t::number_float:
12278 case value_t::binary:
12279 case value_t::discarded:
12282 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
12287 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12293 @brief return the key of an object iterator
12294 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12296 const typename object_t::key_type& key() const
12298 JSON_ASSERT(m_object != nullptr);
12300 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
12302 return m_it.object_iterator->first;
12305 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
12309 @brief return the value of an iterator
12310 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12312 reference value() const
12314 return operator*();
12317 JSON_PRIVATE_UNLESS_TESTED:
12318 /// associated JSON instance
12319 pointer m_object = nullptr;
12320 /// the actual iterator of the associated instance
12321 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
12323 } // namespace detail
12324 } // namespace nlohmann
12326 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12328 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12331 #include <cstddef> // ptrdiff_t
12332 #include <iterator> // reverse_iterator
12333 #include <utility> // declval
12339 //////////////////////
12340 // reverse_iterator //
12341 //////////////////////
12344 @brief a template for a reverse iterator class
12346 @tparam Base the base iterator type to reverse. Valid types are @ref
12347 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
12348 create @ref const_reverse_iterator).
12350 @requirement The class satisfies the following concept requirements:
12352 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
12353 The iterator that can be moved can be moved in both directions (i.e.
12354 incremented and decremented).
12355 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
12356 It is possible to write to the pointed-to element (only if @a Base is
12359 @since version 1.0.0
12361 template<typename Base>
12362 class json_reverse_iterator : public std::reverse_iterator<Base>
12365 using difference_type = std::ptrdiff_t;
12366 /// shortcut to the reverse iterator adapter
12367 using base_iterator = std::reverse_iterator<Base>;
12368 /// the reference type for the pointed-to element
12369 using reference = typename Base::reference;
12371 /// create reverse iterator from iterator
12372 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
12373 : base_iterator(it) {}
12375 /// create reverse iterator from base class
12376 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12378 /// post-increment (it++)
12379 json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
12381 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12384 /// pre-increment (++it)
12385 json_reverse_iterator& operator++()
12387 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12390 /// post-decrement (it--)
12391 json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
12393 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12396 /// pre-decrement (--it)
12397 json_reverse_iterator& operator--()
12399 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12402 /// add to iterator
12403 json_reverse_iterator& operator+=(difference_type i)
12405 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12408 /// add to iterator
12409 json_reverse_iterator operator+(difference_type i) const
12411 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12414 /// subtract from iterator
12415 json_reverse_iterator operator-(difference_type i) const
12417 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12420 /// return difference
12421 difference_type operator-(const json_reverse_iterator& other) const
12423 return base_iterator(*this) - base_iterator(other);
12426 /// access to successor
12427 reference operator[](difference_type n) const
12429 return *(this->operator+(n));
12432 /// return the key of an object iterator
12433 auto key() const -> decltype(std::declval<Base>().key())
12435 auto it = --this->base();
12439 /// return the value of an iterator
12440 reference value() const
12442 auto it = --this->base();
12443 return it.operator * ();
12446 } // namespace detail
12447 } // namespace nlohmann
12449 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12451 // #include <nlohmann/detail/json_pointer.hpp>
12454 #include <algorithm> // all_of
12455 #include <cctype> // isdigit
12456 #include <limits> // max
12457 #include <numeric> // accumulate
12458 #include <string> // string
12459 #include <utility> // move
12460 #include <vector> // vector
12462 // #include <nlohmann/detail/exceptions.hpp>
12464 // #include <nlohmann/detail/macro_scope.hpp>
12466 // #include <nlohmann/detail/string_escape.hpp>
12468 // #include <nlohmann/detail/value_t.hpp>
12473 template<typename BasicJsonType>
12476 // allow basic_json to access private members
12477 NLOHMANN_BASIC_JSON_TPL_DECLARATION
12478 friend class basic_json;
12482 @brief create JSON pointer
12484 Create a JSON pointer according to the syntax described in
12485 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
12487 @param[in] s string representing the JSON pointer; if omitted, the empty
12488 string is assumed which references the whole JSON value
12490 @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
12491 not begin with a slash (`/`); see example below
12493 @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
12494 not followed by `0` (representing `~`) or `1` (representing `/`); see
12497 @liveexample{The example shows the construction several valid JSON pointers
12498 as well as the exceptional behavior.,json_pointer}
12500 @since version 2.0.0
12502 explicit json_pointer(const std::string& s = "")
12503 : reference_tokens(split(s))
12507 @brief return a string representation of the JSON pointer
12509 @invariant For each JSON pointer `ptr`, it holds:
12511 ptr == json_pointer(ptr.to_string());
12514 @return a string representation of the JSON pointer
12516 @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
12518 @since version 2.0.0
12520 std::string to_string() const
12522 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12524 [](const std::string & a, const std::string & b)
12526 return a + "/" + detail::escape(b);
12530 /// @copydoc to_string()
12531 operator std::string() const
12533 return to_string();
12537 @brief append another JSON pointer at the end of this JSON pointer
12539 @param[in] ptr JSON pointer to append
12540 @return JSON pointer with @a ptr appended
12542 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12544 @complexity Linear in the length of @a ptr.
12546 @sa see @ref operator/=(std::string) to append a reference token
12547 @sa see @ref operator/=(std::size_t) to append an array index
12548 @sa see @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
12550 @since version 3.6.0
12552 json_pointer& operator/=(const json_pointer& ptr)
12554 reference_tokens.insert(reference_tokens.end(),
12555 ptr.reference_tokens.begin(),
12556 ptr.reference_tokens.end());
12561 @brief append an unescaped reference token at the end of this JSON pointer
12563 @param[in] token reference token to append
12564 @return JSON pointer with @a token appended without escaping @a token
12566 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12568 @complexity Amortized constant.
12570 @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12571 @sa see @ref operator/=(std::size_t) to append an array index
12572 @sa see @ref operator/(const json_pointer&, std::size_t) for a binary operator
12574 @since version 3.6.0
12576 json_pointer& operator/=(std::string token)
12578 push_back(std::move(token));
12583 @brief append an array index at the end of this JSON pointer
12585 @param[in] array_idx array index to append
12586 @return JSON pointer with @a array_idx appended
12588 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12590 @complexity Amortized constant.
12592 @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12593 @sa see @ref operator/=(std::string) to append a reference token
12594 @sa see @ref operator/(const json_pointer&, std::string) for a binary operator
12596 @since version 3.6.0
12598 json_pointer& operator/=(std::size_t array_idx)
12600 return *this /= std::to_string(array_idx);
12604 @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
12606 @param[in] lhs JSON pointer
12607 @param[in] rhs JSON pointer
12608 @return a new JSON pointer with @a rhs appended to @a lhs
12610 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12612 @complexity Linear in the length of @a lhs and @a rhs.
12614 @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12616 @since version 3.6.0
12618 friend json_pointer operator/(const json_pointer& lhs,
12619 const json_pointer& rhs)
12621 return json_pointer(lhs) /= rhs;
12625 @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
12627 @param[in] ptr JSON pointer
12628 @param[in] token reference token
12629 @return a new JSON pointer with unescaped @a token appended to @a ptr
12631 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12633 @complexity Linear in the length of @a ptr.
12635 @sa see @ref operator/=(std::string) to append a reference token
12637 @since version 3.6.0
12639 friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param)
12641 return json_pointer(ptr) /= std::move(token);
12645 @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
12647 @param[in] ptr JSON pointer
12648 @param[in] array_idx array index
12649 @return a new JSON pointer with @a array_idx appended to @a ptr
12651 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12653 @complexity Linear in the length of @a ptr.
12655 @sa see @ref operator/=(std::size_t) to append an array index
12657 @since version 3.6.0
12659 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
12661 return json_pointer(ptr) /= array_idx;
12665 @brief returns the parent of this JSON pointer
12667 @return parent of this JSON pointer; in case this JSON pointer is the root,
12668 the root itself is returned
12670 @complexity Linear in the length of the JSON pointer.
12672 @liveexample{The example shows the result of `parent_pointer` for different
12673 JSON Pointers.,json_pointer__parent_pointer}
12675 @since version 3.6.0
12677 json_pointer parent_pointer() const
12684 json_pointer res = *this;
12690 @brief remove last reference token
12694 @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
12696 @complexity Constant.
12698 @throw out_of_range.405 if JSON pointer has no parent
12700 @since version 3.6.0
12704 if (JSON_HEDLEY_UNLIKELY(empty()))
12706 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12709 reference_tokens.pop_back();
12713 @brief return last reference token
12716 @return last reference token
12718 @liveexample{The example shows the usage of `back`.,json_pointer__back}
12720 @complexity Constant.
12722 @throw out_of_range.405 if JSON pointer has no parent
12724 @since version 3.6.0
12726 const std::string& back() const
12728 if (JSON_HEDLEY_UNLIKELY(empty()))
12730 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12733 return reference_tokens.back();
12737 @brief append an unescaped token at the end of the reference pointer
12739 @param[in] token token to add
12741 @complexity Amortized constant.
12743 @liveexample{The example shows the result of `push_back` for different
12744 JSON Pointers.,json_pointer__push_back}
12746 @since version 3.6.0
12748 void push_back(const std::string& token)
12750 reference_tokens.push_back(token);
12753 /// @copydoc push_back(const std::string&)
12754 void push_back(std::string&& token)
12756 reference_tokens.push_back(std::move(token));
12760 @brief return whether pointer points to the root document
12762 @return true iff the JSON pointer points to the root document
12764 @complexity Constant.
12766 @exceptionsafety No-throw guarantee: this function never throws exceptions.
12768 @liveexample{The example shows the result of `empty` for different JSON
12769 Pointers.,json_pointer__empty}
12771 @since version 3.6.0
12773 bool empty() const noexcept
12775 return reference_tokens.empty();
12780 @param[in] s reference token to be converted into an array index
12782 @return integer representation of @a s
12784 @throw parse_error.106 if an array index begins with '0'
12785 @throw parse_error.109 if an array index begins not with a digit
12786 @throw out_of_range.404 if string @a s could not be converted to an integer
12787 @throw out_of_range.410 if an array index exceeds size_type
12789 static typename BasicJsonType::size_type array_index(const std::string& s)
12791 using size_type = typename BasicJsonType::size_type;
12793 // error condition (cf. RFC 6901, Sect. 4)
12794 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
12796 JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
12799 // error condition (cf. RFC 6901, Sect. 4)
12800 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
12802 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
12805 std::size_t processed_chars = 0;
12806 unsigned long long res = 0; // NOLINT(runtime/int)
12809 res = std::stoull(s, &processed_chars);
12811 JSON_CATCH(std::out_of_range&)
12813 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12816 // check if the string was completely read
12817 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
12819 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12822 // only triggered on special platforms (like 32bit), see also
12823 // https://github.com/nlohmann/json/pull/2203
12824 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
12826 JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
12829 return static_cast<size_type>(res);
12832 JSON_PRIVATE_UNLESS_TESTED:
12833 json_pointer top() const
12835 if (JSON_HEDLEY_UNLIKELY(empty()))
12837 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12840 json_pointer result = *this;
12841 result.reference_tokens = {reference_tokens[0]};
12847 @brief create and return a reference to the pointed to value
12849 @complexity Linear in the number of reference tokens.
12851 @throw parse_error.109 if array index is not a number
12852 @throw type_error.313 if value cannot be unflattened
12854 BasicJsonType& get_and_create(BasicJsonType& j) const
12858 // in case no reference tokens exist, return a reference to the JSON value
12859 // j which will be overwritten by a primitive value
12860 for (const auto& reference_token : reference_tokens)
12862 switch (result->type())
12864 case detail::value_t::null:
12866 if (reference_token == "0")
12868 // start a new array if reference token is 0
12869 result = &result->operator[](0);
12873 // start a new object otherwise
12874 result = &result->operator[](reference_token);
12879 case detail::value_t::object:
12881 // create an entry in the object
12882 result = &result->operator[](reference_token);
12886 case detail::value_t::array:
12888 // create an entry in the array
12889 result = &result->operator[](array_index(reference_token));
12894 The following code is only reached if there exists a reference
12895 token _and_ the current value is primitive. In this case, we have
12896 an error situation, because primitive values may only occur as
12897 single value; that is, with an empty list of reference tokens.
12899 case detail::value_t::string:
12900 case detail::value_t::boolean:
12901 case detail::value_t::number_integer:
12902 case detail::value_t::number_unsigned:
12903 case detail::value_t::number_float:
12904 case detail::value_t::binary:
12905 case detail::value_t::discarded:
12907 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
12915 @brief return a reference to the pointed to value
12917 @note This version does not throw if a value is not present, but tries to
12918 create nested values instead. For instance, calling this function
12919 with pointer `"/this/that"` on a null value is equivalent to calling
12920 `operator[]("this").operator[]("that")` on that value, effectively
12921 changing the null value to an object.
12923 @param[in] ptr a JSON value
12925 @return reference to the JSON value pointed to by the JSON pointer
12927 @complexity Linear in the length of the JSON pointer.
12929 @throw parse_error.106 if an array index begins with '0'
12930 @throw parse_error.109 if an array index was not a number
12931 @throw out_of_range.404 if the JSON pointer can not be resolved
12933 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12935 for (const auto& reference_token : reference_tokens)
12937 // convert null values to arrays or objects before continuing
12938 if (ptr->is_null())
12940 // check if reference token is a number
12942 std::all_of(reference_token.begin(), reference_token.end(),
12943 [](const unsigned char x)
12945 return std::isdigit(x);
12948 // change value to array for numbers or "-" or to object otherwise
12949 *ptr = (nums || reference_token == "-")
12950 ? detail::value_t::array
12951 : detail::value_t::object;
12954 switch (ptr->type())
12956 case detail::value_t::object:
12958 // use unchecked object access
12959 ptr = &ptr->operator[](reference_token);
12963 case detail::value_t::array:
12965 if (reference_token == "-")
12967 // explicitly treat "-" as index beyond the end
12968 ptr = &ptr->operator[](ptr->m_value.array->size());
12972 // convert array index to number; unchecked access
12973 ptr = &ptr->operator[](array_index(reference_token));
12978 case detail::value_t::null:
12979 case detail::value_t::string:
12980 case detail::value_t::boolean:
12981 case detail::value_t::number_integer:
12982 case detail::value_t::number_unsigned:
12983 case detail::value_t::number_float:
12984 case detail::value_t::binary:
12985 case detail::value_t::discarded:
12987 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12995 @throw parse_error.106 if an array index begins with '0'
12996 @throw parse_error.109 if an array index was not a number
12997 @throw out_of_range.402 if the array index '-' is used
12998 @throw out_of_range.404 if the JSON pointer can not be resolved
13000 BasicJsonType& get_checked(BasicJsonType* ptr) const
13002 for (const auto& reference_token : reference_tokens)
13004 switch (ptr->type())
13006 case detail::value_t::object:
13008 // note: at performs range check
13009 ptr = &ptr->at(reference_token);
13013 case detail::value_t::array:
13015 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13017 // "-" always fails the range check
13018 JSON_THROW(detail::out_of_range::create(402,
13019 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13020 ") is out of range", *ptr));
13023 // note: at performs range check
13024 ptr = &ptr->at(array_index(reference_token));
13028 case detail::value_t::null:
13029 case detail::value_t::string:
13030 case detail::value_t::boolean:
13031 case detail::value_t::number_integer:
13032 case detail::value_t::number_unsigned:
13033 case detail::value_t::number_float:
13034 case detail::value_t::binary:
13035 case detail::value_t::discarded:
13037 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13045 @brief return a const reference to the pointed to value
13047 @param[in] ptr a JSON value
13049 @return const reference to the JSON value pointed to by the JSON
13052 @throw parse_error.106 if an array index begins with '0'
13053 @throw parse_error.109 if an array index was not a number
13054 @throw out_of_range.402 if the array index '-' is used
13055 @throw out_of_range.404 if the JSON pointer can not be resolved
13057 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
13059 for (const auto& reference_token : reference_tokens)
13061 switch (ptr->type())
13063 case detail::value_t::object:
13065 // use unchecked object access
13066 ptr = &ptr->operator[](reference_token);
13070 case detail::value_t::array:
13072 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13074 // "-" cannot be used for const access
13075 JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
13078 // use unchecked array access
13079 ptr = &ptr->operator[](array_index(reference_token));
13083 case detail::value_t::null:
13084 case detail::value_t::string:
13085 case detail::value_t::boolean:
13086 case detail::value_t::number_integer:
13087 case detail::value_t::number_unsigned:
13088 case detail::value_t::number_float:
13089 case detail::value_t::binary:
13090 case detail::value_t::discarded:
13092 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13100 @throw parse_error.106 if an array index begins with '0'
13101 @throw parse_error.109 if an array index was not a number
13102 @throw out_of_range.402 if the array index '-' is used
13103 @throw out_of_range.404 if the JSON pointer can not be resolved
13105 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
13107 for (const auto& reference_token : reference_tokens)
13109 switch (ptr->type())
13111 case detail::value_t::object:
13113 // note: at performs range check
13114 ptr = &ptr->at(reference_token);
13118 case detail::value_t::array:
13120 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13122 // "-" always fails the range check
13123 JSON_THROW(detail::out_of_range::create(402,
13124 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13125 ") is out of range", *ptr));
13128 // note: at performs range check
13129 ptr = &ptr->at(array_index(reference_token));
13133 case detail::value_t::null:
13134 case detail::value_t::string:
13135 case detail::value_t::boolean:
13136 case detail::value_t::number_integer:
13137 case detail::value_t::number_unsigned:
13138 case detail::value_t::number_float:
13139 case detail::value_t::binary:
13140 case detail::value_t::discarded:
13142 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13150 @throw parse_error.106 if an array index begins with '0'
13151 @throw parse_error.109 if an array index was not a number
13153 bool contains(const BasicJsonType* ptr) const
13155 for (const auto& reference_token : reference_tokens)
13157 switch (ptr->type())
13159 case detail::value_t::object:
13161 if (!ptr->contains(reference_token))
13163 // we did not find the key in the object
13167 ptr = &ptr->operator[](reference_token);
13171 case detail::value_t::array:
13173 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13175 // "-" always fails the range check
13178 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13183 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
13185 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13187 // first char should be between '1' and '9'
13190 for (std::size_t i = 1; i < reference_token.size(); i++)
13192 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13194 // other char should be between '0' and '9'
13200 const auto idx = array_index(reference_token);
13201 if (idx >= ptr->size())
13203 // index out of range
13207 ptr = &ptr->operator[](idx);
13211 case detail::value_t::null:
13212 case detail::value_t::string:
13213 case detail::value_t::boolean:
13214 case detail::value_t::number_integer:
13215 case detail::value_t::number_unsigned:
13216 case detail::value_t::number_float:
13217 case detail::value_t::binary:
13218 case detail::value_t::discarded:
13221 // we do not expect primitive values if there is still a
13222 // reference token to process
13228 // no reference token left means we found a primitive value
13233 @brief split the string input to reference tokens
13235 @note This function is only called by the json_pointer constructor.
13236 All exceptions below are documented there.
13238 @throw parse_error.107 if the pointer is not empty or begins with '/'
13239 @throw parse_error.108 if character '~' is not followed by '0' or '1'
13241 static std::vector<std::string> split(const std::string& reference_string)
13243 std::vector<std::string> result;
13245 // special case: empty reference string -> no reference tokens
13246 if (reference_string.empty())
13251 // check if nonempty reference string begins with slash
13252 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
13254 JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
13257 // extract the reference tokens:
13258 // - slash: position of the last read slash (or end of string)
13259 // - start: position after the previous slash
13261 // search for the first slash after the first character
13262 std::size_t slash = reference_string.find_first_of('/', 1),
13263 // set the beginning of the first reference token
13265 // we can stop if start == 0 (if slash == std::string::npos)
13267 // set the beginning of the next reference token
13268 // (will eventually be 0 if slash == std::string::npos)
13269 start = (slash == std::string::npos) ? 0 : slash + 1,
13271 slash = reference_string.find_first_of('/', start))
13273 // use the text between the beginning of the reference token
13274 // (start) and the last slash (slash).
13275 auto reference_token = reference_string.substr(start, slash - start);
13277 // check reference tokens are properly escaped
13278 for (std::size_t pos = reference_token.find_first_of('~');
13279 pos != std::string::npos;
13280 pos = reference_token.find_first_of('~', pos + 1))
13282 JSON_ASSERT(reference_token[pos] == '~');
13284 // ~ must be followed by 0 or 1
13285 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
13286 (reference_token[pos + 1] != '0' &&
13287 reference_token[pos + 1] != '1')))
13289 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
13293 // finally, store the reference token
13294 detail::unescape(reference_token);
13295 result.push_back(reference_token);
13303 @param[in] reference_string the reference string to the current value
13304 @param[in] value the value to consider
13305 @param[in,out] result the result object to insert values to
13307 @note Empty objects or arrays are flattened to `null`.
13309 static void flatten(const std::string& reference_string,
13310 const BasicJsonType& value,
13311 BasicJsonType& result)
13313 switch (value.type())
13315 case detail::value_t::array:
13317 if (value.m_value.array->empty())
13319 // flatten empty array as null
13320 result[reference_string] = nullptr;
13324 // iterate array and use index as reference string
13325 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13327 flatten(reference_string + "/" + std::to_string(i),
13328 value.m_value.array->operator[](i), result);
13334 case detail::value_t::object:
13336 if (value.m_value.object->empty())
13338 // flatten empty object as null
13339 result[reference_string] = nullptr;
13343 // iterate object and use keys as reference string
13344 for (const auto& element : *value.m_value.object)
13346 flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
13352 case detail::value_t::null:
13353 case detail::value_t::string:
13354 case detail::value_t::boolean:
13355 case detail::value_t::number_integer:
13356 case detail::value_t::number_unsigned:
13357 case detail::value_t::number_float:
13358 case detail::value_t::binary:
13359 case detail::value_t::discarded:
13362 // add primitive value with its reference string
13363 result[reference_string] = value;
13370 @param[in] value flattened JSON
13372 @return unflattened JSON
13374 @throw parse_error.109 if array index is not a number
13375 @throw type_error.314 if value is not an object
13376 @throw type_error.315 if object values are not primitive
13377 @throw type_error.313 if value cannot be unflattened
13379 static BasicJsonType
13380 unflatten(const BasicJsonType& value)
13382 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
13384 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
13387 BasicJsonType result;
13389 // iterate the JSON object values
13390 for (const auto& element : *value.m_value.object)
13392 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
13394 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
13397 // assign value to reference pointed to by JSON pointer; Note that if
13398 // the JSON pointer is "" (i.e., points to the whole value), function
13399 // get_and_create returns a reference to result itself. An assignment
13400 // will then create a primitive value.
13401 json_pointer(element.first).get_and_create(result) = element.second;
13408 @brief compares two JSON pointers for equality
13410 @param[in] lhs JSON pointer to compare
13411 @param[in] rhs JSON pointer to compare
13412 @return whether @a lhs is equal to @a rhs
13414 @complexity Linear in the length of the JSON pointer
13416 @exceptionsafety No-throw guarantee: this function never throws exceptions.
13418 friend bool operator==(json_pointer const& lhs,
13419 json_pointer const& rhs) noexcept
13421 return lhs.reference_tokens == rhs.reference_tokens;
13425 @brief compares two JSON pointers for inequality
13427 @param[in] lhs JSON pointer to compare
13428 @param[in] rhs JSON pointer to compare
13429 @return whether @a lhs is not equal @a rhs
13431 @complexity Linear in the length of the JSON pointer
13433 @exceptionsafety No-throw guarantee: this function never throws exceptions.
13435 friend bool operator!=(json_pointer const& lhs,
13436 json_pointer const& rhs) noexcept
13438 return !(lhs == rhs);
13441 /// the reference tokens
13442 std::vector<std::string> reference_tokens;
13444 } // namespace nlohmann
13446 // #include <nlohmann/detail/json_ref.hpp>
13449 #include <initializer_list>
13452 // #include <nlohmann/detail/meta/type_traits.hpp>
13459 template<typename BasicJsonType>
13463 using value_type = BasicJsonType;
13465 json_ref(value_type&& value)
13466 : owned_value(std::move(value))
13469 json_ref(const value_type& value)
13470 : value_ref(&value)
13473 json_ref(std::initializer_list<json_ref> init)
13474 : owned_value(init)
13479 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13480 json_ref(Args && ... args)
13481 : owned_value(std::forward<Args>(args)...)
13484 // class should be movable only
13485 json_ref(json_ref&&) noexcept = default;
13486 json_ref(const json_ref&) = delete;
13487 json_ref& operator=(const json_ref&) = delete;
13488 json_ref& operator=(json_ref&&) = delete;
13489 ~json_ref() = default;
13491 value_type moved_or_copied() const
13493 if (value_ref == nullptr)
13495 return std::move(owned_value);
13500 value_type const& operator*() const
13502 return value_ref ? *value_ref : owned_value;
13505 value_type const* operator->() const
13511 mutable value_type owned_value = nullptr;
13512 value_type const* value_ref = nullptr;
13514 } // namespace detail
13515 } // namespace nlohmann
13517 // #include <nlohmann/detail/macro_scope.hpp>
13519 // #include <nlohmann/detail/string_escape.hpp>
13521 // #include <nlohmann/detail/meta/cpp_future.hpp>
13523 // #include <nlohmann/detail/meta/type_traits.hpp>
13525 // #include <nlohmann/detail/output/binary_writer.hpp>
13528 #include <algorithm> // reverse
13529 #include <array> // array
13530 #include <cmath> // isnan, isinf
13531 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13532 #include <cstring> // memcpy
13533 #include <limits> // numeric_limits
13534 #include <string> // string
13535 #include <utility> // move
13537 // #include <nlohmann/detail/input/binary_reader.hpp>
13539 // #include <nlohmann/detail/macro_scope.hpp>
13541 // #include <nlohmann/detail/output/output_adapters.hpp>
13544 #include <algorithm> // copy
13545 #include <cstddef> // size_t
13546 #include <iterator> // back_inserter
13547 #include <memory> // shared_ptr, make_shared
13548 #include <string> // basic_string
13549 #include <vector> // vector
13552 #include <ios> // streamsize
13553 #include <ostream> // basic_ostream
13554 #endif // JSON_NO_IO
13556 // #include <nlohmann/detail/macro_scope.hpp>
13563 /// abstract output adapter interface
13564 template<typename CharType> struct output_adapter_protocol
13566 virtual void write_character(CharType c) = 0;
13567 virtual void write_characters(const CharType* s, std::size_t length) = 0;
13568 virtual ~output_adapter_protocol() = default;
13570 output_adapter_protocol() = default;
13571 output_adapter_protocol(const output_adapter_protocol&) = default;
13572 output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
13573 output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
13574 output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
13577 /// a type to simplify interfaces
13578 template<typename CharType>
13579 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13581 /// output adapter for byte vectors
13582 template<typename CharType, typename AllocatorType = std::allocator<CharType>>
13583 class output_vector_adapter : public output_adapter_protocol<CharType>
13586 explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
13590 void write_character(CharType c) override
13595 JSON_HEDLEY_NON_NULL(2)
13596 void write_characters(const CharType* s, std::size_t length) override
13598 std::copy(s, s + length, std::back_inserter(v));
13602 std::vector<CharType, AllocatorType>& v;
13606 /// output adapter for output streams
13607 template<typename CharType>
13608 class output_stream_adapter : public output_adapter_protocol<CharType>
13611 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13615 void write_character(CharType c) override
13620 JSON_HEDLEY_NON_NULL(2)
13621 void write_characters(const CharType* s, std::size_t length) override
13623 stream.write(s, static_cast<std::streamsize>(length));
13627 std::basic_ostream<CharType>& stream;
13629 #endif // JSON_NO_IO
13631 /// output adapter for basic_string
13632 template<typename CharType, typename StringType = std::basic_string<CharType>>
13633 class output_string_adapter : public output_adapter_protocol<CharType>
13636 explicit output_string_adapter(StringType& s) noexcept
13640 void write_character(CharType c) override
13645 JSON_HEDLEY_NON_NULL(2)
13646 void write_characters(const CharType* s, std::size_t length) override
13648 str.append(s, length);
13655 template<typename CharType, typename StringType = std::basic_string<CharType>>
13656 class output_adapter
13659 template<typename AllocatorType = std::allocator<CharType>>
13660 output_adapter(std::vector<CharType, AllocatorType>& vec)
13661 : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
13664 output_adapter(std::basic_ostream<CharType>& s)
13665 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
13666 #endif // JSON_NO_IO
13668 output_adapter(StringType& s)
13669 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
13671 operator output_adapter_t<CharType>()
13677 output_adapter_t<CharType> oa = nullptr;
13679 } // namespace detail
13680 } // namespace nlohmann
13687 ///////////////////
13688 // binary writer //
13689 ///////////////////
13692 @brief serialization to CBOR and MessagePack values
13694 template<typename BasicJsonType, typename CharType>
13695 class binary_writer
13697 using string_t = typename BasicJsonType::string_t;
13698 using binary_t = typename BasicJsonType::binary_t;
13699 using number_float_t = typename BasicJsonType::number_float_t;
13703 @brief create a binary writer
13705 @param[in] adapter output adapter to write to
13707 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
13713 @param[in] j JSON value to serialize
13714 @pre j.type() == value_t::object
13716 void write_bson(const BasicJsonType& j)
13720 case value_t::object:
13722 write_bson_object(*j.m_value.object);
13726 case value_t::null:
13727 case value_t::array:
13728 case value_t::string:
13729 case value_t::boolean:
13730 case value_t::number_integer:
13731 case value_t::number_unsigned:
13732 case value_t::number_float:
13733 case value_t::binary:
13734 case value_t::discarded:
13737 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));
13743 @param[in] j JSON value to serialize
13745 void write_cbor(const BasicJsonType& j)
13749 case value_t::null:
13751 oa->write_character(to_char_type(0xF6));
13755 case value_t::boolean:
13757 oa->write_character(j.m_value.boolean
13758 ? to_char_type(0xF5)
13759 : to_char_type(0xF4));
13763 case value_t::number_integer:
13765 if (j.m_value.number_integer >= 0)
13767 // CBOR does not differentiate between positive signed
13768 // integers and unsigned integers. Therefore, we used the
13769 // code from the value_t::number_unsigned case here.
13770 if (j.m_value.number_integer <= 0x17)
13772 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13774 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13776 oa->write_character(to_char_type(0x18));
13777 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13779 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
13781 oa->write_character(to_char_type(0x19));
13782 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13784 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
13786 oa->write_character(to_char_type(0x1A));
13787 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13791 oa->write_character(to_char_type(0x1B));
13792 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13797 // The conversions below encode the sign in the first
13798 // byte, and the value is converted to a positive number.
13799 const auto positive_number = -1 - j.m_value.number_integer;
13800 if (j.m_value.number_integer >= -24)
13802 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
13804 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
13806 oa->write_character(to_char_type(0x38));
13807 write_number(static_cast<std::uint8_t>(positive_number));
13809 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
13811 oa->write_character(to_char_type(0x39));
13812 write_number(static_cast<std::uint16_t>(positive_number));
13814 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
13816 oa->write_character(to_char_type(0x3A));
13817 write_number(static_cast<std::uint32_t>(positive_number));
13821 oa->write_character(to_char_type(0x3B));
13822 write_number(static_cast<std::uint64_t>(positive_number));
13828 case value_t::number_unsigned:
13830 if (j.m_value.number_unsigned <= 0x17)
13832 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13834 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13836 oa->write_character(to_char_type(0x18));
13837 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13839 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13841 oa->write_character(to_char_type(0x19));
13842 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
13844 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13846 oa->write_character(to_char_type(0x1A));
13847 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
13851 oa->write_character(to_char_type(0x1B));
13852 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
13857 case value_t::number_float:
13859 if (std::isnan(j.m_value.number_float))
13861 // NaN is 0xf97e00 in CBOR
13862 oa->write_character(to_char_type(0xF9));
13863 oa->write_character(to_char_type(0x7E));
13864 oa->write_character(to_char_type(0x00));
13866 else if (std::isinf(j.m_value.number_float))
13868 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
13869 oa->write_character(to_char_type(0xf9));
13870 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
13871 oa->write_character(to_char_type(0x00));
13875 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
13880 case value_t::string:
13882 // step 1: write control byte and the string length
13883 const auto N = j.m_value.string->size();
13886 write_number(static_cast<std::uint8_t>(0x60 + N));
13888 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13890 oa->write_character(to_char_type(0x78));
13891 write_number(static_cast<std::uint8_t>(N));
13893 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13895 oa->write_character(to_char_type(0x79));
13896 write_number(static_cast<std::uint16_t>(N));
13898 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13900 oa->write_character(to_char_type(0x7A));
13901 write_number(static_cast<std::uint32_t>(N));
13904 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13906 oa->write_character(to_char_type(0x7B));
13907 write_number(static_cast<std::uint64_t>(N));
13911 // step 2: write the string
13912 oa->write_characters(
13913 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13914 j.m_value.string->size());
13918 case value_t::array:
13920 // step 1: write control byte and the array size
13921 const auto N = j.m_value.array->size();
13924 write_number(static_cast<std::uint8_t>(0x80 + N));
13926 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13928 oa->write_character(to_char_type(0x98));
13929 write_number(static_cast<std::uint8_t>(N));
13931 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13933 oa->write_character(to_char_type(0x99));
13934 write_number(static_cast<std::uint16_t>(N));
13936 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13938 oa->write_character(to_char_type(0x9A));
13939 write_number(static_cast<std::uint32_t>(N));
13942 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13944 oa->write_character(to_char_type(0x9B));
13945 write_number(static_cast<std::uint64_t>(N));
13949 // step 2: write each element
13950 for (const auto& el : *j.m_value.array)
13957 case value_t::binary:
13959 if (j.m_value.binary->has_subtype())
13961 if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
13963 write_number(static_cast<std::uint8_t>(0xd8));
13964 write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
13966 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
13968 write_number(static_cast<std::uint8_t>(0xd9));
13969 write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
13971 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
13973 write_number(static_cast<std::uint8_t>(0xda));
13974 write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
13976 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
13978 write_number(static_cast<std::uint8_t>(0xdb));
13979 write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
13983 // step 1: write control byte and the binary array size
13984 const auto N = j.m_value.binary->size();
13987 write_number(static_cast<std::uint8_t>(0x40 + N));
13989 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13991 oa->write_character(to_char_type(0x58));
13992 write_number(static_cast<std::uint8_t>(N));
13994 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13996 oa->write_character(to_char_type(0x59));
13997 write_number(static_cast<std::uint16_t>(N));
13999 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14001 oa->write_character(to_char_type(0x5A));
14002 write_number(static_cast<std::uint32_t>(N));
14005 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14007 oa->write_character(to_char_type(0x5B));
14008 write_number(static_cast<std::uint64_t>(N));
14012 // step 2: write each element
14013 oa->write_characters(
14014 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14020 case value_t::object:
14022 // step 1: write control byte and the object size
14023 const auto N = j.m_value.object->size();
14026 write_number(static_cast<std::uint8_t>(0xA0 + N));
14028 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14030 oa->write_character(to_char_type(0xB8));
14031 write_number(static_cast<std::uint8_t>(N));
14033 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14035 oa->write_character(to_char_type(0xB9));
14036 write_number(static_cast<std::uint16_t>(N));
14038 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14040 oa->write_character(to_char_type(0xBA));
14041 write_number(static_cast<std::uint32_t>(N));
14044 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14046 oa->write_character(to_char_type(0xBB));
14047 write_number(static_cast<std::uint64_t>(N));
14051 // step 2: write each element
14052 for (const auto& el : *j.m_value.object)
14054 write_cbor(el.first);
14055 write_cbor(el.second);
14060 case value_t::discarded:
14067 @param[in] j JSON value to serialize
14069 void write_msgpack(const BasicJsonType& j)
14073 case value_t::null: // nil
14075 oa->write_character(to_char_type(0xC0));
14079 case value_t::boolean: // true and false
14081 oa->write_character(j.m_value.boolean
14082 ? to_char_type(0xC3)
14083 : to_char_type(0xC2));
14087 case value_t::number_integer:
14089 if (j.m_value.number_integer >= 0)
14091 // MessagePack does not differentiate between positive
14092 // signed integers and unsigned integers. Therefore, we used
14093 // the code from the value_t::number_unsigned case here.
14094 if (j.m_value.number_unsigned < 128)
14097 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14099 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14102 oa->write_character(to_char_type(0xCC));
14103 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14105 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14108 oa->write_character(to_char_type(0xCD));
14109 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14111 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14114 oa->write_character(to_char_type(0xCE));
14115 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14117 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14120 oa->write_character(to_char_type(0xCF));
14121 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14126 if (j.m_value.number_integer >= -32)
14129 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14131 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14132 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14135 oa->write_character(to_char_type(0xD0));
14136 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14138 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14139 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14142 oa->write_character(to_char_type(0xD1));
14143 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
14145 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14146 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14149 oa->write_character(to_char_type(0xD2));
14150 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
14152 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14153 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14156 oa->write_character(to_char_type(0xD3));
14157 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
14163 case value_t::number_unsigned:
14165 if (j.m_value.number_unsigned < 128)
14168 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14170 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14173 oa->write_character(to_char_type(0xCC));
14174 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14176 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14179 oa->write_character(to_char_type(0xCD));
14180 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14182 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14185 oa->write_character(to_char_type(0xCE));
14186 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14188 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14191 oa->write_character(to_char_type(0xCF));
14192 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14197 case value_t::number_float:
14199 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
14203 case value_t::string:
14205 // step 1: write control byte and the string length
14206 const auto N = j.m_value.string->size();
14210 write_number(static_cast<std::uint8_t>(0xA0 | N));
14212 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14215 oa->write_character(to_char_type(0xD9));
14216 write_number(static_cast<std::uint8_t>(N));
14218 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14221 oa->write_character(to_char_type(0xDA));
14222 write_number(static_cast<std::uint16_t>(N));
14224 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14227 oa->write_character(to_char_type(0xDB));
14228 write_number(static_cast<std::uint32_t>(N));
14231 // step 2: write the string
14232 oa->write_characters(
14233 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14234 j.m_value.string->size());
14238 case value_t::array:
14240 // step 1: write control byte and the array size
14241 const auto N = j.m_value.array->size();
14245 write_number(static_cast<std::uint8_t>(0x90 | N));
14247 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14250 oa->write_character(to_char_type(0xDC));
14251 write_number(static_cast<std::uint16_t>(N));
14253 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14256 oa->write_character(to_char_type(0xDD));
14257 write_number(static_cast<std::uint32_t>(N));
14260 // step 2: write each element
14261 for (const auto& el : *j.m_value.array)
14268 case value_t::binary:
14270 // step 0: determine if the binary type has a set subtype to
14271 // determine whether or not to use the ext or fixext types
14272 const bool use_ext = j.m_value.binary->has_subtype();
14274 // step 1: write control byte and the byte string length
14275 const auto N = j.m_value.binary->size();
14276 if (N <= (std::numeric_limits<std::uint8_t>::max)())
14278 std::uint8_t output_type{};
14285 output_type = 0xD4; // fixext 1
14288 output_type = 0xD5; // fixext 2
14291 output_type = 0xD6; // fixext 4
14294 output_type = 0xD7; // fixext 8
14297 output_type = 0xD8; // fixext 16
14300 output_type = 0xC7; // ext 8
14308 output_type = 0xC4; // bin 8
14312 oa->write_character(to_char_type(output_type));
14315 write_number(static_cast<std::uint8_t>(N));
14318 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14320 std::uint8_t output_type = use_ext
14324 oa->write_character(to_char_type(output_type));
14325 write_number(static_cast<std::uint16_t>(N));
14327 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14329 std::uint8_t output_type = use_ext
14333 oa->write_character(to_char_type(output_type));
14334 write_number(static_cast<std::uint32_t>(N));
14337 // step 1.5: if this is an ext type, write the subtype
14340 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14343 // step 2: write the byte string
14344 oa->write_characters(
14345 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14351 case value_t::object:
14353 // step 1: write control byte and the object size
14354 const auto N = j.m_value.object->size();
14358 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
14360 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14363 oa->write_character(to_char_type(0xDE));
14364 write_number(static_cast<std::uint16_t>(N));
14366 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14369 oa->write_character(to_char_type(0xDF));
14370 write_number(static_cast<std::uint32_t>(N));
14373 // step 2: write each element
14374 for (const auto& el : *j.m_value.object)
14376 write_msgpack(el.first);
14377 write_msgpack(el.second);
14382 case value_t::discarded:
14389 @param[in] j JSON value to serialize
14390 @param[in] use_count whether to use '#' prefixes (optimized format)
14391 @param[in] use_type whether to use '$' prefixes (optimized format)
14392 @param[in] add_prefix whether prefixes need to be used for this value
14394 void write_ubjson(const BasicJsonType& j, const bool use_count,
14395 const bool use_type, const bool add_prefix = true)
14399 case value_t::null:
14403 oa->write_character(to_char_type('Z'));
14408 case value_t::boolean:
14412 oa->write_character(j.m_value.boolean
14413 ? to_char_type('T')
14414 : to_char_type('F'));
14419 case value_t::number_integer:
14421 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
14425 case value_t::number_unsigned:
14427 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
14431 case value_t::number_float:
14433 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
14437 case value_t::string:
14441 oa->write_character(to_char_type('S'));
14443 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
14444 oa->write_characters(
14445 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14446 j.m_value.string->size());
14450 case value_t::array:
14454 oa->write_character(to_char_type('['));
14457 bool prefix_required = true;
14458 if (use_type && !j.m_value.array->empty())
14460 JSON_ASSERT(use_count);
14461 const CharType first_prefix = ubjson_prefix(j.front());
14462 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14463 [this, first_prefix](const BasicJsonType & v)
14465 return ubjson_prefix(v) == first_prefix;
14470 prefix_required = false;
14471 oa->write_character(to_char_type('$'));
14472 oa->write_character(first_prefix);
14478 oa->write_character(to_char_type('#'));
14479 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
14482 for (const auto& el : *j.m_value.array)
14484 write_ubjson(el, use_count, use_type, prefix_required);
14489 oa->write_character(to_char_type(']'));
14495 case value_t::binary:
14499 oa->write_character(to_char_type('['));
14502 if (use_type && !j.m_value.binary->empty())
14504 JSON_ASSERT(use_count);
14505 oa->write_character(to_char_type('$'));
14506 oa->write_character('U');
14511 oa->write_character(to_char_type('#'));
14512 write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
14517 oa->write_characters(
14518 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14519 j.m_value.binary->size());
14523 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14525 oa->write_character(to_char_type('U'));
14526 oa->write_character(j.m_value.binary->data()[i]);
14532 oa->write_character(to_char_type(']'));
14538 case value_t::object:
14542 oa->write_character(to_char_type('{'));
14545 bool prefix_required = true;
14546 if (use_type && !j.m_value.object->empty())
14548 JSON_ASSERT(use_count);
14549 const CharType first_prefix = ubjson_prefix(j.front());
14550 const bool same_prefix = std::all_of(j.begin(), j.end(),
14551 [this, first_prefix](const BasicJsonType & v)
14553 return ubjson_prefix(v) == first_prefix;
14558 prefix_required = false;
14559 oa->write_character(to_char_type('$'));
14560 oa->write_character(first_prefix);
14566 oa->write_character(to_char_type('#'));
14567 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
14570 for (const auto& el : *j.m_value.object)
14572 write_number_with_ubjson_prefix(el.first.size(), true);
14573 oa->write_characters(
14574 reinterpret_cast<const CharType*>(el.first.c_str()),
14576 write_ubjson(el.second, use_count, use_type, prefix_required);
14581 oa->write_character(to_char_type('}'));
14587 case value_t::discarded:
14599 @return The size of a BSON document entry header, including the id marker
14600 and the entry name size (and its null-terminator).
14602 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14604 const auto it = name.find(static_cast<typename string_t::value_type>(0));
14605 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14607 JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
14608 static_cast<void>(j);
14611 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14615 @brief Writes the given @a element_type and @a name to the output adapter
14617 void write_bson_entry_header(const string_t& name,
14618 const std::uint8_t element_type)
14620 oa->write_character(to_char_type(element_type)); // boolean
14621 oa->write_characters(
14622 reinterpret_cast<const CharType*>(name.c_str()),
14627 @brief Writes a BSON element with key @a name and boolean value @a value
14629 void write_bson_boolean(const string_t& name,
14632 write_bson_entry_header(name, 0x08);
14633 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
14637 @brief Writes a BSON element with key @a name and double value @a value
14639 void write_bson_double(const string_t& name,
14640 const double value)
14642 write_bson_entry_header(name, 0x01);
14643 write_number<double, true>(value);
14647 @return The size of the BSON-encoded string in @a value
14649 static std::size_t calc_bson_string_size(const string_t& value)
14651 return sizeof(std::int32_t) + value.size() + 1ul;
14655 @brief Writes a BSON element with key @a name and string value @a value
14657 void write_bson_string(const string_t& name,
14658 const string_t& value)
14660 write_bson_entry_header(name, 0x02);
14662 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
14663 oa->write_characters(
14664 reinterpret_cast<const CharType*>(value.c_str()),
14669 @brief Writes a BSON element with key @a name and null value
14671 void write_bson_null(const string_t& name)
14673 write_bson_entry_header(name, 0x0A);
14677 @return The size of the BSON-encoded integer @a value
14679 static std::size_t calc_bson_integer_size(const std::int64_t value)
14681 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
14682 ? sizeof(std::int32_t)
14683 : sizeof(std::int64_t);
14687 @brief Writes a BSON element with key @a name and integer @a value
14689 void write_bson_integer(const string_t& name,
14690 const std::int64_t value)
14692 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
14694 write_bson_entry_header(name, 0x10); // int32
14695 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
14699 write_bson_entry_header(name, 0x12); // int64
14700 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
14705 @return The size of the BSON-encoded unsigned integer in @a j
14707 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
14709 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14710 ? sizeof(std::int32_t)
14711 : sizeof(std::int64_t);
14715 @brief Writes a BSON element with key @a name and unsigned @a value
14717 void write_bson_unsigned(const string_t& name,
14718 const BasicJsonType& j)
14720 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14722 write_bson_entry_header(name, 0x10 /* int32 */);
14723 write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
14725 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14727 write_bson_entry_header(name, 0x12 /* int64 */);
14728 write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
14732 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(j.m_value.number_unsigned) + " cannot be represented by BSON as it does not fit int64", j));
14737 @brief Writes a BSON element with key @a name and object @a value
14739 void write_bson_object_entry(const string_t& name,
14740 const typename BasicJsonType::object_t& value)
14742 write_bson_entry_header(name, 0x03); // object
14743 write_bson_object(value);
14747 @return The size of the BSON-encoded array @a value
14749 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
14751 std::size_t array_index = 0ul;
14753 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
14755 return result + calc_bson_element_size(std::to_string(array_index++), el);
14758 return sizeof(std::int32_t) + embedded_document_size + 1ul;
14762 @return The size of the BSON-encoded binary array @a value
14764 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
14766 return sizeof(std::int32_t) + value.size() + 1ul;
14770 @brief Writes a BSON element with key @a name and array @a value
14772 void write_bson_array(const string_t& name,
14773 const typename BasicJsonType::array_t& value)
14775 write_bson_entry_header(name, 0x04); // array
14776 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
14778 std::size_t array_index = 0ul;
14780 for (const auto& el : value)
14782 write_bson_element(std::to_string(array_index++), el);
14785 oa->write_character(to_char_type(0x00));
14789 @brief Writes a BSON element with key @a name and binary value @a value
14791 void write_bson_binary(const string_t& name,
14792 const binary_t& value)
14794 write_bson_entry_header(name, 0x05);
14796 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
14797 write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : std::uint8_t(0x00));
14799 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
14803 @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
14804 @return The calculated size for the BSON document entry for @a j with the given @a name.
14806 static std::size_t calc_bson_element_size(const string_t& name,
14807 const BasicJsonType& j)
14809 const auto header_size = calc_bson_entry_header_size(name, j);
14812 case value_t::object:
14813 return header_size + calc_bson_object_size(*j.m_value.object);
14815 case value_t::array:
14816 return header_size + calc_bson_array_size(*j.m_value.array);
14818 case value_t::binary:
14819 return header_size + calc_bson_binary_size(*j.m_value.binary);
14821 case value_t::boolean:
14822 return header_size + 1ul;
14824 case value_t::number_float:
14825 return header_size + 8ul;
14827 case value_t::number_integer:
14828 return header_size + calc_bson_integer_size(j.m_value.number_integer);
14830 case value_t::number_unsigned:
14831 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
14833 case value_t::string:
14834 return header_size + calc_bson_string_size(*j.m_value.string);
14836 case value_t::null:
14837 return header_size + 0ul;
14840 case value_t::discarded:
14842 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14849 @brief Serializes the JSON value @a j to BSON and associates it with the
14851 @param name The name to associate with the JSON entity @a j within the
14852 current BSON document
14854 void write_bson_element(const string_t& name,
14855 const BasicJsonType& j)
14859 case value_t::object:
14860 return write_bson_object_entry(name, *j.m_value.object);
14862 case value_t::array:
14863 return write_bson_array(name, *j.m_value.array);
14865 case value_t::binary:
14866 return write_bson_binary(name, *j.m_value.binary);
14868 case value_t::boolean:
14869 return write_bson_boolean(name, j.m_value.boolean);
14871 case value_t::number_float:
14872 return write_bson_double(name, j.m_value.number_float);
14874 case value_t::number_integer:
14875 return write_bson_integer(name, j.m_value.number_integer);
14877 case value_t::number_unsigned:
14878 return write_bson_unsigned(name, j);
14880 case value_t::string:
14881 return write_bson_string(name, *j.m_value.string);
14883 case value_t::null:
14884 return write_bson_null(name);
14887 case value_t::discarded:
14889 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14896 @brief Calculates the size of the BSON serialization of the given
14898 @param[in] value JSON value to serialize
14899 @pre value.type() == value_t::object
14901 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14903 std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
14904 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14906 return result += calc_bson_element_size(el.first, el.second);
14909 return sizeof(std::int32_t) + document_size + 1ul;
14913 @param[in] value JSON value to serialize
14914 @pre value.type() == value_t::object
14916 void write_bson_object(const typename BasicJsonType::object_t& value)
14918 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14920 for (const auto& el : value)
14922 write_bson_element(el.first, el.second);
14925 oa->write_character(to_char_type(0x00));
14932 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14934 return to_char_type(0xFA); // Single-Precision Float
14937 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14939 return to_char_type(0xFB); // Double-Precision Float
14946 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14948 return to_char_type(0xCA); // float 32
14951 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14953 return to_char_type(0xCB); // float 64
14960 // UBJSON: write number (floating point)
14961 template<typename NumberType, typename std::enable_if<
14962 std::is_floating_point<NumberType>::value, int>::type = 0>
14963 void write_number_with_ubjson_prefix(const NumberType n,
14964 const bool add_prefix)
14968 oa->write_character(get_ubjson_float_prefix(n));
14973 // UBJSON: write number (unsigned integer)
14974 template<typename NumberType, typename std::enable_if<
14975 std::is_unsigned<NumberType>::value, int>::type = 0>
14976 void write_number_with_ubjson_prefix(const NumberType n,
14977 const bool add_prefix)
14979 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14983 oa->write_character(to_char_type('i')); // int8
14985 write_number(static_cast<std::uint8_t>(n));
14987 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14991 oa->write_character(to_char_type('U')); // uint8
14993 write_number(static_cast<std::uint8_t>(n));
14995 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14999 oa->write_character(to_char_type('I')); // int16
15001 write_number(static_cast<std::int16_t>(n));
15003 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15007 oa->write_character(to_char_type('l')); // int32
15009 write_number(static_cast<std::int32_t>(n));
15011 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15015 oa->write_character(to_char_type('L')); // int64
15017 write_number(static_cast<std::int64_t>(n));
15023 oa->write_character(to_char_type('H')); // high-precision number
15026 const auto number = BasicJsonType(n).dump();
15027 write_number_with_ubjson_prefix(number.size(), true);
15028 for (std::size_t i = 0; i < number.size(); ++i)
15030 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15035 // UBJSON: write number (signed integer)
15036 template < typename NumberType, typename std::enable_if <
15037 std::is_signed<NumberType>::value&&
15038 !std::is_floating_point<NumberType>::value, int >::type = 0 >
15039 void write_number_with_ubjson_prefix(const NumberType n,
15040 const bool add_prefix)
15042 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
15046 oa->write_character(to_char_type('i')); // int8
15048 write_number(static_cast<std::int8_t>(n));
15050 else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
15054 oa->write_character(to_char_type('U')); // uint8
15056 write_number(static_cast<std::uint8_t>(n));
15058 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
15062 oa->write_character(to_char_type('I')); // int16
15064 write_number(static_cast<std::int16_t>(n));
15066 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
15070 oa->write_character(to_char_type('l')); // int32
15072 write_number(static_cast<std::int32_t>(n));
15074 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
15078 oa->write_character(to_char_type('L')); // int64
15080 write_number(static_cast<std::int64_t>(n));
15087 oa->write_character(to_char_type('H')); // high-precision number
15090 const auto number = BasicJsonType(n).dump();
15091 write_number_with_ubjson_prefix(number.size(), true);
15092 for (std::size_t i = 0; i < number.size(); ++i)
15094 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15101 @brief determine the type prefix of container values
15103 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
15107 case value_t::null:
15110 case value_t::boolean:
15111 return j.m_value.boolean ? 'T' : 'F';
15113 case value_t::number_integer:
15115 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15119 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15123 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15127 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15131 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15135 // anything else is treated as high-precision number
15136 return 'H'; // LCOV_EXCL_LINE
15139 case value_t::number_unsigned:
15141 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15145 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15149 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15153 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15157 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15161 // anything else is treated as high-precision number
15162 return 'H'; // LCOV_EXCL_LINE
15165 case value_t::number_float:
15166 return get_ubjson_float_prefix(j.m_value.number_float);
15168 case value_t::string:
15171 case value_t::array: // fallthrough
15172 case value_t::binary:
15175 case value_t::object:
15178 case value_t::discarded:
15179 default: // discarded values
15184 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15186 return 'd'; // float 32
15189 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15191 return 'D'; // float 64
15194 ///////////////////////
15195 // Utility functions //
15196 ///////////////////////
15199 @brief write a number to output input
15200 @param[in] n number of type @a NumberType
15201 @tparam NumberType the type of the number
15202 @tparam OutputIsLittleEndian Set to true if output data is
15203 required to be little endian
15205 @note This function needs to respect the system's endianness, because bytes
15206 in CBOR, MessagePack, and UBJSON are stored in network order (big
15207 endian) and therefore need reordering on little endian systems.
15209 template<typename NumberType, bool OutputIsLittleEndian = false>
15210 void write_number(const NumberType n)
15212 // step 1: write number to array of length NumberType
15213 std::array<CharType, sizeof(NumberType)> vec{};
15214 std::memcpy(vec.data(), &n, sizeof(NumberType));
15216 // step 2: write array to output (with possible reordering)
15217 if (is_little_endian != OutputIsLittleEndian)
15219 // reverse byte order prior to conversion if necessary
15220 std::reverse(vec.begin(), vec.end());
15223 oa->write_characters(vec.data(), sizeof(NumberType));
15226 void write_compact_float(const number_float_t n, detail::input_format_t format)
15229 #pragma GCC diagnostic push
15230 #pragma GCC diagnostic ignored "-Wfloat-equal"
15232 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
15233 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
15234 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
15236 oa->write_character(format == detail::input_format_t::cbor
15237 ? get_cbor_float_prefix(static_cast<float>(n))
15238 : get_msgpack_float_prefix(static_cast<float>(n)));
15239 write_number(static_cast<float>(n));
15243 oa->write_character(format == detail::input_format_t::cbor
15244 ? get_cbor_float_prefix(n)
15245 : get_msgpack_float_prefix(n));
15249 #pragma GCC diagnostic pop
15254 // The following to_char_type functions are implement the conversion
15255 // between uint8_t and CharType. In case CharType is not unsigned,
15256 // such a conversion is required to allow values greater than 128.
15257 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
15258 template < typename C = CharType,
15259 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
15260 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15262 return *reinterpret_cast<char*>(&x);
15265 template < typename C = CharType,
15266 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
15267 static CharType to_char_type(std::uint8_t x) noexcept
15269 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
15270 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
15272 std::memcpy(&result, &x, sizeof(x));
15276 template<typename C = CharType,
15277 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
15278 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15283 template < typename InputCharType, typename C = CharType,
15285 std::is_signed<C>::value &&
15286 std::is_signed<char>::value &&
15287 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
15289 static constexpr CharType to_char_type(InputCharType x) noexcept
15295 /// whether we can assume little endianness
15296 const bool is_little_endian = little_endianness();
15299 output_adapter_t<CharType> oa = nullptr;
15301 } // namespace detail
15302 } // namespace nlohmann
15304 // #include <nlohmann/detail/output/output_adapters.hpp>
15306 // #include <nlohmann/detail/output/serializer.hpp>
15309 #include <algorithm> // reverse, remove, fill, find, none_of
15310 #include <array> // array
15311 #include <clocale> // localeconv, lconv
15312 #include <cmath> // labs, isfinite, isnan, signbit
15313 #include <cstddef> // size_t, ptrdiff_t
15314 #include <cstdint> // uint8_t
15315 #include <cstdio> // snprintf
15316 #include <limits> // numeric_limits
15317 #include <string> // string, char_traits
15318 #include <iomanip> // setfill, setw
15319 #include <sstream> // stringstream
15320 #include <type_traits> // is_same
15321 #include <utility> // move
15323 // #include <nlohmann/detail/conversions/to_chars.hpp>
15326 #include <array> // array
15327 #include <cmath> // signbit, isfinite
15328 #include <cstdint> // intN_t, uintN_t
15329 #include <cstring> // memcpy, memmove
15330 #include <limits> // numeric_limits
15331 #include <type_traits> // conditional
15333 // #include <nlohmann/detail/macro_scope.hpp>
15342 @brief implements the Grisu2 algorithm for binary to decimal floating-point
15345 This implementation is a slightly modified version of the reference
15346 implementation which may be obtained from
15347 http://florian.loitsch.com/publications (bench.tar.gz).
15349 The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
15351 For a detailed description of the algorithm see:
15353 [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
15354 Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
15355 Language Design and Implementation, PLDI 2010
15356 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
15357 Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
15358 Design and Implementation, PLDI 1996
15360 namespace dtoa_impl
15363 template<typename Target, typename Source>
15364 Target reinterpret_bits(const Source source)
15366 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
15369 std::memcpy(&target, &source, sizeof(Source));
15373 struct diyfp // f * 2^e
15375 static constexpr int kPrecision = 64; // = q
15377 std::uint64_t f = 0;
15380 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
15383 @brief returns x - y
15384 @pre x.e == y.e and x.f >= y.f
15386 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
15388 JSON_ASSERT(x.e == y.e);
15389 JSON_ASSERT(x.f >= y.f);
15391 return {x.f - y.f, x.e};
15395 @brief returns x * y
15396 @note The result is rounded. (Only the upper q bits are returned.)
15398 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
15400 static_assert(kPrecision == 64, "internal error");
15403 // f = round((x.f * y.f) / 2^q)
15404 // e = x.e + y.e + q
15406 // Emulate the 64-bit * 64-bit multiplication:
15409 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15410 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
15411 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
15412 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
15413 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
15414 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
15415 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
15417 // (Since Q might be larger than 2^32 - 1)
15419 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15421 // (Q_hi + H does not overflow a 64-bit int)
15423 // = p_lo + 2^64 p_hi
15425 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15426 const std::uint64_t u_hi = x.f >> 32u;
15427 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15428 const std::uint64_t v_hi = y.f >> 32u;
15430 const std::uint64_t p0 = u_lo * v_lo;
15431 const std::uint64_t p1 = u_lo * v_hi;
15432 const std::uint64_t p2 = u_hi * v_lo;
15433 const std::uint64_t p3 = u_hi * v_hi;
15435 const std::uint64_t p0_hi = p0 >> 32u;
15436 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15437 const std::uint64_t p1_hi = p1 >> 32u;
15438 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15439 const std::uint64_t p2_hi = p2 >> 32u;
15441 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15443 // The full product might now be computed as
15445 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
15446 // p_lo = p0_lo + (Q << 32)
15448 // But in this particular case here, the full p_lo is not required.
15449 // Effectively we only need to add the highest bit in p_lo to p_hi (and
15450 // Q_hi + 1 does not overflow).
15452 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
15454 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15456 return {h, x.e + y.e + 64};
15460 @brief normalize x such that the significand is >= 2^(q-1)
15463 static diyfp normalize(diyfp x) noexcept
15465 JSON_ASSERT(x.f != 0);
15467 while ((x.f >> 63u) == 0)
15477 @brief normalize x such that the result has the exponent E
15478 @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
15480 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
15482 const int delta = x.e - target_exponent;
15484 JSON_ASSERT(delta >= 0);
15485 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
15487 return {x.f << delta, target_exponent};
15499 Compute the (normalized) diyfp representing the input number 'value' and its
15502 @pre value must be finite and positive
15504 template<typename FloatType>
15505 boundaries compute_boundaries(FloatType value)
15507 JSON_ASSERT(std::isfinite(value));
15508 JSON_ASSERT(value > 0);
15510 // Convert the IEEE representation into a diyfp.
15512 // If v is denormal:
15513 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
15514 // If v is normalized:
15515 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
15517 static_assert(std::numeric_limits<FloatType>::is_iec559,
15518 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
15520 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
15521 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
15522 constexpr int kMinExp = 1 - kBias;
15523 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
15525 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
15527 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
15528 const std::uint64_t E = bits >> (kPrecision - 1);
15529 const std::uint64_t F = bits & (kHiddenBit - 1);
15531 const bool is_denormal = E == 0;
15532 const diyfp v = is_denormal
15533 ? diyfp(F, kMinExp)
15534 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
15536 // Compute the boundaries m- and m+ of the floating-point value
15539 // Determine v- and v+, the floating-point predecessor and successor if v,
15542 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
15543 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
15547 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
15548 // between m- and m+ round to v, regardless of how the input rounding
15549 // algorithm breaks ties.
15551 // ---+-------------+-------------+-------------+-------------+--- (A)
15554 // -----------------+------+------+-------------+-------------+--- (B)
15557 const bool lower_boundary_is_closer = F == 0 && E > 1;
15558 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
15559 const diyfp m_minus = lower_boundary_is_closer
15560 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
15561 : diyfp(2 * v.f - 1, v.e - 1); // (A)
15563 // Determine the normalized w+ = m+.
15564 const diyfp w_plus = diyfp::normalize(m_plus);
15566 // Determine w- = m- such that e_(w-) = e_(w+).
15567 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
15569 return {diyfp::normalize(v), w_minus, w_plus};
15572 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
15573 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
15574 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
15576 // alpha <= e = e_c + e_w + q <= gamma
15580 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
15581 // <= f_c * f_w * 2^gamma
15583 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
15585 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
15589 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
15591 // The choice of (alpha,gamma) determines the size of the table and the form of
15592 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
15595 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
15596 // processed independently: An integral part p1, and a fractional part p2:
15598 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
15599 // = (f div 2^-e) + (f mod 2^-e) * 2^e
15602 // The conversion of p1 into decimal form requires a series of divisions and
15603 // modulos by (a power of) 10. These operations are faster for 32-bit than for
15604 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
15605 // achieved by choosing
15607 // -e >= 32 or e <= -32 := gamma
15609 // In order to convert the fractional part
15611 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
15613 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
15614 // d[-i] are extracted in order:
15616 // (10 * p2) div 2^-e = d[-1]
15617 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
15619 // The multiplication by 10 must not overflow. It is sufficient to choose
15621 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
15623 // Since p2 = f mod 2^-e < 2^-e,
15625 // -e <= 60 or e >= -60 := alpha
15627 constexpr int kAlpha = -60;
15628 constexpr int kGamma = -32;
15630 struct cached_power // c = f * 2^e ~= 10^k
15638 For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
15639 power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
15640 satisfies (Definition 3.2 from [1])
15642 alpha <= e_c + e + q <= gamma.
15644 inline cached_power get_cached_power_for_binary_exponent(int e)
15648 // alpha <= e_c + e + q <= gamma (1)
15649 // ==> f_c * 2^alpha <= c * 2^e * 2^q
15651 // and since the c's are normalized, 2^(q-1) <= f_c,
15653 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
15654 // ==> 2^(alpha - e - 1) <= c
15656 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
15658 // k = ceil( log_10( 2^(alpha - e - 1) ) )
15659 // = ceil( (alpha - e - 1) * log_10(2) )
15662 // "In theory the result of the procedure could be wrong since c is rounded,
15663 // and the computation itself is approximated [...]. In practice, however,
15664 // this simple function is sufficient."
15666 // For IEEE double precision floating-point numbers converted into
15667 // normalized diyfp's w = f * 2^e, with q = 64,
15669 // e >= -1022 (min IEEE exponent)
15671 // -52 (p - 1, possibly normalize denormal IEEE numbers)
15672 // -11 (normalize the diyfp)
15677 // e <= +1023 (max IEEE exponent)
15679 // -11 (normalize the diyfp)
15682 // This binary exponent range [-1137,960] results in a decimal exponent
15683 // range [-307,324]. One does not need to store a cached power for each
15684 // k in this range. For each such k it suffices to find a cached power
15685 // such that the exponent of the product lies in [alpha,gamma].
15686 // This implies that the difference of the decimal exponents of adjacent
15687 // table entries must be less than or equal to
15689 // floor( (gamma - alpha) * log_10(2) ) = 8.
15691 // (A smaller distance gamma-alpha would require a larger table.)
15694 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
15696 constexpr int kCachedPowersMinDecExp = -300;
15697 constexpr int kCachedPowersDecStep = 8;
15699 static constexpr std::array<cached_power, 79> kCachedPowers =
15702 { 0xAB70FE17C79AC6CA, -1060, -300 },
15703 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
15704 { 0xBE5691EF416BD60C, -1007, -284 },
15705 { 0x8DD01FAD907FFC3C, -980, -276 },
15706 { 0xD3515C2831559A83, -954, -268 },
15707 { 0x9D71AC8FADA6C9B5, -927, -260 },
15708 { 0xEA9C227723EE8BCB, -901, -252 },
15709 { 0xAECC49914078536D, -874, -244 },
15710 { 0x823C12795DB6CE57, -847, -236 },
15711 { 0xC21094364DFB5637, -821, -228 },
15712 { 0x9096EA6F3848984F, -794, -220 },
15713 { 0xD77485CB25823AC7, -768, -212 },
15714 { 0xA086CFCD97BF97F4, -741, -204 },
15715 { 0xEF340A98172AACE5, -715, -196 },
15716 { 0xB23867FB2A35B28E, -688, -188 },
15717 { 0x84C8D4DFD2C63F3B, -661, -180 },
15718 { 0xC5DD44271AD3CDBA, -635, -172 },
15719 { 0x936B9FCEBB25C996, -608, -164 },
15720 { 0xDBAC6C247D62A584, -582, -156 },
15721 { 0xA3AB66580D5FDAF6, -555, -148 },
15722 { 0xF3E2F893DEC3F126, -529, -140 },
15723 { 0xB5B5ADA8AAFF80B8, -502, -132 },
15724 { 0x87625F056C7C4A8B, -475, -124 },
15725 { 0xC9BCFF6034C13053, -449, -116 },
15726 { 0x964E858C91BA2655, -422, -108 },
15727 { 0xDFF9772470297EBD, -396, -100 },
15728 { 0xA6DFBD9FB8E5B88F, -369, -92 },
15729 { 0xF8A95FCF88747D94, -343, -84 },
15730 { 0xB94470938FA89BCF, -316, -76 },
15731 { 0x8A08F0F8BF0F156B, -289, -68 },
15732 { 0xCDB02555653131B6, -263, -60 },
15733 { 0x993FE2C6D07B7FAC, -236, -52 },
15734 { 0xE45C10C42A2B3B06, -210, -44 },
15735 { 0xAA242499697392D3, -183, -36 },
15736 { 0xFD87B5F28300CA0E, -157, -28 },
15737 { 0xBCE5086492111AEB, -130, -20 },
15738 { 0x8CBCCC096F5088CC, -103, -12 },
15739 { 0xD1B71758E219652C, -77, -4 },
15740 { 0x9C40000000000000, -50, 4 },
15741 { 0xE8D4A51000000000, -24, 12 },
15742 { 0xAD78EBC5AC620000, 3, 20 },
15743 { 0x813F3978F8940984, 30, 28 },
15744 { 0xC097CE7BC90715B3, 56, 36 },
15745 { 0x8F7E32CE7BEA5C70, 83, 44 },
15746 { 0xD5D238A4ABE98068, 109, 52 },
15747 { 0x9F4F2726179A2245, 136, 60 },
15748 { 0xED63A231D4C4FB27, 162, 68 },
15749 { 0xB0DE65388CC8ADA8, 189, 76 },
15750 { 0x83C7088E1AAB65DB, 216, 84 },
15751 { 0xC45D1DF942711D9A, 242, 92 },
15752 { 0x924D692CA61BE758, 269, 100 },
15753 { 0xDA01EE641A708DEA, 295, 108 },
15754 { 0xA26DA3999AEF774A, 322, 116 },
15755 { 0xF209787BB47D6B85, 348, 124 },
15756 { 0xB454E4A179DD1877, 375, 132 },
15757 { 0x865B86925B9BC5C2, 402, 140 },
15758 { 0xC83553C5C8965D3D, 428, 148 },
15759 { 0x952AB45CFA97A0B3, 455, 156 },
15760 { 0xDE469FBD99A05FE3, 481, 164 },
15761 { 0xA59BC234DB398C25, 508, 172 },
15762 { 0xF6C69A72A3989F5C, 534, 180 },
15763 { 0xB7DCBF5354E9BECE, 561, 188 },
15764 { 0x88FCF317F22241E2, 588, 196 },
15765 { 0xCC20CE9BD35C78A5, 614, 204 },
15766 { 0x98165AF37B2153DF, 641, 212 },
15767 { 0xE2A0B5DC971F303A, 667, 220 },
15768 { 0xA8D9D1535CE3B396, 694, 228 },
15769 { 0xFB9B7CD9A4A7443C, 720, 236 },
15770 { 0xBB764C4CA7A44410, 747, 244 },
15771 { 0x8BAB8EEFB6409C1A, 774, 252 },
15772 { 0xD01FEF10A657842C, 800, 260 },
15773 { 0x9B10A4E5E9913129, 827, 268 },
15774 { 0xE7109BFBA19C0C9D, 853, 276 },
15775 { 0xAC2820D9623BF429, 880, 284 },
15776 { 0x80444B5E7AA7CF85, 907, 292 },
15777 { 0xBF21E44003ACDD2D, 933, 300 },
15778 { 0x8E679C2F5E44FF8F, 960, 308 },
15779 { 0xD433179D9C8CB841, 986, 316 },
15780 { 0x9E19DB92B4E31BA9, 1013, 324 },
15784 // This computation gives exactly the same results for k as
15785 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
15786 // for |e| <= 1500, but doesn't require floating-point operations.
15787 // NB: log_10(2) ~= 78913 / 2^18
15788 JSON_ASSERT(e >= -1500);
15789 JSON_ASSERT(e <= 1500);
15790 const int f = kAlpha - e - 1;
15791 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
15793 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
15794 JSON_ASSERT(index >= 0);
15795 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
15797 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
15798 JSON_ASSERT(kAlpha <= cached.e + e + 64);
15799 JSON_ASSERT(kGamma >= cached.e + e + 64);
15805 For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
15806 For n == 0, returns 1 and sets pow10 := 1.
15808 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
15811 if (n >= 1000000000)
15813 pow10 = 1000000000;
15817 if (n >= 100000000)
15862 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
15863 std::uint64_t rest, std::uint64_t ten_k)
15865 JSON_ASSERT(len >= 1);
15866 JSON_ASSERT(dist <= delta);
15867 JSON_ASSERT(rest <= delta);
15868 JSON_ASSERT(ten_k > 0);
15870 // <--------------------------- delta ---->
15871 // <---- dist --------->
15872 // --------------[------------------+-------------------]--------------
15877 // <---- rest ---->
15878 // --------------[------------------+----+--------------]--------------
15882 // ten_k represents a unit-in-the-last-place in the decimal representation
15884 // Decrement buf by ten_k while this takes buf closer to w.
15886 // The tests are written in this order to avoid overflow in unsigned
15887 // integer arithmetic.
15890 && delta - rest >= ten_k
15891 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
15893 JSON_ASSERT(buf[len - 1] != '0');
15900 Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
15901 M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
15903 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
15904 diyfp M_minus, diyfp w, diyfp M_plus)
15906 static_assert(kAlpha >= -60, "internal error");
15907 static_assert(kGamma <= -32, "internal error");
15909 // Generates the digits (and the exponent) of a decimal floating-point
15910 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15911 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15913 // <--------------------------- delta ---->
15914 // <---- dist --------->
15915 // --------------[------------------+-------------------]--------------
15918 // Grisu2 generates the digits of M+ from left to right and stops as soon as
15919 // V is in [M-,M+].
15921 JSON_ASSERT(M_plus.e >= kAlpha);
15922 JSON_ASSERT(M_plus.e <= kGamma);
15924 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15925 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
15927 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15930 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15931 // = ((p1 ) * 2^-e + (p2 )) * 2^e
15934 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15936 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.)
15937 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
15941 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15943 JSON_ASSERT(p1 > 0);
15945 std::uint32_t pow10{};
15946 const int k = find_largest_pow10(p1, pow10);
15948 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15950 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15951 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
15953 // M+ = p1 + p2 * 2^e
15954 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
15955 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15956 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
15958 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15960 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15962 // but stop as soon as
15964 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15970 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
15971 // pow10 = 10^(n-1) <= p1 < 10^n
15973 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
15974 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
15976 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15977 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15979 JSON_ASSERT(d <= 9);
15980 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15982 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15987 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
15991 // Now check if enough digits have been generated.
15994 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15997 // Since rest and delta share the same exponent e, it suffices to
15998 // compare the significands.
15999 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
16002 // V = buffer * 10^n, with M- <= V <= M+.
16004 decimal_exponent += n;
16006 // We may now just stop. But instead look if the buffer could be
16007 // decremented to bring V closer to w.
16009 // pow10 = 10^n is now 1 ulp in the decimal representation V.
16010 // The rounding procedure works with diyfp's with an implicit
16013 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
16015 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
16016 grisu2_round(buffer, length, dist, delta, rest, ten_n);
16023 // pow10 = 10^(n-1) <= p1 < 10^n
16024 // Invariants restored.
16029 // The digits of the integral part have been generated:
16031 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
16032 // = buffer + p2 * 2^e
16034 // Now generate the digits of the fractional part p2 * 2^e.
16037 // No decimal point is generated: the exponent is adjusted instead.
16039 // p2 actually represents the fraction
16043 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
16045 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
16047 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
16048 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
16052 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
16053 // = ( d) * 2^-e + ( r)
16056 // 10^m * p2 * 2^e = d + r * 2^e
16060 // M+ = buffer + p2 * 2^e
16061 // = buffer + 10^-m * (d + r * 2^e)
16062 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
16064 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
16066 JSON_ASSERT(p2 > delta);
16072 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
16073 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
16074 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
16075 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
16077 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
16079 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
16080 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
16082 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
16083 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
16084 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
16086 JSON_ASSERT(d <= 9);
16087 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16089 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
16094 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
16095 // Invariant restored.
16097 // Check if enough digits have been generated.
16099 // 10^-m * p2 * 2^e <= delta * 2^e
16100 // p2 * 2^e <= 10^m * delta * 2^e
16101 // p2 <= 10^m * delta
16110 // V = buffer * 10^-m, with M- <= V <= M+.
16112 decimal_exponent -= m;
16114 // 1 ulp in the decimal representation is now 10^-m.
16115 // Since delta and dist are now scaled by 10^m, we need to do the
16116 // same with ulp in order to keep the units in sync.
16118 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16120 const std::uint64_t ten_m = one.f;
16121 grisu2_round(buffer, length, dist, delta, p2, ten_m);
16123 // By construction this algorithm generates the shortest possible decimal
16124 // number (Loitsch, Theorem 6.2) which rounds back to w.
16125 // For an input number of precision p, at least
16127 // N = 1 + ceil(p * log_10(2))
16129 // decimal digits are sufficient to identify all binary floating-point
16130 // numbers (Matula, "In-and-Out conversions").
16131 // This implies that the algorithm does not produce more than N decimal
16134 // N = 17 for p = 53 (IEEE double precision)
16135 // N = 9 for p = 24 (IEEE single precision)
16139 v = buf * 10^decimal_exponent
16140 len is the length of the buffer (number of decimal digits)
16141 The buffer must be large enough, i.e. >= max_digits10.
16143 JSON_HEDLEY_NON_NULL(1)
16144 inline void grisu2(char* buf, int& len, int& decimal_exponent,
16145 diyfp m_minus, diyfp v, diyfp m_plus)
16147 JSON_ASSERT(m_plus.e == m_minus.e);
16148 JSON_ASSERT(m_plus.e == v.e);
16150 // --------(-----------------------+-----------------------)-------- (A)
16153 // --------------------(-----------+-----------------------)-------- (B)
16156 // First scale v (and m- and m+) such that the exponent is in the range
16159 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
16161 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
16163 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
16164 const diyfp w = diyfp::mul(v, c_minus_k);
16165 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
16166 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
16168 // ----(---+---)---------------(---+---)---------------(---+---)----
16170 // = c*m- = c*v = c*m+
16172 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
16173 // w+ are now off by a small amount.
16176 // w - v * 10^k < 1 ulp
16178 // To account for this inaccuracy, add resp. subtract 1 ulp.
16180 // --------+---[---------------(---+---)---------------]---+--------
16183 // Now any number in [M-, M+] (bounds included) will round to w when input,
16184 // regardless of how the input rounding algorithm breaks ties.
16186 // And digit_gen generates the shortest possible such number in [M-, M+].
16187 // Note that this does not mean that Grisu2 always generates the shortest
16188 // possible number in the interval (m-, m+).
16189 const diyfp M_minus(w_minus.f + 1, w_minus.e);
16190 const diyfp M_plus (w_plus.f - 1, w_plus.e );
16192 decimal_exponent = -cached.k; // = -(-k) = k
16194 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
16198 v = buf * 10^decimal_exponent
16199 len is the length of the buffer (number of decimal digits)
16200 The buffer must be large enough, i.e. >= max_digits10.
16202 template<typename FloatType>
16203 JSON_HEDLEY_NON_NULL(1)
16204 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
16206 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
16207 "internal error: not enough precision");
16209 JSON_ASSERT(std::isfinite(value));
16210 JSON_ASSERT(value > 0);
16212 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
16213 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
16214 // decimal representations are not exactly "short".
16216 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
16217 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
16218 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
16220 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
16221 // representation using the corresponding std::from_chars function recovers value exactly". That
16222 // indicates that single precision floating-point numbers should be recovered using
16225 // NB: If the neighbors are computed for single-precision numbers, there is a single float
16226 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
16227 // value is off by 1 ulp.
16229 const boundaries w = compute_boundaries(static_cast<double>(value));
16231 const boundaries w = compute_boundaries(value);
16234 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
16238 @brief appends a decimal representation of e to buf
16239 @return a pointer to the element following the exponent.
16240 @pre -1000 < e < 1000
16242 JSON_HEDLEY_NON_NULL(1)
16243 JSON_HEDLEY_RETURNS_NON_NULL
16244 inline char* append_exponent(char* buf, int e)
16246 JSON_ASSERT(e > -1000);
16247 JSON_ASSERT(e < 1000);
16259 auto k = static_cast<std::uint32_t>(e);
16262 // Always print at least two digits in the exponent.
16263 // This is for compatibility with printf("%g").
16265 *buf++ = static_cast<char>('0' + k);
16269 *buf++ = static_cast<char>('0' + k / 10);
16271 *buf++ = static_cast<char>('0' + k);
16275 *buf++ = static_cast<char>('0' + k / 100);
16277 *buf++ = static_cast<char>('0' + k / 10);
16279 *buf++ = static_cast<char>('0' + k);
16286 @brief prettify v = buf * 10^decimal_exponent
16288 If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
16289 notation. Otherwise it will be printed in exponential notation.
16294 JSON_HEDLEY_NON_NULL(1)
16295 JSON_HEDLEY_RETURNS_NON_NULL
16296 inline char* format_buffer(char* buf, int len, int decimal_exponent,
16297 int min_exp, int max_exp)
16299 JSON_ASSERT(min_exp < 0);
16300 JSON_ASSERT(max_exp > 0);
16303 const int n = len + decimal_exponent;
16305 // v = buf * 10^(n-k)
16306 // k is the length of the buffer (number of decimal digits)
16307 // n is the position of the decimal point relative to the start of the buffer.
16309 if (k <= n && n <= max_exp)
16312 // len <= max_exp + 2
16314 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
16315 // Make it look like a floating-point number (#362, #378)
16318 return buf + (static_cast<size_t>(n) + 2);
16321 if (0 < n && n <= max_exp)
16324 // len <= max_digits10 + 1
16326 JSON_ASSERT(k > n);
16328 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
16330 return buf + (static_cast<size_t>(k) + 1U);
16333 if (min_exp < n && n <= 0)
16336 // len <= 2 + (-min_exp - 1) + max_digits10
16338 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
16341 std::memset(buf + 2, '0', static_cast<size_t>(-n));
16342 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
16355 // len <= max_digits10 + 1 + 5
16357 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
16359 buf += 1 + static_cast<size_t>(k);
16363 return append_exponent(buf, n - 1);
16366 } // namespace dtoa_impl
16369 @brief generates a decimal representation of the floating-point number value in [first, last).
16371 The format of the resulting decimal representation is similar to printf's %g
16372 format. Returns an iterator pointing past-the-end of the decimal representation.
16374 @note The input number must be finite, i.e. NaN's and Inf's are not supported.
16375 @note The buffer must be large enough.
16376 @note The result is NOT null-terminated.
16378 template<typename FloatType>
16379 JSON_HEDLEY_NON_NULL(1, 2)
16380 JSON_HEDLEY_RETURNS_NON_NULL
16381 char* to_chars(char* first, const char* last, FloatType value)
16383 static_cast<void>(last); // maybe unused - fix warning
16384 JSON_ASSERT(std::isfinite(value));
16386 // Use signbit(value) instead of (value < 0) since signbit works for -0.
16387 if (std::signbit(value))
16394 #pragma GCC diagnostic push
16395 #pragma GCC diagnostic ignored "-Wfloat-equal"
16397 if (value == 0) // +-0
16400 // Make it look like a floating-point number (#362, #378)
16406 #pragma GCC diagnostic pop
16409 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
16411 // Compute v = buffer * 10^decimal_exponent.
16412 // The decimal digits are stored in the buffer, which needs to be interpreted
16413 // as an unsigned decimal integer.
16414 // len is the length of the buffer, i.e. the number of decimal digits.
16416 int decimal_exponent = 0;
16417 dtoa_impl::grisu2(first, len, decimal_exponent, value);
16419 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
16421 // Format the buffer like printf("%.*g", prec, value)
16422 constexpr int kMinExp = -4;
16423 // Use digits10 here to increase compatibility with version 2.
16424 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
16426 JSON_ASSERT(last - first >= kMaxExp + 2);
16427 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
16428 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
16430 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
16433 } // namespace detail
16434 } // namespace nlohmann
16436 // #include <nlohmann/detail/exceptions.hpp>
16438 // #include <nlohmann/detail/macro_scope.hpp>
16440 // #include <nlohmann/detail/meta/cpp_future.hpp>
16442 // #include <nlohmann/detail/output/binary_writer.hpp>
16444 // #include <nlohmann/detail/output/output_adapters.hpp>
16446 // #include <nlohmann/detail/value_t.hpp>
16453 ///////////////////
16454 // serialization //
16455 ///////////////////
16457 /// how to treat decoding errors
16458 enum class error_handler_t
16460 strict, ///< throw a type_error exception in case of invalid UTF-8
16461 replace, ///< replace invalid UTF-8 sequences with U+FFFD
16462 ignore ///< ignore invalid UTF-8 sequences
16465 template<typename BasicJsonType>
16468 using string_t = typename BasicJsonType::string_t;
16469 using number_float_t = typename BasicJsonType::number_float_t;
16470 using number_integer_t = typename BasicJsonType::number_integer_t;
16471 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
16472 using binary_char_t = typename BasicJsonType::binary_t::value_type;
16473 static constexpr std::uint8_t UTF8_ACCEPT = 0;
16474 static constexpr std::uint8_t UTF8_REJECT = 1;
16478 @param[in] s output stream to serialize to
16479 @param[in] ichar indentation character to use
16480 @param[in] error_handler_ how to react on decoding errors
16482 serializer(output_adapter_t<char> s, const char ichar,
16483 error_handler_t error_handler_ = error_handler_t::strict)
16485 , loc(std::localeconv())
16486 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
16487 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
16488 , indent_char(ichar)
16489 , indent_string(512, indent_char)
16490 , error_handler(error_handler_)
16493 // delete because of pointer members
16494 serializer(const serializer&) = delete;
16495 serializer& operator=(const serializer&) = delete;
16496 serializer(serializer&&) = delete;
16497 serializer& operator=(serializer&&) = delete;
16498 ~serializer() = default;
16501 @brief internal implementation of the serialization function
16503 This function is called by the public member function dump and organizes
16504 the serialization internally. The indentation level is propagated as
16505 additional parameter. In case of arrays and objects, the function is
16506 called recursively.
16508 - strings and object keys are escaped using `escape_string()`
16509 - integer numbers are converted implicitly via `operator<<`
16510 - floating-point numbers are converted to a string using `"%g"` format
16511 - binary values are serialized as objects containing the subtype and the
16514 @param[in] val value to serialize
16515 @param[in] pretty_print whether the output shall be pretty-printed
16516 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
16517 in the output are escaped with `\uXXXX` sequences, and the result consists
16518 of ASCII characters only.
16519 @param[in] indent_step the indent level
16520 @param[in] current_indent the current indent level (only used internally)
16522 void dump(const BasicJsonType& val,
16523 const bool pretty_print,
16524 const bool ensure_ascii,
16525 const unsigned int indent_step,
16526 const unsigned int current_indent = 0)
16528 switch (val.m_type)
16530 case value_t::object:
16532 if (val.m_value.object->empty())
16534 o->write_characters("{}", 2);
16540 o->write_characters("{\n", 2);
16542 // variable to hold indentation for recursive calls
16543 const auto new_indent = current_indent + indent_step;
16544 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16546 indent_string.resize(indent_string.size() * 2, ' ');
16549 // first n-1 elements
16550 auto i = val.m_value.object->cbegin();
16551 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16553 o->write_characters(indent_string.c_str(), new_indent);
16554 o->write_character('\"');
16555 dump_escaped(i->first, ensure_ascii);
16556 o->write_characters("\": ", 3);
16557 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16558 o->write_characters(",\n", 2);
16562 JSON_ASSERT(i != val.m_value.object->cend());
16563 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16564 o->write_characters(indent_string.c_str(), new_indent);
16565 o->write_character('\"');
16566 dump_escaped(i->first, ensure_ascii);
16567 o->write_characters("\": ", 3);
16568 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16570 o->write_character('\n');
16571 o->write_characters(indent_string.c_str(), current_indent);
16572 o->write_character('}');
16576 o->write_character('{');
16578 // first n-1 elements
16579 auto i = val.m_value.object->cbegin();
16580 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16582 o->write_character('\"');
16583 dump_escaped(i->first, ensure_ascii);
16584 o->write_characters("\":", 2);
16585 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16586 o->write_character(',');
16590 JSON_ASSERT(i != val.m_value.object->cend());
16591 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16592 o->write_character('\"');
16593 dump_escaped(i->first, ensure_ascii);
16594 o->write_characters("\":", 2);
16595 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16597 o->write_character('}');
16603 case value_t::array:
16605 if (val.m_value.array->empty())
16607 o->write_characters("[]", 2);
16613 o->write_characters("[\n", 2);
16615 // variable to hold indentation for recursive calls
16616 const auto new_indent = current_indent + indent_step;
16617 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16619 indent_string.resize(indent_string.size() * 2, ' ');
16622 // first n-1 elements
16623 for (auto i = val.m_value.array->cbegin();
16624 i != val.m_value.array->cend() - 1; ++i)
16626 o->write_characters(indent_string.c_str(), new_indent);
16627 dump(*i, true, ensure_ascii, indent_step, new_indent);
16628 o->write_characters(",\n", 2);
16632 JSON_ASSERT(!val.m_value.array->empty());
16633 o->write_characters(indent_string.c_str(), new_indent);
16634 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
16636 o->write_character('\n');
16637 o->write_characters(indent_string.c_str(), current_indent);
16638 o->write_character(']');
16642 o->write_character('[');
16644 // first n-1 elements
16645 for (auto i = val.m_value.array->cbegin();
16646 i != val.m_value.array->cend() - 1; ++i)
16648 dump(*i, false, ensure_ascii, indent_step, current_indent);
16649 o->write_character(',');
16653 JSON_ASSERT(!val.m_value.array->empty());
16654 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
16656 o->write_character(']');
16662 case value_t::string:
16664 o->write_character('\"');
16665 dump_escaped(*val.m_value.string, ensure_ascii);
16666 o->write_character('\"');
16670 case value_t::binary:
16674 o->write_characters("{\n", 2);
16676 // variable to hold indentation for recursive calls
16677 const auto new_indent = current_indent + indent_step;
16678 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16680 indent_string.resize(indent_string.size() * 2, ' ');
16683 o->write_characters(indent_string.c_str(), new_indent);
16685 o->write_characters("\"bytes\": [", 10);
16687 if (!val.m_value.binary->empty())
16689 for (auto i = val.m_value.binary->cbegin();
16690 i != val.m_value.binary->cend() - 1; ++i)
16693 o->write_characters(", ", 2);
16695 dump_integer(val.m_value.binary->back());
16698 o->write_characters("],\n", 3);
16699 o->write_characters(indent_string.c_str(), new_indent);
16701 o->write_characters("\"subtype\": ", 11);
16702 if (val.m_value.binary->has_subtype())
16704 dump_integer(val.m_value.binary->subtype());
16708 o->write_characters("null", 4);
16710 o->write_character('\n');
16711 o->write_characters(indent_string.c_str(), current_indent);
16712 o->write_character('}');
16716 o->write_characters("{\"bytes\":[", 10);
16718 if (!val.m_value.binary->empty())
16720 for (auto i = val.m_value.binary->cbegin();
16721 i != val.m_value.binary->cend() - 1; ++i)
16724 o->write_character(',');
16726 dump_integer(val.m_value.binary->back());
16729 o->write_characters("],\"subtype\":", 12);
16730 if (val.m_value.binary->has_subtype())
16732 dump_integer(val.m_value.binary->subtype());
16733 o->write_character('}');
16737 o->write_characters("null}", 5);
16743 case value_t::boolean:
16745 if (val.m_value.boolean)
16747 o->write_characters("true", 4);
16751 o->write_characters("false", 5);
16756 case value_t::number_integer:
16758 dump_integer(val.m_value.number_integer);
16762 case value_t::number_unsigned:
16764 dump_integer(val.m_value.number_unsigned);
16768 case value_t::number_float:
16770 dump_float(val.m_value.number_float);
16774 case value_t::discarded:
16776 o->write_characters("<discarded>", 11);
16780 case value_t::null:
16782 o->write_characters("null", 4);
16786 default: // LCOV_EXCL_LINE
16787 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16791 JSON_PRIVATE_UNLESS_TESTED:
16793 @brief dump escaped string
16795 Escape a string by replacing certain special characters by a sequence of an
16796 escape character (backslash) and another character and other control
16797 characters by a sequence of "\u" followed by a four-digit hex
16798 representation. The escaped string is written to output stream @a o.
16800 @param[in] s the string to escape
16801 @param[in] ensure_ascii whether to escape non-ASCII characters with
16804 @complexity Linear in the length of string @a s.
16806 void dump_escaped(const string_t& s, const bool ensure_ascii)
16808 std::uint32_t codepoint{};
16809 std::uint8_t state = UTF8_ACCEPT;
16810 std::size_t bytes = 0; // number of bytes written to string_buffer
16812 // number of bytes written at the point of the last valid byte
16813 std::size_t bytes_after_last_accept = 0;
16814 std::size_t undumped_chars = 0;
16816 for (std::size_t i = 0; i < s.size(); ++i)
16818 const auto byte = static_cast<std::uint8_t>(s[i]);
16820 switch (decode(state, codepoint, byte))
16822 case UTF8_ACCEPT: // decode found a new code point
16826 case 0x08: // backspace
16828 string_buffer[bytes++] = '\\';
16829 string_buffer[bytes++] = 'b';
16833 case 0x09: // horizontal tab
16835 string_buffer[bytes++] = '\\';
16836 string_buffer[bytes++] = 't';
16840 case 0x0A: // newline
16842 string_buffer[bytes++] = '\\';
16843 string_buffer[bytes++] = 'n';
16847 case 0x0C: // formfeed
16849 string_buffer[bytes++] = '\\';
16850 string_buffer[bytes++] = 'f';
16854 case 0x0D: // carriage return
16856 string_buffer[bytes++] = '\\';
16857 string_buffer[bytes++] = 'r';
16861 case 0x22: // quotation mark
16863 string_buffer[bytes++] = '\\';
16864 string_buffer[bytes++] = '\"';
16868 case 0x5C: // reverse solidus
16870 string_buffer[bytes++] = '\\';
16871 string_buffer[bytes++] = '\\';
16877 // escape control characters (0x00..0x1F) or, if
16878 // ensure_ascii parameter is used, non-ASCII characters
16879 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
16881 if (codepoint <= 0xFFFF)
16883 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16884 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
16885 static_cast<std::uint16_t>(codepoint));
16890 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16891 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
16892 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
16893 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
16899 // copy byte to buffer (all previous bytes
16900 // been copied have in default case above)
16901 string_buffer[bytes++] = s[i];
16907 // write buffer and reset index; there must be 13 bytes
16908 // left, as this is the maximal number of bytes to be
16909 // written ("\uxxxx\uxxxx\0") for one code point
16910 if (string_buffer.size() - bytes < 13)
16912 o->write_characters(string_buffer.data(), bytes);
16916 // remember the byte position of this accept
16917 bytes_after_last_accept = bytes;
16918 undumped_chars = 0;
16922 case UTF8_REJECT: // decode found invalid UTF-8 byte
16924 switch (error_handler)
16926 case error_handler_t::strict:
16928 std::stringstream ss;
16929 ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (byte | 0);
16930 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + ss.str(), BasicJsonType()));
16933 case error_handler_t::ignore:
16934 case error_handler_t::replace:
16936 // in case we saw this character the first time, we
16937 // would like to read it again, because the byte
16938 // may be OK for itself, but just not OK for the
16939 // previous sequence
16940 if (undumped_chars > 0)
16945 // reset length buffer to the last accepted index;
16946 // thus removing/ignoring the invalid characters
16947 bytes = bytes_after_last_accept;
16949 if (error_handler == error_handler_t::replace)
16951 // add a replacement character
16954 string_buffer[bytes++] = '\\';
16955 string_buffer[bytes++] = 'u';
16956 string_buffer[bytes++] = 'f';
16957 string_buffer[bytes++] = 'f';
16958 string_buffer[bytes++] = 'f';
16959 string_buffer[bytes++] = 'd';
16963 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
16964 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
16965 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
16968 // write buffer and reset index; there must be 13 bytes
16969 // left, as this is the maximal number of bytes to be
16970 // written ("\uxxxx\uxxxx\0") for one code point
16971 if (string_buffer.size() - bytes < 13)
16973 o->write_characters(string_buffer.data(), bytes);
16977 bytes_after_last_accept = bytes;
16980 undumped_chars = 0;
16982 // continue processing the string
16983 state = UTF8_ACCEPT;
16987 default: // LCOV_EXCL_LINE
16988 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16993 default: // decode found yet incomplete multi-byte code point
16997 // code point will not be escaped - copy byte to buffer
16998 string_buffer[bytes++] = s[i];
17006 // we finished processing the string
17007 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
17012 o->write_characters(string_buffer.data(), bytes);
17017 // we finish reading, but do not accept: string was incomplete
17018 switch (error_handler)
17020 case error_handler_t::strict:
17022 std::stringstream ss;
17023 ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (static_cast<std::uint8_t>(s.back()) | 0);
17024 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + ss.str(), BasicJsonType()));
17027 case error_handler_t::ignore:
17029 // write all accepted bytes
17030 o->write_characters(string_buffer.data(), bytes_after_last_accept);
17034 case error_handler_t::replace:
17036 // write all accepted bytes
17037 o->write_characters(string_buffer.data(), bytes_after_last_accept);
17038 // add a replacement character
17041 o->write_characters("\\ufffd", 6);
17045 o->write_characters("\xEF\xBF\xBD", 3);
17050 default: // LCOV_EXCL_LINE
17051 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17058 @brief count digits
17060 Count the number of decimal (base 10) digits for an input unsigned integer.
17062 @param[in] x unsigned integer number to count its digits
17063 @return number of decimal digits
17065 inline unsigned int count_digits(number_unsigned_t x) noexcept
17067 unsigned int n_digits = 1;
17076 return n_digits + 1;
17080 return n_digits + 2;
17084 return n_digits + 3;
17092 @brief dump an integer
17094 Dump a given integer to output stream @a o. Works internally with
17097 @param[in] x integer number (signed or unsigned) to dump
17098 @tparam NumberType either @a number_integer_t or @a number_unsigned_t
17100 template < typename NumberType, detail::enable_if_t <
17101 std::is_integral<NumberType>::value ||
17102 std::is_same<NumberType, number_unsigned_t>::value ||
17103 std::is_same<NumberType, number_integer_t>::value ||
17104 std::is_same<NumberType, binary_char_t>::value,
17106 void dump_integer(NumberType x)
17108 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
17111 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
17112 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
17113 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
17114 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
17115 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
17116 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17117 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17118 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17119 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17120 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17124 // special case for "0"
17127 o->write_character('0');
17131 // use a pointer to fill the buffer
17132 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17134 const bool is_negative = std::is_signed<NumberType>::value && !(x >= 0); // see issue #755
17135 number_unsigned_t abs_value;
17137 unsigned int n_chars{};
17142 abs_value = remove_sign(static_cast<number_integer_t>(x));
17144 // account one more byte for the minus sign
17145 n_chars = 1 + count_digits(abs_value);
17149 abs_value = static_cast<number_unsigned_t>(x);
17150 n_chars = count_digits(abs_value);
17153 // spare 1 byte for '\0'
17154 JSON_ASSERT(n_chars < number_buffer.size() - 1);
17156 // jump to the end to generate the string from backward
17157 // so we later avoid reversing the result
17158 buffer_ptr += n_chars;
17160 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
17161 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
17162 while (abs_value >= 100)
17164 const auto digits_index = static_cast<unsigned>((abs_value % 100));
17166 *(--buffer_ptr) = digits_to_99[digits_index][1];
17167 *(--buffer_ptr) = digits_to_99[digits_index][0];
17170 if (abs_value >= 10)
17172 const auto digits_index = static_cast<unsigned>(abs_value);
17173 *(--buffer_ptr) = digits_to_99[digits_index][1];
17174 *(--buffer_ptr) = digits_to_99[digits_index][0];
17178 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
17181 o->write_characters(number_buffer.data(), n_chars);
17185 @brief dump a floating-point number
17187 Dump a given floating-point number to output stream @a o. Works internally
17188 with @a number_buffer.
17190 @param[in] x floating-point number to dump
17192 void dump_float(number_float_t x)
17195 if (!std::isfinite(x))
17197 o->write_characters("null", 4);
17201 // If number_float_t is an IEEE-754 single or double precision number,
17202 // use the Grisu2 algorithm to produce short numbers which are
17203 // guaranteed to round-trip, using strtof and strtod, resp.
17205 // NB: The test below works if <long double> == <double>.
17206 static constexpr bool is_ieee_single_or_double
17207 = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
17208 (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
17210 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
17213 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
17215 auto* begin = number_buffer.data();
17216 auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
17218 o->write_characters(begin, static_cast<size_t>(end - begin));
17221 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
17223 // get number of digits for a float -> text -> float round-trip
17224 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
17226 // the actual conversion
17227 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17228 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
17230 // negative value indicates an error
17231 JSON_ASSERT(len > 0);
17232 // check if buffer was large enough
17233 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
17235 // erase thousands separator
17236 if (thousands_sep != '\0')
17238 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
17239 const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
17240 std::fill(end, number_buffer.end(), '\0');
17241 JSON_ASSERT((end - number_buffer.begin()) <= len);
17242 len = (end - number_buffer.begin());
17245 // convert decimal point to '.'
17246 if (decimal_point != '\0' && decimal_point != '.')
17248 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
17249 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
17250 if (dec_pos != number_buffer.end())
17256 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
17258 // determine if need to append ".0"
17259 const bool value_is_int_like =
17260 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
17263 return c == '.' || c == 'e';
17266 if (value_is_int_like)
17268 o->write_characters(".0", 2);
17273 @brief check whether a string is UTF-8 encoded
17275 The function checks each byte of a string whether it is UTF-8 encoded. The
17276 result of the check is stored in the @a state parameter. The function must
17277 be called initially with state 0 (accept). State 1 means the string must
17278 be rejected, because the current byte is not allowed. If the string is
17279 completely processed, but the state is non-zero, the string ended
17280 prematurely; that is, the last byte indicated more bytes should have
17283 @param[in,out] state the state of the decoding
17284 @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT)
17285 @param[in] byte next byte to decode
17288 @note The function has been edited: a std::array is used.
17290 @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
17291 @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
17293 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
17295 static const std::array<std::uint8_t, 400> utf8d =
17298 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
17299 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
17300 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
17301 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
17302 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
17303 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
17304 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
17305 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
17306 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
17307 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
17308 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
17309 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
17310 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
17311 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
17315 JSON_ASSERT(byte < utf8d.size());
17316 const std::uint8_t type = utf8d[byte];
17318 codep = (state != UTF8_ACCEPT)
17319 ? (byte & 0x3fu) | (codep << 6u)
17320 : (0xFFu >> type) & (byte);
17322 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
17323 JSON_ASSERT(index < 400);
17324 state = utf8d[index];
17329 * Overload to make the compiler happy while it is instantiating
17330 * dump_integer for number_unsigned_t.
17331 * Must never be called.
17333 number_unsigned_t remove_sign(number_unsigned_t x)
17335 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17336 return x; // LCOV_EXCL_LINE
17340 * Helper function for dump_integer
17342 * This function takes a negative signed integer and returns its absolute
17343 * value as unsigned integer. The plus/minus shuffling is necessary as we can
17344 * not directly remove the sign of an arbitrary signed integer as the
17345 * absolute values of INT_MIN and INT_MAX are usually not the same. See
17346 * #1708 for details.
17348 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
17350 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
17351 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
17355 /// the output of the serializer
17356 output_adapter_t<char> o = nullptr;
17358 /// a (hopefully) large enough character buffer
17359 std::array<char, 64> number_buffer{{}};
17362 const std::lconv* loc = nullptr;
17363 /// the locale's thousand separator character
17364 const char thousands_sep = '\0';
17365 /// the locale's decimal point character
17366 const char decimal_point = '\0';
17369 std::array<char, 512> string_buffer{{}};
17371 /// the indentation character
17372 const char indent_char;
17373 /// the indentation string
17374 string_t indent_string;
17376 /// error_handler how to react on decoding errors
17377 const error_handler_t error_handler;
17379 } // namespace detail
17380 } // namespace nlohmann
17382 // #include <nlohmann/detail/value_t.hpp>
17384 // #include <nlohmann/json_fwd.hpp>
17386 // #include <nlohmann/ordered_map.hpp>
17389 #include <functional> // less
17390 #include <initializer_list> // initializer_list
17391 #include <iterator> // input_iterator_tag, iterator_traits
17392 #include <memory> // allocator
17393 #include <stdexcept> // for out_of_range
17394 #include <type_traits> // enable_if, is_convertible
17395 #include <utility> // pair
17396 #include <vector> // vector
17398 // #include <nlohmann/detail/macro_scope.hpp>
17404 /// ordered_map: a minimal map-like container that preserves insertion order
17405 /// for use within nlohmann::basic_json<ordered_map>
17406 template <class Key, class T, class IgnoredLess = std::less<Key>,
17407 class Allocator = std::allocator<std::pair<const Key, T>>>
17408 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
17410 using key_type = Key;
17411 using mapped_type = T;
17412 using Container = std::vector<std::pair<const Key, T>, Allocator>;
17413 using typename Container::iterator;
17414 using typename Container::const_iterator;
17415 using typename Container::size_type;
17416 using typename Container::value_type;
17418 // Explicit constructors instead of `using Container::Container`
17419 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
17420 ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
17421 template <class It>
17422 ordered_map(It first, It last, const Allocator& alloc = Allocator())
17423 : Container{first, last, alloc} {}
17424 ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
17425 : Container{init, alloc} {}
17427 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
17429 for (auto it = this->begin(); it != this->end(); ++it)
17431 if (it->first == key)
17433 return {it, false};
17436 Container::emplace_back(key, t);
17437 return {--this->end(), true};
17440 T& operator[](const Key& key)
17442 return emplace(key, T{}).first->second;
17445 const T& operator[](const Key& key) const
17450 T& at(const Key& key)
17452 for (auto it = this->begin(); it != this->end(); ++it)
17454 if (it->first == key)
17460 JSON_THROW(std::out_of_range("key not found"));
17463 const T& at(const Key& key) const
17465 for (auto it = this->begin(); it != this->end(); ++it)
17467 if (it->first == key)
17473 JSON_THROW(std::out_of_range("key not found"));
17476 size_type erase(const Key& key)
17478 for (auto it = this->begin(); it != this->end(); ++it)
17480 if (it->first == key)
17482 // Since we cannot move const Keys, re-construct them in place
17483 for (auto next = it; ++next != this->end(); ++it)
17485 it->~value_type(); // Destroy but keep allocation
17486 new (&*it) value_type{std::move(*next)};
17488 Container::pop_back();
17495 iterator erase(iterator pos)
17497 return erase(pos, std::next(pos));
17500 iterator erase(iterator first, iterator last)
17502 const auto elements_affected = std::distance(first, last);
17503 const auto offset = std::distance(Container::begin(), first);
17505 // This is the start situation. We need to delete elements_affected
17506 // elements (3 in this example: e, f, g), and need to return an
17507 // iterator past the last deleted element (h in this example).
17508 // Note that offset is the distance from the start of the vector
17509 // to first. We will need this later.
17511 // [ a, b, c, d, e, f, g, h, i, j ]
17515 // Since we cannot move const Keys, we re-construct them in place.
17516 // We start at first and re-construct (viz. copy) the elements from
17517 // the back of the vector. Example for first iteration:
17520 // v | destroy e and re-construct with h
17521 // [ a, b, c, d, e, f, g, h, i, j ]
17523 // it it + elements_affected
17525 for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
17527 it->~value_type(); // destroy but keep allocation
17528 new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
17531 // [ a, b, c, d, h, i, j, h, i, j ]
17535 // remove the unneeded elements at the end of the vector
17536 Container::resize(this->size() - static_cast<size_type>(elements_affected));
17538 // [ a, b, c, d, h, i, j ]
17542 // first is now pointing past the last deleted element, but we cannot
17543 // use this iterator, because it may have been invalidated by the
17544 // resize call. Instead, we can return begin() + offset.
17545 return Container::begin() + offset;
17548 size_type count(const Key& key) const
17550 for (auto it = this->begin(); it != this->end(); ++it)
17552 if (it->first == key)
17560 iterator find(const Key& key)
17562 for (auto it = this->begin(); it != this->end(); ++it)
17564 if (it->first == key)
17569 return Container::end();
17572 const_iterator find(const Key& key) const
17574 for (auto it = this->begin(); it != this->end(); ++it)
17576 if (it->first == key)
17581 return Container::end();
17584 std::pair<iterator, bool> insert( value_type&& value )
17586 return emplace(value.first, std::move(value.second));
17589 std::pair<iterator, bool> insert( const value_type& value )
17591 for (auto it = this->begin(); it != this->end(); ++it)
17593 if (it->first == value.first)
17595 return {it, false};
17598 Container::push_back(value);
17599 return {--this->end(), true};
17602 template<typename InputIt>
17603 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
17604 std::input_iterator_tag>::value>::type;
17606 template<typename InputIt, typename = require_input_iter<InputIt>>
17607 void insert(InputIt first, InputIt last)
17609 for (auto it = first; it != last; ++it)
17616 } // namespace nlohmann
17619 #if defined(JSON_HAS_CPP_17)
17620 #include <string_view>
17624 @brief namespace for Niels Lohmann
17625 @see https://github.com/nlohmann
17626 @since version 1.0.0
17632 @brief a class to store JSON values
17634 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
17636 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
17638 @tparam StringType type for JSON strings and object keys (`std::string` by
17639 default; will be used in @ref string_t)
17640 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
17642 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
17643 default; will be used in @ref number_integer_t)
17644 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
17645 `uint64_t` by default; will be used in @ref number_unsigned_t)
17646 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
17647 default; will be used in @ref number_float_t)
17648 @tparam BinaryType type for packed binary data for compatibility with binary
17649 serialization formats (`std::vector<std::uint8_t>` by default; will be used in
17651 @tparam AllocatorType type of the allocator to use (`std::allocator` by
17653 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
17654 and `from_json()` (@ref adl_serializer by default)
17656 @requirement The class satisfies the following concept requirements:
17658 - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
17659 JSON values can be default constructed. The result will be a JSON null
17661 - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
17662 A JSON value can be constructed from an rvalue argument.
17663 - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
17664 A JSON value can be copy-constructed from an lvalue expression.
17665 - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
17666 A JSON value van be assigned from an rvalue argument.
17667 - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
17668 A JSON value can be copy-assigned from an lvalue expression.
17669 - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
17670 JSON values can be destructed.
17672 - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
17674 [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
17675 All non-static data members are private and standard layout types, the
17676 class has no virtual functions or (virtual) base classes.
17678 - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
17679 JSON values can be compared with `==`, see @ref
17680 operator==(const_reference,const_reference).
17681 - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
17682 JSON values can be compared with `<`, see @ref
17683 operator<(const_reference,const_reference).
17684 - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
17685 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
17686 other compatible types, using unqualified function call @ref swap().
17687 - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
17688 JSON values can be compared against `std::nullptr_t` objects which are used
17689 to model the `null` value.
17691 - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
17692 JSON values can be used like STL containers and provide iterator access.
17693 - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
17694 JSON values can be used like STL containers and provide reverse iterator
17697 @invariant The member variables @a m_value and @a m_type have the following
17699 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
17700 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
17701 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
17702 The invariants are checked by member function assert_invariant().
17705 @note ObjectType trick from https://stackoverflow.com/a/9860911
17708 @see [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange
17709 Format](https://tools.ietf.org/html/rfc8259)
17711 @since version 1.0.0
17715 NLOHMANN_BASIC_JSON_TPL_DECLARATION
17716 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
17719 template<detail::value_t> friend struct detail::external_constructor;
17720 friend ::nlohmann::json_pointer<basic_json>;
17722 template<typename BasicJsonType, typename InputType>
17723 friend class ::nlohmann::detail::parser;
17724 friend ::nlohmann::detail::serializer<basic_json>;
17725 template<typename BasicJsonType>
17726 friend class ::nlohmann::detail::iter_impl;
17727 template<typename BasicJsonType, typename CharType>
17728 friend class ::nlohmann::detail::binary_writer;
17729 template<typename BasicJsonType, typename InputType, typename SAX>
17730 friend class ::nlohmann::detail::binary_reader;
17731 template<typename BasicJsonType>
17732 friend class ::nlohmann::detail::json_sax_dom_parser;
17733 template<typename BasicJsonType>
17734 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
17735 friend class ::nlohmann::detail::exception;
17737 /// workaround type for MSVC
17738 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
17740 JSON_PRIVATE_UNLESS_TESTED:
17741 // convenience aliases for types residing in namespace detail;
17742 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
17744 template<typename InputAdapterType>
17745 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
17746 InputAdapterType adapter,
17747 detail::parser_callback_t<basic_json>cb = nullptr,
17748 const bool allow_exceptions = true,
17749 const bool ignore_comments = false
17752 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
17753 std::move(cb), allow_exceptions, ignore_comments);
17757 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
17758 template<typename BasicJsonType>
17759 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
17760 template<typename BasicJsonType>
17761 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
17762 template<typename Iterator>
17763 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
17764 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
17766 template<typename CharType>
17767 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
17769 template<typename InputType>
17770 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
17771 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
17773 JSON_PRIVATE_UNLESS_TESTED:
17774 using serializer = ::nlohmann::detail::serializer<basic_json>;
17777 using value_t = detail::value_t;
17778 /// JSON Pointer, see @ref nlohmann::json_pointer
17779 using json_pointer = ::nlohmann::json_pointer<basic_json>;
17780 template<typename T, typename SFINAE>
17781 using json_serializer = JSONSerializer<T, SFINAE>;
17782 /// how to treat decoding errors
17783 using error_handler_t = detail::error_handler_t;
17784 /// how to treat CBOR tags
17785 using cbor_tag_handler_t = detail::cbor_tag_handler_t;
17786 /// helper type for initializer lists of basic_json values
17787 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
17789 using input_format_t = detail::input_format_t;
17790 /// SAX interface type, see @ref nlohmann::json_sax
17791 using json_sax_t = json_sax<basic_json>;
17797 /// @name exceptions
17798 /// Classes to implement user-defined exceptions.
17801 /// @copydoc detail::exception
17802 using exception = detail::exception;
17803 /// @copydoc detail::parse_error
17804 using parse_error = detail::parse_error;
17805 /// @copydoc detail::invalid_iterator
17806 using invalid_iterator = detail::invalid_iterator;
17807 /// @copydoc detail::type_error
17808 using type_error = detail::type_error;
17809 /// @copydoc detail::out_of_range
17810 using out_of_range = detail::out_of_range;
17811 /// @copydoc detail::other_error
17812 using other_error = detail::other_error;
17817 /////////////////////
17818 // container types //
17819 /////////////////////
17821 /// @name container types
17822 /// The canonic container types to use @ref basic_json like any other STL
17826 /// the type of elements in a basic_json container
17827 using value_type = basic_json;
17829 /// the type of an element reference
17830 using reference = value_type&;
17831 /// the type of an element const reference
17832 using const_reference = const value_type&;
17834 /// a type to represent differences between iterators
17835 using difference_type = std::ptrdiff_t;
17836 /// a type to represent container sizes
17837 using size_type = std::size_t;
17839 /// the allocator type
17840 using allocator_type = AllocatorType<basic_json>;
17842 /// the type of an element pointer
17843 using pointer = typename std::allocator_traits<allocator_type>::pointer;
17844 /// the type of an element const pointer
17845 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
17847 /// an iterator for a basic_json container
17848 using iterator = iter_impl<basic_json>;
17849 /// a const iterator for a basic_json container
17850 using const_iterator = iter_impl<const basic_json>;
17851 /// a reverse iterator for a basic_json container
17852 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
17853 /// a const reverse iterator for a basic_json container
17854 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
17860 @brief returns the allocator associated with the container
17862 static allocator_type get_allocator()
17864 return allocator_type();
17868 @brief returns version information on the library
17870 This function returns a JSON object with information about the library,
17871 including the version number and information on the platform and compiler.
17873 @return JSON object holding version information
17875 ----------- | ---------------
17876 `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).
17877 `copyright` | The copyright line for the library as string.
17878 `name` | The name of the library as string.
17879 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
17880 `url` | The URL of the project as string.
17881 `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).
17883 @liveexample{The following code shows an example output of the `meta()`
17886 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17887 changes to any JSON value.
17889 @complexity Constant.
17893 JSON_HEDLEY_WARN_UNUSED_RESULT
17894 static basic_json meta()
17898 result["copyright"] = "(C) 2013-2021 Niels Lohmann";
17899 result["name"] = "JSON for Modern C++";
17900 result["url"] = "https://github.com/nlohmann/json";
17901 result["version"]["string"] =
17902 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
17903 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
17904 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
17905 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
17906 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
17907 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
17910 result["platform"] = "win32";
17911 #elif defined __linux__
17912 result["platform"] = "linux";
17913 #elif defined __APPLE__
17914 result["platform"] = "apple";
17915 #elif defined __unix__
17916 result["platform"] = "unix";
17918 result["platform"] = "unknown";
17921 #if defined(__ICC) || defined(__INTEL_COMPILER)
17922 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
17923 #elif defined(__clang__)
17924 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
17925 #elif defined(__GNUC__) || defined(__GNUG__)
17926 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
17927 #elif defined(__HP_cc) || defined(__HP_aCC)
17928 result["compiler"] = "hp"
17929 #elif defined(__IBMCPP__)
17930 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
17931 #elif defined(_MSC_VER)
17932 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
17933 #elif defined(__PGI)
17934 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
17935 #elif defined(__SUNPRO_CC)
17936 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
17938 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
17942 result["compiler"]["c++"] = std::to_string(__cplusplus);
17944 result["compiler"]["c++"] = "unknown";
17950 ///////////////////////////
17951 // JSON value data types //
17952 ///////////////////////////
17954 /// @name JSON value data types
17955 /// The data types to store a JSON value. These types are derived from
17956 /// the template arguments passed to class @ref basic_json.
17959 #if defined(JSON_HAS_CPP_14)
17960 // Use transparent comparator if possible, combined with perfect forwarding
17961 // on find() and count() calls prevents unnecessary string construction.
17962 using object_comparator_t = std::less<>;
17964 using object_comparator_t = std::less<StringType>;
17968 @brief a type for an object
17970 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows:
17971 > An object is an unordered collection of zero or more name/value pairs,
17972 > where a name is a string and a value is a string, number, boolean, null,
17973 > object, or array.
17975 To store objects in C++, a type is defined by the template parameters
17978 @tparam ObjectType the container to store objects (e.g., `std::map` or
17979 `std::unordered_map`)
17980 @tparam StringType the type of the keys or names (e.g., `std::string`).
17981 The comparison function `std::less<StringType>` is used to order elements
17982 inside the container.
17983 @tparam AllocatorType the allocator to use for objects (e.g.,
17988 With the default values for @a ObjectType (`std::map`), @a StringType
17989 (`std::string`), and @a AllocatorType (`std::allocator`), the default
17990 value for @a object_t is:
17994 std::string, // key_type
17995 basic_json, // value_type
17996 std::less<std::string>, // key_compare
17997 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
18003 The choice of @a object_t influences the behavior of the JSON class. With
18004 the default type, objects have the following behavior:
18006 - When all names are unique, objects will be interoperable in the sense
18007 that all software implementations receiving that object will agree on
18008 the name-value mappings.
18009 - When the names within an object are not unique, it is unspecified which
18010 one of the values for a given key will be chosen. For instance,
18011 `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
18013 - Internally, name/value pairs are stored in lexicographical order of the
18014 names. Objects will also be serialized (see @ref dump) in this order.
18015 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
18016 and serialized as `{"a": 2, "b": 1}`.
18017 - When comparing objects, the order of the name/value pairs is irrelevant.
18018 This makes objects interoperable in the sense that they will not be
18019 affected by these differences. For instance, `{"b": 1, "a": 2}` and
18020 `{"a": 2, "b": 1}` will be treated as equal.
18024 [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
18025 > An implementation may set limits on the maximum depth of nesting.
18027 In this class, the object's limit of nesting is not explicitly constrained.
18028 However, a maximum depth of nesting may be introduced by the compiler or
18029 runtime environment. A theoretical limit can be queried by calling the
18030 @ref max_size function of a JSON object.
18034 Objects are stored as pointers in a @ref basic_json type. That is, for any
18035 access to object values, a pointer of type `object_t*` must be
18038 @sa see @ref array_t -- type for an array value
18040 @since version 1.0.0
18042 @note The order name/value pairs are added to the object is *not*
18043 preserved by the library. Therefore, iterating an object may return
18044 name/value pairs in a different order than they were originally stored. In
18045 fact, keys will be traversed in alphabetical order as `std::map` with
18046 `std::less` is used by default. Please note this behavior conforms to [RFC
18047 8259](https://tools.ietf.org/html/rfc8259), because any order implements the
18048 specified "unordered" nature of JSON objects.
18050 using object_t = ObjectType<StringType,
18052 object_comparator_t,
18053 AllocatorType<std::pair<const StringType,
18057 @brief a type for an array
18059 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows:
18060 > An array is an ordered sequence of zero or more values.
18062 To store objects in C++, a type is defined by the template parameters
18065 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
18067 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
18071 With the default values for @a ArrayType (`std::vector`) and @a
18072 AllocatorType (`std::allocator`), the default value for @a array_t is:
18076 basic_json, // value_type
18077 std::allocator<basic_json> // allocator_type
18083 [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
18084 > An implementation may set limits on the maximum depth of nesting.
18086 In this class, the array's limit of nesting is not explicitly constrained.
18087 However, a maximum depth of nesting may be introduced by the compiler or
18088 runtime environment. A theoretical limit can be queried by calling the
18089 @ref max_size function of a JSON array.
18093 Arrays are stored as pointers in a @ref basic_json type. That is, for any
18094 access to array values, a pointer of type `array_t*` must be dereferenced.
18096 @sa see @ref object_t -- type for an object value
18098 @since version 1.0.0
18100 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
18103 @brief a type for a string
18105 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows:
18106 > A string is a sequence of zero or more Unicode characters.
18108 To store objects in C++, a type is defined by the template parameter
18109 described below. Unicode values are split by the JSON class into
18110 byte-sized characters during deserialization.
18112 @tparam StringType the container to store strings (e.g., `std::string`).
18113 Note this container is used for keys/names in objects, see @ref object_t.
18117 With the default values for @a StringType (`std::string`), the default
18118 value for @a string_t is:
18126 Strings are stored in UTF-8 encoding. Therefore, functions like
18127 `std::string::size()` or `std::string::length()` return the number of
18128 bytes in the string rather than the number of characters or glyphs.
18130 #### String comparison
18132 [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
18133 > Software implementations are typically required to test names of object
18134 > members for equality. Implementations that transform the textual
18135 > representation into sequences of Unicode code units and then perform the
18136 > comparison numerically, code unit by code unit, are interoperable in the
18137 > sense that implementations will agree in all cases on equality or
18138 > inequality of two strings. For example, implementations that compare
18139 > strings with escaped characters unconverted may incorrectly find that
18140 > `"a\\b"` and `"a\u005Cb"` are not equal.
18142 This implementation is interoperable as it does compare strings code unit
18147 String values are stored as pointers in a @ref basic_json type. That is,
18148 for any access to string values, a pointer of type `string_t*` must be
18151 @since version 1.0.0
18153 using string_t = StringType;
18156 @brief a type for a boolean
18158 [RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a
18159 type which differentiates the two literals `true` and `false`.
18161 To store objects in C++, a type is defined by the template parameter @a
18162 BooleanType which chooses the type to use.
18166 With the default values for @a BooleanType (`bool`), the default value for
18175 Boolean values are stored directly inside a @ref basic_json type.
18177 @since version 1.0.0
18179 using boolean_t = BooleanType;
18182 @brief a type for a number (integer)
18184 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18185 > The representation of numbers is similar to that used in most
18186 > programming languages. A number is represented in base 10 using decimal
18187 > digits. It contains an integer component that may be prefixed with an
18188 > optional minus sign, which may be followed by a fraction part and/or an
18189 > exponent part. Leading zeros are not allowed. (...) Numeric values that
18190 > cannot be represented in the grammar below (such as Infinity and NaN)
18191 > are not permitted.
18193 This description includes both integer and floating-point numbers.
18194 However, C++ allows more precise storage if it is known whether the number
18195 is a signed integer, an unsigned integer or a floating-point number.
18196 Therefore, three different types, @ref number_integer_t, @ref
18197 number_unsigned_t and @ref number_float_t are used.
18199 To store integer numbers in C++, a type is defined by the template
18200 parameter @a NumberIntegerType which chooses the type to use.
18204 With the default values for @a NumberIntegerType (`int64_t`), the default
18205 value for @a number_integer_t is:
18211 #### Default behavior
18213 - The restrictions about leading zeros is not enforced in C++. Instead,
18214 leading zeros in integer literals lead to an interpretation as octal
18215 number. Internally, the value will be stored as decimal number. For
18216 instance, the C++ integer literal `010` will be serialized to `8`.
18217 During deserialization, leading zeros yield an error.
18218 - Not-a-number (NaN) values will be serialized to `null`.
18222 [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
18223 > An implementation may set limits on the range and precision of numbers.
18225 When the default type is used, the maximal integer number that can be
18226 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
18227 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
18228 that are out of range will yield over/underflow when used in a
18229 constructor. During deserialization, too large or small integer numbers
18230 will be automatically be stored as @ref number_unsigned_t or @ref
18233 [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
18234 > Note that when such software is used, numbers that are integers and are
18235 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
18236 > that implementations will agree exactly on their numeric values.
18238 As this range is a subrange of the exactly supported range [INT64_MIN,
18239 INT64_MAX], this class's integer type is interoperable.
18243 Integer number values are stored directly inside a @ref basic_json type.
18245 @sa see @ref number_float_t -- type for number values (floating-point)
18247 @sa see @ref number_unsigned_t -- type for number values (unsigned integer)
18249 @since version 1.0.0
18251 using number_integer_t = NumberIntegerType;
18254 @brief a type for a number (unsigned)
18256 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18257 > The representation of numbers is similar to that used in most
18258 > programming languages. A number is represented in base 10 using decimal
18259 > digits. It contains an integer component that may be prefixed with an
18260 > optional minus sign, which may be followed by a fraction part and/or an
18261 > exponent part. Leading zeros are not allowed. (...) Numeric values that
18262 > cannot be represented in the grammar below (such as Infinity and NaN)
18263 > are not permitted.
18265 This description includes both integer and floating-point numbers.
18266 However, C++ allows more precise storage if it is known whether the number
18267 is a signed integer, an unsigned integer or a floating-point number.
18268 Therefore, three different types, @ref number_integer_t, @ref
18269 number_unsigned_t and @ref number_float_t are used.
18271 To store unsigned integer numbers in C++, a type is defined by the
18272 template parameter @a NumberUnsignedType which chooses the type to use.
18276 With the default values for @a NumberUnsignedType (`uint64_t`), the
18277 default value for @a number_unsigned_t is:
18283 #### Default behavior
18285 - The restrictions about leading zeros is not enforced in C++. Instead,
18286 leading zeros in integer literals lead to an interpretation as octal
18287 number. Internally, the value will be stored as decimal number. For
18288 instance, the C++ integer literal `010` will be serialized to `8`.
18289 During deserialization, leading zeros yield an error.
18290 - Not-a-number (NaN) values will be serialized to `null`.
18294 [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
18295 > An implementation may set limits on the range and precision of numbers.
18297 When the default type is used, the maximal integer number that can be
18298 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
18299 number that can be stored is `0`. Integer numbers that are out of range
18300 will yield over/underflow when used in a constructor. During
18301 deserialization, too large or small integer numbers will be automatically
18302 be stored as @ref number_integer_t or @ref number_float_t.
18304 [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
18305 > Note that when such software is used, numbers that are integers and are
18306 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
18307 > that implementations will agree exactly on their numeric values.
18309 As this range is a subrange (when considered in conjunction with the
18310 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
18311 this class's integer type is interoperable.
18315 Integer number values are stored directly inside a @ref basic_json type.
18317 @sa see @ref number_float_t -- type for number values (floating-point)
18318 @sa see @ref number_integer_t -- type for number values (integer)
18320 @since version 2.0.0
18322 using number_unsigned_t = NumberUnsignedType;
18325 @brief a type for a number (floating-point)
18327 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18328 > The representation of numbers is similar to that used in most
18329 > programming languages. A number is represented in base 10 using decimal
18330 > digits. It contains an integer component that may be prefixed with an
18331 > optional minus sign, which may be followed by a fraction part and/or an
18332 > exponent part. Leading zeros are not allowed. (...) Numeric values that
18333 > cannot be represented in the grammar below (such as Infinity and NaN)
18334 > are not permitted.
18336 This description includes both integer and floating-point numbers.
18337 However, C++ allows more precise storage if it is known whether the number
18338 is a signed integer, an unsigned integer or a floating-point number.
18339 Therefore, three different types, @ref number_integer_t, @ref
18340 number_unsigned_t and @ref number_float_t are used.
18342 To store floating-point numbers in C++, a type is defined by the template
18343 parameter @a NumberFloatType which chooses the type to use.
18347 With the default values for @a NumberFloatType (`double`), the default
18348 value for @a number_float_t is:
18354 #### Default behavior
18356 - The restrictions about leading zeros is not enforced in C++. Instead,
18357 leading zeros in floating-point literals will be ignored. Internally,
18358 the value will be stored as decimal number. For instance, the C++
18359 floating-point literal `01.2` will be serialized to `1.2`. During
18360 deserialization, leading zeros yield an error.
18361 - Not-a-number (NaN) values will be serialized to `null`.
18365 [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
18366 > This specification allows implementations to set limits on the range and
18367 > precision of numbers accepted. Since software that implements IEEE
18368 > 754-2008 binary64 (double precision) numbers is generally available and
18369 > widely used, good interoperability can be achieved by implementations
18370 > that expect no more precision or range than these provide, in the sense
18371 > that implementations will approximate JSON numbers within the expected
18374 This implementation does exactly follow this approach, as it uses double
18375 precision floating-point numbers. Note values smaller than
18376 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
18377 will be stored as NaN internally and be serialized to `null`.
18381 Floating-point number values are stored directly inside a @ref basic_json
18384 @sa see @ref number_integer_t -- type for number values (integer)
18386 @sa see @ref number_unsigned_t -- type for number values (unsigned integer)
18388 @since version 1.0.0
18390 using number_float_t = NumberFloatType;
18393 @brief a type for a packed binary type
18395 This type is a type designed to carry binary data that appears in various
18396 serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
18397 BSON's generic binary subtype. This type is NOT a part of standard JSON and
18398 exists solely for compatibility with these binary types. As such, it is
18399 simply defined as an ordered sequence of zero or more byte values.
18401 Additionally, as an implementation detail, the subtype of the binary data is
18402 carried around as a `std::uint8_t`, which is compatible with both of the
18403 binary data formats that use binary subtyping, (though the specific
18404 numbering is incompatible with each other, and it is up to the user to
18405 translate between them).
18407 [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
18409 > Major type 2: a byte string. The string's length in bytes is represented
18410 > following the rules for positive integers (major type 0).
18412 [MessagePack's documentation on the bin type
18413 family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
18414 describes this type as:
18415 > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes
18416 > in addition to the size of the byte array.
18418 [BSON's specifications](http://bsonspec.org/spec.html) describe several
18419 binary types; however, this type is intended to represent the generic binary
18420 type which has the description:
18421 > Generic binary subtype - This is the most commonly used binary subtype and
18422 > should be the 'default' for drivers and tools.
18424 None of these impose any limitations on the internal representation other
18425 than the basic unit of storage be some type of array whose parts are
18426 decomposable into bytes.
18428 The default representation of this binary format is a
18429 `std::vector<std::uint8_t>`, which is a very common way to represent a byte
18430 array in modern C++.
18434 The default values for @a BinaryType is `std::vector<std::uint8_t>`
18438 Binary Arrays are stored as pointers in a @ref basic_json type. That is,
18439 for any access to array values, a pointer of the type `binary_t*` must be
18442 #### Notes on subtypes
18445 - Binary values are represented as byte strings. Subtypes are serialized
18448 - If a subtype is given and the binary array contains exactly 1, 2, 4, 8,
18449 or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8)
18450 is used. For other sizes, the ext family (ext8, ext16, ext32) is used.
18451 The subtype is then added as signed 8-bit integer.
18452 - If no subtype is given, the bin family (bin8, bin16, bin32) is used.
18454 - If a subtype is given, it is used and added as unsigned 8-bit integer.
18455 - If no subtype is given, the generic binary subtype 0x00 is used.
18457 @sa see @ref binary -- create a binary array
18459 @since version 3.8.0
18461 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
18466 /// helper for exception-safe object creation
18467 template<typename T, typename... Args>
18468 JSON_HEDLEY_RETURNS_NON_NULL
18469 static T* create(Args&& ... args)
18471 AllocatorType<T> alloc;
18472 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18474 auto deleter = [&](T * obj)
18476 AllocatorTraits::deallocate(alloc, obj, 1);
18478 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18479 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18480 JSON_ASSERT(obj != nullptr);
18481 return obj.release();
18484 ////////////////////////
18485 // JSON value storage //
18486 ////////////////////////
18488 JSON_PRIVATE_UNLESS_TESTED:
18490 @brief a JSON value
18492 The actual storage for a JSON value of the @ref basic_json class. This
18493 union combines the different storage types for the JSON value types
18494 defined in @ref value_t.
18496 JSON type | value_t type | used type
18497 --------- | --------------- | ------------------------
18498 object | object | pointer to @ref object_t
18499 array | array | pointer to @ref array_t
18500 string | string | pointer to @ref string_t
18501 boolean | boolean | @ref boolean_t
18502 number | number_integer | @ref number_integer_t
18503 number | number_unsigned | @ref number_unsigned_t
18504 number | number_float | @ref number_float_t
18505 binary | binary | pointer to @ref binary_t
18506 null | null | *no value is stored*
18508 @note Variable-length types (objects, arrays, and strings) are stored as
18509 pointers. The size of the union should not exceed 64 bits if the default
18510 value types are used.
18512 @since version 1.0.0
18516 /// object (stored with pointer to save storage)
18518 /// array (stored with pointer to save storage)
18520 /// string (stored with pointer to save storage)
18522 /// binary (stored with pointer to save storage)
18526 /// number (integer)
18527 number_integer_t number_integer;
18528 /// number (unsigned integer)
18529 number_unsigned_t number_unsigned;
18530 /// number (floating-point)
18531 number_float_t number_float;
18533 /// default constructor (for null values)
18534 json_value() = default;
18535 /// constructor for booleans
18536 json_value(boolean_t v) noexcept : boolean(v) {}
18537 /// constructor for numbers (integer)
18538 json_value(number_integer_t v) noexcept : number_integer(v) {}
18539 /// constructor for numbers (unsigned)
18540 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
18541 /// constructor for numbers (floating-point)
18542 json_value(number_float_t v) noexcept : number_float(v) {}
18543 /// constructor for empty values of a given type
18544 json_value(value_t t)
18548 case value_t::object:
18550 object = create<object_t>();
18554 case value_t::array:
18556 array = create<array_t>();
18560 case value_t::string:
18562 string = create<string_t>("");
18566 case value_t::binary:
18568 binary = create<binary_t>();
18572 case value_t::boolean:
18574 boolean = boolean_t(false);
18578 case value_t::number_integer:
18580 number_integer = number_integer_t(0);
18584 case value_t::number_unsigned:
18586 number_unsigned = number_unsigned_t(0);
18590 case value_t::number_float:
18592 number_float = number_float_t(0.0);
18596 case value_t::null:
18598 object = nullptr; // silence warning, see #821
18602 case value_t::discarded:
18605 object = nullptr; // silence warning, see #821
18606 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
18608 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.4", basic_json())); // LCOV_EXCL_LINE
18615 /// constructor for strings
18616 json_value(const string_t& value) : string(create<string_t>(value)) {}
18618 /// constructor for rvalue strings
18619 json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
18621 /// constructor for objects
18622 json_value(const object_t& value) : object(create<object_t>(value)) {}
18624 /// constructor for rvalue objects
18625 json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
18627 /// constructor for arrays
18628 json_value(const array_t& value) : array(create<array_t>(value)) {}
18630 /// constructor for rvalue arrays
18631 json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
18633 /// constructor for binary arrays
18634 json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
18636 /// constructor for rvalue binary arrays
18637 json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
18639 /// constructor for binary arrays (internal type)
18640 json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
18642 /// constructor for rvalue binary arrays (internal type)
18643 json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
18645 void destroy(value_t t)
18647 if (t == value_t::array || t == value_t::object)
18649 // flatten the current json_value to a heap-allocated stack
18650 std::vector<basic_json> stack;
18652 // move the top-level items to stack
18653 if (t == value_t::array)
18655 stack.reserve(array->size());
18656 std::move(array->begin(), array->end(), std::back_inserter(stack));
18660 stack.reserve(object->size());
18661 for (auto&& it : *object)
18663 stack.push_back(std::move(it.second));
18667 while (!stack.empty())
18669 // move the last item to local variable to be processed
18670 basic_json current_item(std::move(stack.back()));
18673 // if current_item is array/object, move
18674 // its children to the stack to be processed later
18675 if (current_item.is_array())
18677 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
18679 current_item.m_value.array->clear();
18681 else if (current_item.is_object())
18683 for (auto&& it : *current_item.m_value.object)
18685 stack.push_back(std::move(it.second));
18688 current_item.m_value.object->clear();
18691 // it's now safe that current_item get destructed
18692 // since it doesn't have any children
18698 case value_t::object:
18700 AllocatorType<object_t> alloc;
18701 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18702 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18706 case value_t::array:
18708 AllocatorType<array_t> alloc;
18709 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18710 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18714 case value_t::string:
18716 AllocatorType<string_t> alloc;
18717 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18718 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18722 case value_t::binary:
18724 AllocatorType<binary_t> alloc;
18725 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18726 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18730 case value_t::null:
18731 case value_t::boolean:
18732 case value_t::number_integer:
18733 case value_t::number_unsigned:
18734 case value_t::number_float:
18735 case value_t::discarded:
18746 @brief checks the class invariants
18748 This function asserts the class invariants. It needs to be called at the
18749 end of every constructor to make sure that created objects respect the
18750 invariant. Furthermore, it has to be called each time the type of a JSON
18751 value is changed, because the invariant expresses a relationship between
18752 @a m_type and @a m_value.
18754 Furthermore, the parent relation is checked for arrays and objects: If
18755 @a check_parents true and the value is an array or object, then the
18756 container's elements must have the current value as parent.
18758 @param[in] check_parents whether the parent relation should be checked.
18759 The value is true by default and should only be set to false
18760 during destruction of objects when the invariant does not
18763 void assert_invariant(bool check_parents = true) const noexcept
18765 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18766 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18767 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18768 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18770 #if JSON_DIAGNOSTICS
18773 // cppcheck-suppress assertWithSideEffect
18774 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
18776 return j.m_parent == this;
18779 JSON_CATCH(...) {} // LCOV_EXCL_LINE
18781 static_cast<void>(check_parents);
18786 #if JSON_DIAGNOSTICS
18789 case value_t::array:
18791 for (auto& element : *m_value.array)
18793 element.m_parent = this;
18798 case value_t::object:
18800 for (auto& element : *m_value.object)
18802 element.second.m_parent = this;
18807 case value_t::null:
18808 case value_t::string:
18809 case value_t::boolean:
18810 case value_t::number_integer:
18811 case value_t::number_unsigned:
18812 case value_t::number_float:
18813 case value_t::binary:
18814 case value_t::discarded:
18821 iterator set_parents(iterator it, typename iterator::difference_type count)
18823 #if JSON_DIAGNOSTICS
18824 for (typename iterator::difference_type i = 0; i < count; ++i)
18826 (it + i)->m_parent = this;
18829 static_cast<void>(count);
18834 reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1))
18836 #if JSON_DIAGNOSTICS
18837 if (old_capacity != std::size_t(-1))
18839 // see https://github.com/nlohmann/json/issues/2838
18840 JSON_ASSERT(type() == value_t::array);
18841 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
18843 // capacity has changed: update all parents
18849 // ordered_json uses a vector internally, so pointers could have
18850 // been invalidated; see https://github.com/nlohmann/json/issues/2962
18851 #ifdef JSON_HEDLEY_MSVC_VERSION
18852 #pragma warning(push )
18853 #pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
18855 if (detail::is_ordered_map<object_t>::value)
18860 #ifdef JSON_HEDLEY_MSVC_VERSION
18861 #pragma warning( pop )
18866 static_cast<void>(j);
18867 static_cast<void>(old_capacity);
18873 //////////////////////////
18874 // JSON parser callback //
18875 //////////////////////////
18878 @brief parser event types
18880 The parser callback distinguishes the following events:
18881 - `object_start`: the parser read `{` and started to process a JSON object
18882 - `key`: the parser read a key of a value in an object
18883 - `object_end`: the parser read `}` and finished processing a JSON object
18884 - `array_start`: the parser read `[` and started to process a JSON array
18885 - `array_end`: the parser read `]` and finished processing a JSON array
18886 - `value`: the parser finished reading a JSON value
18888 @image html callback_events.png "Example when certain parse events are triggered"
18890 @sa see @ref parser_callback_t for more information and examples
18892 using parse_event_t = detail::parse_event_t;
18895 @brief per-element parser callback type
18897 With a parser callback function, the result of parsing a JSON text can be
18898 influenced. When passed to @ref parse, it is called on certain events
18899 (passed as @ref parse_event_t via parameter @a event) with a set recursion
18900 depth @a depth and context JSON value @a parsed. The return value of the
18901 callback function is a boolean indicating whether the element that emitted
18902 the callback shall be kept or not.
18904 We distinguish six scenarios (determined by the event type) in which the
18905 callback function can be called. The following table describes the values
18906 of the parameters @a depth, @a event, and @a parsed.
18908 parameter @a event | description | parameter @a depth | parameter @a parsed
18909 ------------------ | ----------- | ------------------ | -------------------
18910 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
18911 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
18912 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
18913 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
18914 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
18915 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
18917 @image html callback_events.png "Example when certain parse events are triggered"
18919 Discarding a value (i.e., returning `false`) has different effects
18920 depending on the context in which function was called:
18922 - Discarded values in structured types are skipped. That is, the parser
18923 will behave as if the discarded value was never read.
18924 - In case a value outside a structured type is skipped, it is replaced
18925 with `null`. This case happens if the top-level element is skipped.
18927 @param[in] depth the depth of the recursion during parsing
18929 @param[in] event an event of type parse_event_t indicating the context in
18930 the callback function has been called
18932 @param[in,out] parsed the current intermediate parse result; note that
18933 writing to this value has no effect for parse_event_t::key events
18935 @return Whether the JSON value which called the function during parsing
18936 should be kept (`true`) or not (`false`). In the latter case, it is either
18937 skipped completely or replaced by an empty discarded object.
18939 @sa see @ref parse for examples
18941 @since version 1.0.0
18943 using parser_callback_t = detail::parser_callback_t<basic_json>;
18949 /// @name constructors and destructors
18950 /// Constructors of class @ref basic_json, copy/move constructor, copy
18951 /// assignment, static functions creating objects, and the destructor.
18955 @brief create an empty value with a given type
18957 Create an empty JSON value with a given type. The value will be default
18958 initialized with an empty value which depends on the type:
18960 Value type | initial value
18961 ----------- | -------------
18968 binary | empty array
18970 @param[in] v the type of the value to create
18972 @complexity Constant.
18974 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18975 changes to any JSON value.
18977 @liveexample{The following code shows the constructor for different @ref
18978 value_t values,basic_json__value_t}
18980 @sa see @ref clear() -- restores the postcondition of this constructor
18982 @since version 1.0.0
18984 basic_json(const value_t v)
18985 : m_type(v), m_value(v)
18987 assert_invariant();
18991 @brief create a null object
18993 Create a `null` JSON value. It either takes a null pointer as parameter
18994 (explicitly creating `null`) or no parameter (implicitly creating `null`).
18995 The passed null pointer itself is not read -- it is only used to choose
18996 the right constructor.
18998 @complexity Constant.
19000 @exceptionsafety No-throw guarantee: this constructor never throws
19003 @liveexample{The following code shows the constructor with and without a
19004 null pointer parameter.,basic_json__nullptr_t}
19006 @since version 1.0.0
19008 basic_json(std::nullptr_t = nullptr) noexcept
19009 : basic_json(value_t::null)
19011 assert_invariant();
19015 @brief create a JSON value
19017 This is a "catch all" constructor for all compatible JSON types; that is,
19018 types for which a `to_json()` method exists. The constructor forwards the
19019 parameter @a val to that method (to `json_serializer<U>::to_json` method
19020 with `U = uncvref_t<CompatibleType>`, to be exact).
19022 Template type @a CompatibleType includes, but is not limited to, the
19024 - **arrays**: @ref array_t and all kinds of compatible containers such as
19025 `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
19026 `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
19027 `std::multiset`, and `std::unordered_multiset` with a `value_type` from
19028 which a @ref basic_json value can be constructed.
19029 - **objects**: @ref object_t and all kinds of compatible associative
19030 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
19031 and `std::unordered_multimap` with a `key_type` compatible to
19032 @ref string_t and a `value_type` from which a @ref basic_json value can
19034 - **strings**: @ref string_t, string literals, and all compatible string
19035 containers can be used.
19036 - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
19037 @ref number_float_t, and all convertible number types such as `int`,
19038 `size_t`, `int64_t`, `float` or `double` can be used.
19039 - **boolean**: @ref boolean_t / `bool` can be used.
19040 - **binary**: @ref binary_t / `std::vector<std::uint8_t>` may be used,
19041 unfortunately because string literals cannot be distinguished from binary
19042 character arrays by the C++ type system, all types compatible with `const
19043 char*` will be directed to the string constructor instead. This is both
19044 for backwards compatibility, and due to the fact that a binary type is not
19045 a standard JSON type.
19047 See the examples below.
19049 @tparam CompatibleType a type such that:
19050 - @a CompatibleType is not derived from `std::istream`,
19051 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
19053 - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
19054 - @a CompatibleType is not a @ref basic_json nested type (e.g.,
19055 @ref json_pointer, @ref iterator, etc ...)
19056 - `json_serializer<U>` has a `to_json(basic_json_t&, CompatibleType&&)` method
19058 @tparam U = `uncvref_t<CompatibleType>`
19060 @param[in] val the value to be forwarded to the respective constructor
19062 @complexity Usually linear in the size of the passed @a val, also
19063 depending on the implementation of the called `to_json()`
19066 @exceptionsafety Depends on the called constructor. For types directly
19067 supported by the library (i.e., all types for which no `to_json()` function
19068 was provided), strong guarantee holds: if an exception is thrown, there are
19069 no changes to any JSON value.
19071 @liveexample{The following code shows the constructor with several
19072 compatible types.,basic_json__CompatibleType}
19074 @since version 2.1.0
19076 template < typename CompatibleType,
19077 typename U = detail::uncvref_t<CompatibleType>,
19078 detail::enable_if_t <
19079 !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
19080 basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
19081 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
19082 std::forward<CompatibleType>(val))))
19084 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
19086 assert_invariant();
19090 @brief create a JSON value from an existing one
19092 This is a constructor for existing @ref basic_json types.
19093 It does not hijack copy/move constructors, since the parameter has different
19094 template arguments than the current ones.
19096 The constructor tries to convert the internal @ref m_value of the parameter.
19098 @tparam BasicJsonType a type such that:
19099 - @a BasicJsonType is a @ref basic_json type.
19100 - @a BasicJsonType has different template arguments than @ref basic_json_t.
19102 @param[in] val the @ref basic_json value to be converted.
19104 @complexity Usually linear in the size of the passed @a val, also
19105 depending on the implementation of the called `to_json()`
19108 @exceptionsafety Depends on the called constructor. For types directly
19109 supported by the library (i.e., all types for which no `to_json()` function
19110 was provided), strong guarantee holds: if an exception is thrown, there are
19111 no changes to any JSON value.
19113 @since version 3.2.0
19115 template < typename BasicJsonType,
19116 detail::enable_if_t <
19117 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
19118 basic_json(const BasicJsonType& val)
19120 using other_boolean_t = typename BasicJsonType::boolean_t;
19121 using other_number_float_t = typename BasicJsonType::number_float_t;
19122 using other_number_integer_t = typename BasicJsonType::number_integer_t;
19123 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
19124 using other_string_t = typename BasicJsonType::string_t;
19125 using other_object_t = typename BasicJsonType::object_t;
19126 using other_array_t = typename BasicJsonType::array_t;
19127 using other_binary_t = typename BasicJsonType::binary_t;
19129 switch (val.type())
19131 case value_t::boolean:
19132 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
19134 case value_t::number_float:
19135 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
19137 case value_t::number_integer:
19138 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
19140 case value_t::number_unsigned:
19141 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
19143 case value_t::string:
19144 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
19146 case value_t::object:
19147 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
19149 case value_t::array:
19150 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
19152 case value_t::binary:
19153 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
19155 case value_t::null:
19158 case value_t::discarded:
19159 m_type = value_t::discarded;
19161 default: // LCOV_EXCL_LINE
19162 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19165 assert_invariant();
19169 @brief create a container (array or object) from an initializer list
19171 Creates a JSON value of type array or object from the passed initializer
19172 list @a init. In case @a type_deduction is `true` (default), the type of
19173 the JSON value to be created is deducted from the initializer list @a init
19174 according to the following rules:
19176 1. If the list is empty, an empty JSON object value `{}` is created.
19177 2. If the list consists of pairs whose first element is a string, a JSON
19178 object value is created where the first elements of the pairs are
19179 treated as keys and the second elements are as values.
19180 3. In all other cases, an array is created.
19182 The rules aim to create the best fit between a C++ initializer list and
19183 JSON values. The rationale is as follows:
19185 1. The empty initializer list is written as `{}` which is exactly an empty
19187 2. C++ has no way of describing mapped types other than to list a list of
19188 pairs. As JSON requires that keys must be of type string, rule 2 is the
19189 weakest constraint one can pose on initializer lists to interpret them
19191 3. In all other cases, the initializer list could not be interpreted as
19192 JSON object type, so interpreting it as JSON array type is safe.
19194 With the rules described above, the following JSON values cannot be
19195 expressed by an initializer list:
19197 - the empty array (`[]`): use @ref array(initializer_list_t)
19198 with an empty initializer list in this case
19199 - arrays whose elements satisfy rule 2: use @ref
19200 array(initializer_list_t) with the same initializer list
19203 @note When used without parentheses around an empty initializer list, @ref
19204 basic_json() is called instead of this function, yielding the JSON null
19207 @param[in] init initializer list with JSON values
19209 @param[in] type_deduction internal parameter; when set to `true`, the type
19210 of the JSON value is deducted from the initializer list @a init; when set
19211 to `false`, the type provided via @a manual_type is forced. This mode is
19212 used by the functions @ref array(initializer_list_t) and
19213 @ref object(initializer_list_t).
19215 @param[in] manual_type internal parameter; when @a type_deduction is set
19216 to `false`, the created JSON value will use the provided type (only @ref
19217 value_t::array and @ref value_t::object are valid); when @a type_deduction
19218 is set to `true`, this parameter has no effect
19220 @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
19221 `value_t::object`, but @a init contains an element which is not a pair
19222 whose first element is a string. In this case, the constructor could not
19223 create an object. If @a type_deduction would have be `true`, an array
19224 would have been created. See @ref object(initializer_list_t)
19227 @complexity Linear in the size of the initializer list @a init.
19229 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19230 changes to any JSON value.
19232 @liveexample{The example below shows how JSON values are created from
19233 initializer lists.,basic_json__list_init_t}
19235 @sa see @ref array(initializer_list_t) -- create a JSON array
19236 value from an initializer list
19237 @sa see @ref object(initializer_list_t) -- create a JSON object
19238 value from an initializer list
19240 @since version 1.0.0
19242 basic_json(initializer_list_t init,
19243 bool type_deduction = true,
19244 value_t manual_type = value_t::array)
19246 // check if each element is an array with two elements whose first
19247 // element is a string
19248 bool is_an_object = std::all_of(init.begin(), init.end(),
19249 [](const detail::json_ref<basic_json>& element_ref)
19251 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19254 // adjust type if type deduction is not wanted
19255 if (!type_deduction)
19257 // if array is wanted, do not create an object though possible
19258 if (manual_type == value_t::array)
19260 is_an_object = false;
19263 // if object is wanted but impossible, throw an exception
19264 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19266 JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
19272 // the initializer list is a list of pairs -> create object
19273 m_type = value_t::object;
19274 m_value = value_t::object;
19276 for (auto& element_ref : init)
19278 auto element = element_ref.moved_or_copied();
19279 m_value.object->emplace(
19280 std::move(*((*element.m_value.array)[0].m_value.string)),
19281 std::move((*element.m_value.array)[1]));
19286 // the initializer list describes an array -> create array
19287 m_type = value_t::array;
19288 m_value.array = create<array_t>(init.begin(), init.end());
19292 assert_invariant();
19296 @brief explicitly create a binary array (without subtype)
19298 Creates a JSON binary array value from a given binary container. Binary
19299 values are part of various binary formats, such as CBOR, MessagePack, and
19300 BSON. This constructor is used to create a value for serialization to those
19303 @note Note, this function exists because of the difficulty in correctly
19304 specifying the correct template overload in the standard value ctor, as both
19305 JSON arrays and JSON binary arrays are backed with some form of a
19306 `std::vector`. Because JSON binary arrays are a non-standard extension it
19307 was decided that it would be best to prevent automatic initialization of a
19308 binary array type, for backwards compatibility and so it does not happen on
19311 @param[in] init container containing bytes to use as binary type
19313 @return JSON binary array value
19315 @complexity Linear in the size of @a init.
19317 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19318 changes to any JSON value.
19320 @since version 3.8.0
19322 JSON_HEDLEY_WARN_UNUSED_RESULT
19323 static basic_json binary(const typename binary_t::container_type& init)
19325 auto res = basic_json();
19326 res.m_type = value_t::binary;
19327 res.m_value = init;
19332 @brief explicitly create a binary array (with subtype)
19334 Creates a JSON binary array value from a given binary container. Binary
19335 values are part of various binary formats, such as CBOR, MessagePack, and
19336 BSON. This constructor is used to create a value for serialization to those
19339 @note Note, this function exists because of the difficulty in correctly
19340 specifying the correct template overload in the standard value ctor, as both
19341 JSON arrays and JSON binary arrays are backed with some form of a
19342 `std::vector`. Because JSON binary arrays are a non-standard extension it
19343 was decided that it would be best to prevent automatic initialization of a
19344 binary array type, for backwards compatibility and so it does not happen on
19347 @param[in] init container containing bytes to use as binary type
19348 @param[in] subtype subtype to use in MessagePack and BSON
19350 @return JSON binary array value
19352 @complexity Linear in the size of @a init.
19354 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19355 changes to any JSON value.
19357 @since version 3.8.0
19359 JSON_HEDLEY_WARN_UNUSED_RESULT
19360 static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
19362 auto res = basic_json();
19363 res.m_type = value_t::binary;
19364 res.m_value = binary_t(init, subtype);
19368 /// @copydoc binary(const typename binary_t::container_type&)
19369 JSON_HEDLEY_WARN_UNUSED_RESULT
19370 static basic_json binary(typename binary_t::container_type&& init)
19372 auto res = basic_json();
19373 res.m_type = value_t::binary;
19374 res.m_value = std::move(init);
19378 /// @copydoc binary(const typename binary_t::container_type&, typename binary_t::subtype_type)
19379 JSON_HEDLEY_WARN_UNUSED_RESULT
19380 static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
19382 auto res = basic_json();
19383 res.m_type = value_t::binary;
19384 res.m_value = binary_t(std::move(init), subtype);
19389 @brief explicitly create an array from an initializer list
19391 Creates a JSON array value from a given initializer list. That is, given a
19392 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
19393 initializer list is empty, the empty array `[]` is created.
19395 @note This function is only needed to express two edge cases that cannot
19396 be realized with the initializer list constructor (@ref
19397 basic_json(initializer_list_t, bool, value_t)). These cases
19399 1. creating an array whose elements are all pairs whose first element is a
19400 string -- in this case, the initializer list constructor would create an
19401 object, taking the first elements as keys
19402 2. creating an empty array -- passing the empty initializer list to the
19403 initializer list constructor yields an empty object
19405 @param[in] init initializer list with JSON values to create an array from
19408 @return JSON array value
19410 @complexity Linear in the size of @a init.
19412 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19413 changes to any JSON value.
19415 @liveexample{The following code shows an example for the `array`
19418 @sa see @ref basic_json(initializer_list_t, bool, value_t) --
19419 create a JSON value from an initializer list
19420 @sa see @ref object(initializer_list_t) -- create a JSON object
19421 value from an initializer list
19423 @since version 1.0.0
19425 JSON_HEDLEY_WARN_UNUSED_RESULT
19426 static basic_json array(initializer_list_t init = {})
19428 return basic_json(init, false, value_t::array);
19432 @brief explicitly create an object from an initializer list
19434 Creates a JSON object value from a given initializer list. The initializer
19435 lists elements must be pairs, and their first elements must be strings. If
19436 the initializer list is empty, the empty object `{}` is created.
19438 @note This function is only added for symmetry reasons. In contrast to the
19439 related function @ref array(initializer_list_t), there are
19440 no cases which can only be expressed by this function. That is, any
19441 initializer list @a init can also be passed to the initializer list
19442 constructor @ref basic_json(initializer_list_t, bool, value_t).
19444 @param[in] init initializer list to create an object from (optional)
19446 @return JSON object value
19448 @throw type_error.301 if @a init is not a list of pairs whose first
19449 elements are strings. In this case, no object can be created. When such a
19450 value is passed to @ref basic_json(initializer_list_t, bool, value_t),
19451 an array would have been created from the passed initializer list @a init.
19454 @complexity Linear in the size of @a init.
19456 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19457 changes to any JSON value.
19459 @liveexample{The following code shows an example for the `object`
19462 @sa see @ref basic_json(initializer_list_t, bool, value_t) --
19463 create a JSON value from an initializer list
19464 @sa see @ref array(initializer_list_t) -- create a JSON array
19465 value from an initializer list
19467 @since version 1.0.0
19469 JSON_HEDLEY_WARN_UNUSED_RESULT
19470 static basic_json object(initializer_list_t init = {})
19472 return basic_json(init, false, value_t::object);
19476 @brief construct an array with count copies of given value
19478 Constructs a JSON array value by creating @a cnt copies of a passed value.
19479 In case @a cnt is `0`, an empty array is created.
19481 @param[in] cnt the number of JSON copies of @a val to create
19482 @param[in] val the JSON value to copy
19484 @post `std::distance(begin(),end()) == cnt` holds.
19486 @complexity Linear in @a cnt.
19488 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19489 changes to any JSON value.
19491 @liveexample{The following code shows examples for the @ref
19492 basic_json(size_type\, const basic_json&)
19493 constructor.,basic_json__size_type_basic_json}
19495 @since version 1.0.0
19497 basic_json(size_type cnt, const basic_json& val)
19498 : m_type(value_t::array)
19500 m_value.array = create<array_t>(cnt, val);
19502 assert_invariant();
19506 @brief construct a JSON container given an iterator range
19508 Constructs the JSON value with the contents of the range `[first, last)`.
19509 The semantics depends on the different types a JSON value can have:
19510 - In case of a null type, invalid_iterator.206 is thrown.
19511 - In case of other primitive types (number, boolean, or string), @a first
19512 must be `begin()` and @a last must be `end()`. In this case, the value is
19513 copied. Otherwise, invalid_iterator.204 is thrown.
19514 - In case of structured types (array, object), the constructor behaves as
19515 similar versions for `std::vector` or `std::map`; that is, a JSON array
19516 or object is constructed from the values in the range.
19518 @tparam InputIT an input iterator type (@ref iterator or @ref
19521 @param[in] first begin of the range to copy from (included)
19522 @param[in] last end of the range to copy from (excluded)
19524 @pre Iterators @a first and @a last must be initialized. **This
19525 precondition is enforced with an assertion (see warning).** If
19526 assertions are switched off, a violation of this precondition yields
19527 undefined behavior.
19529 @pre Range `[first, last)` is valid. Usually, this precondition cannot be
19530 checked efficiently. Only certain edge cases are detected; see the
19531 description of the exceptions below. A violation of this precondition
19532 yields undefined behavior.
19534 @warning A precondition is enforced with a runtime assertion that will
19535 result in calling `std::abort` if this precondition is not met.
19536 Assertions can be disabled by defining `NDEBUG` at compile time.
19537 See https://en.cppreference.com/w/cpp/error/assert for more
19540 @throw invalid_iterator.201 if iterators @a first and @a last are not
19541 compatible (i.e., do not belong to the same JSON value). In this case,
19542 the range `[first, last)` is undefined.
19543 @throw invalid_iterator.204 if iterators @a first and @a last belong to a
19544 primitive type (number, boolean, or string), but @a first does not point
19545 to the first element any more. In this case, the range `[first, last)` is
19546 undefined. See example code below.
19547 @throw invalid_iterator.206 if iterators @a first and @a last belong to a
19548 null value. In this case, the range `[first, last)` is undefined.
19550 @complexity Linear in distance between @a first and @a last.
19552 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19553 changes to any JSON value.
19555 @liveexample{The example below shows several ways to create JSON values by
19556 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
19558 @since version 1.0.0
19560 template < class InputIT, typename std::enable_if <
19561 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19562 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19563 basic_json(InputIT first, InputIT last)
19565 JSON_ASSERT(first.m_object != nullptr);
19566 JSON_ASSERT(last.m_object != nullptr);
19568 // make sure iterator fits the current value
19569 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19571 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
19574 // copy type from first iterator
19575 m_type = first.m_object->m_type;
19577 // check if iterator range is complete for primitive values
19580 case value_t::boolean:
19581 case value_t::number_float:
19582 case value_t::number_integer:
19583 case value_t::number_unsigned:
19584 case value_t::string:
19586 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19587 || !last.m_it.primitive_iterator.is_end()))
19589 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
19594 case value_t::null:
19595 case value_t::object:
19596 case value_t::array:
19597 case value_t::binary:
19598 case value_t::discarded:
19605 case value_t::number_integer:
19607 m_value.number_integer = first.m_object->m_value.number_integer;
19611 case value_t::number_unsigned:
19613 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19617 case value_t::number_float:
19619 m_value.number_float = first.m_object->m_value.number_float;
19623 case value_t::boolean:
19625 m_value.boolean = first.m_object->m_value.boolean;
19629 case value_t::string:
19631 m_value = *first.m_object->m_value.string;
19635 case value_t::object:
19637 m_value.object = create<object_t>(first.m_it.object_iterator,
19638 last.m_it.object_iterator);
19642 case value_t::array:
19644 m_value.array = create<array_t>(first.m_it.array_iterator,
19645 last.m_it.array_iterator);
19649 case value_t::binary:
19651 m_value = *first.m_object->m_value.binary;
19655 case value_t::null:
19656 case value_t::discarded:
19658 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
19662 assert_invariant();
19666 ///////////////////////////////////////
19667 // other constructors and destructor //
19668 ///////////////////////////////////////
19670 template<typename JsonRef,
19671 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
19672 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19673 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19676 @brief copy constructor
19678 Creates a copy of a given JSON value.
19680 @param[in] other the JSON value to copy
19682 @post `*this == other`
19684 @complexity Linear in the size of @a other.
19686 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19687 changes to any JSON value.
19689 @requirement This function helps `basic_json` satisfying the
19690 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19692 - The complexity is linear.
19693 - As postcondition, it holds: `other == basic_json(other)`.
19695 @liveexample{The following code shows an example for the copy
19696 constructor.,basic_json__basic_json}
19698 @since version 1.0.0
19700 basic_json(const basic_json& other)
19701 : m_type(other.m_type)
19703 // check of passed value is valid
19704 other.assert_invariant();
19708 case value_t::object:
19710 m_value = *other.m_value.object;
19714 case value_t::array:
19716 m_value = *other.m_value.array;
19720 case value_t::string:
19722 m_value = *other.m_value.string;
19726 case value_t::boolean:
19728 m_value = other.m_value.boolean;
19732 case value_t::number_integer:
19734 m_value = other.m_value.number_integer;
19738 case value_t::number_unsigned:
19740 m_value = other.m_value.number_unsigned;
19744 case value_t::number_float:
19746 m_value = other.m_value.number_float;
19750 case value_t::binary:
19752 m_value = *other.m_value.binary;
19756 case value_t::null:
19757 case value_t::discarded:
19763 assert_invariant();
19767 @brief move constructor
19769 Move constructor. Constructs a JSON value with the contents of the given
19770 value @a other using move semantics. It "steals" the resources from @a
19771 other and leaves it as JSON null value.
19773 @param[in,out] other value to move to this object
19775 @post `*this` has the same value as @a other before the call.
19776 @post @a other is a JSON null value.
19778 @complexity Constant.
19780 @exceptionsafety No-throw guarantee: this constructor never throws
19783 @requirement This function helps `basic_json` satisfying the
19784 [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
19787 @liveexample{The code below shows the move constructor explicitly called
19788 via std::move.,basic_json__moveconstructor}
19790 @since version 1.0.0
19792 basic_json(basic_json&& other) noexcept
19793 : m_type(std::move(other.m_type)),
19794 m_value(std::move(other.m_value))
19796 // check that passed value is valid
19797 other.assert_invariant(false);
19799 // invalidate payload
19800 other.m_type = value_t::null;
19801 other.m_value = {};
19804 assert_invariant();
19808 @brief copy assignment
19810 Copy assignment operator. Copies a JSON value via the "copy and swap"
19811 strategy: It is expressed in terms of the copy constructor, destructor,
19812 and the `swap()` member function.
19814 @param[in] other value to copy from
19816 @complexity Linear.
19818 @requirement This function helps `basic_json` satisfying the
19819 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19821 - The complexity is linear.
19823 @liveexample{The code below shows and example for the copy assignment. It
19824 creates a copy of value `a` which is then swapped with `b`. Finally\, the
19825 copy of `a` (which is the null value after the swap) is
19826 destroyed.,basic_json__copyassignment}
19828 @since version 1.0.0
19830 basic_json& operator=(basic_json other) noexcept (
19831 std::is_nothrow_move_constructible<value_t>::value&&
19832 std::is_nothrow_move_assignable<value_t>::value&&
19833 std::is_nothrow_move_constructible<json_value>::value&&
19834 std::is_nothrow_move_assignable<json_value>::value
19837 // check that passed value is valid
19838 other.assert_invariant();
19841 swap(m_type, other.m_type);
19842 swap(m_value, other.m_value);
19845 assert_invariant();
19852 Destroys the JSON value and frees all allocated memory.
19854 @complexity Linear.
19856 @requirement This function helps `basic_json` satisfying the
19857 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19859 - The complexity is linear.
19860 - All stored elements are destroyed and all memory is freed.
19862 @since version 1.0.0
19864 ~basic_json() noexcept
19866 assert_invariant(false);
19867 m_value.destroy(m_type);
19873 ///////////////////////
19874 // object inspection //
19875 ///////////////////////
19877 /// @name object inspection
19878 /// Functions to inspect the type of a JSON value.
19882 @brief serialization
19884 Serialization function for JSON values. The function tries to mimic
19885 Python's `json.dumps()` function, and currently supports its @a indent
19886 and @a ensure_ascii parameters.
19888 @param[in] indent If indent is nonnegative, then array elements and object
19889 members will be pretty-printed with that indent level. An indent level of
19890 `0` will only insert newlines. `-1` (the default) selects the most compact
19892 @param[in] indent_char The character to use for indentation if @a indent is
19893 greater than `0`. The default is ` ` (space).
19894 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
19895 in the output are escaped with `\uXXXX` sequences, and the result consists
19896 of ASCII characters only.
19897 @param[in] error_handler how to react on decoding errors; there are three
19898 possible values: `strict` (throws and exception in case a decoding error
19899 occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
19900 and `ignore` (ignore invalid UTF-8 sequences during serialization; all
19901 bytes are copied to the output unchanged).
19903 @return string containing the serialization of the JSON value
19905 @throw type_error.316 if a string stored inside the JSON value is not
19906 UTF-8 encoded and @a error_handler is set to strict
19908 @note Binary values are serialized as object containing two keys:
19909 - "bytes": an array of bytes as integers
19910 - "subtype": the subtype as integer or "null" if the binary has no subtype
19912 @complexity Linear.
19914 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19915 changes in the JSON value.
19917 @liveexample{The following example shows the effect of different @a indent\,
19918 @a indent_char\, and @a ensure_ascii parameters to the result of the
19919 serialization.,dump}
19921 @see https://docs.python.org/2/library/json.html#json.dump
19923 @since version 1.0.0; indentation character @a indent_char, option
19924 @a ensure_ascii and exceptions added in version 3.0.0; error
19925 handlers added in version 3.4.0; serialization of binary values added
19928 string_t dump(const int indent = -1,
19929 const char indent_char = ' ',
19930 const bool ensure_ascii = false,
19931 const error_handler_t error_handler = error_handler_t::strict) const
19934 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19938 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19942 s.dump(*this, false, ensure_ascii, 0);
19949 @brief return the type of the JSON value (explicit)
19951 Return the type of the JSON value as a value from the @ref value_t
19954 @return the type of the JSON value
19955 Value type | return value
19956 ------------------------- | -------------------------
19957 null | value_t::null
19958 boolean | value_t::boolean
19959 string | value_t::string
19960 number (integer) | value_t::number_integer
19961 number (unsigned integer) | value_t::number_unsigned
19962 number (floating-point) | value_t::number_float
19963 object | value_t::object
19964 array | value_t::array
19965 binary | value_t::binary
19966 discarded | value_t::discarded
19968 @complexity Constant.
19970 @exceptionsafety No-throw guarantee: this member function never throws
19973 @liveexample{The following code exemplifies `type()` for all JSON
19976 @sa see @ref operator value_t() -- return the type of the JSON value (implicit)
19977 @sa see @ref type_name() -- return the type as string
19979 @since version 1.0.0
19981 constexpr value_t type() const noexcept
19987 @brief return whether type is primitive
19989 This function returns true if and only if the JSON type is primitive
19990 (string, number, boolean, or null).
19992 @return `true` if type is primitive (string, number, boolean, or null),
19995 @complexity Constant.
19997 @exceptionsafety No-throw guarantee: this member function never throws
20000 @liveexample{The following code exemplifies `is_primitive()` for all JSON
20001 types.,is_primitive}
20003 @sa see @ref is_structured() -- returns whether JSON value is structured
20004 @sa see @ref is_null() -- returns whether JSON value is `null`
20005 @sa see @ref is_string() -- returns whether JSON value is a string
20006 @sa see @ref is_boolean() -- returns whether JSON value is a boolean
20007 @sa see @ref is_number() -- returns whether JSON value is a number
20008 @sa see @ref is_binary() -- returns whether JSON value is a binary array
20010 @since version 1.0.0
20012 constexpr bool is_primitive() const noexcept
20014 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
20018 @brief return whether type is structured
20020 This function returns true if and only if the JSON type is structured
20023 @return `true` if type is structured (array or object), `false` otherwise.
20025 @complexity Constant.
20027 @exceptionsafety No-throw guarantee: this member function never throws
20030 @liveexample{The following code exemplifies `is_structured()` for all JSON
20031 types.,is_structured}
20033 @sa see @ref is_primitive() -- returns whether value is primitive
20034 @sa see @ref is_array() -- returns whether value is an array
20035 @sa see @ref is_object() -- returns whether value is an object
20037 @since version 1.0.0
20039 constexpr bool is_structured() const noexcept
20041 return is_array() || is_object();
20045 @brief return whether value is null
20047 This function returns true if and only if the JSON value is null.
20049 @return `true` if type is null, `false` otherwise.
20051 @complexity Constant.
20053 @exceptionsafety No-throw guarantee: this member function never throws
20056 @liveexample{The following code exemplifies `is_null()` for all JSON
20059 @since version 1.0.0
20061 constexpr bool is_null() const noexcept
20063 return m_type == value_t::null;
20067 @brief return whether value is a boolean
20069 This function returns true if and only if the JSON value is a boolean.
20071 @return `true` if type is boolean, `false` otherwise.
20073 @complexity Constant.
20075 @exceptionsafety No-throw guarantee: this member function never throws
20078 @liveexample{The following code exemplifies `is_boolean()` for all JSON
20081 @since version 1.0.0
20083 constexpr bool is_boolean() const noexcept
20085 return m_type == value_t::boolean;
20089 @brief return whether value is a number
20091 This function returns true if and only if the JSON value is a number. This
20092 includes both integer (signed and unsigned) and floating-point values.
20094 @return `true` if type is number (regardless whether integer, unsigned
20095 integer or floating-type), `false` otherwise.
20097 @complexity Constant.
20099 @exceptionsafety No-throw guarantee: this member function never throws
20102 @liveexample{The following code exemplifies `is_number()` for all JSON
20105 @sa see @ref is_number_integer() -- check if value is an integer or unsigned
20107 @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20109 @sa see @ref is_number_float() -- check if value is a floating-point number
20111 @since version 1.0.0
20113 constexpr bool is_number() const noexcept
20115 return is_number_integer() || is_number_float();
20119 @brief return whether value is an integer number
20121 This function returns true if and only if the JSON value is a signed or
20122 unsigned integer number. This excludes floating-point values.
20124 @return `true` if type is an integer or unsigned integer number, `false`
20127 @complexity Constant.
20129 @exceptionsafety No-throw guarantee: this member function never throws
20132 @liveexample{The following code exemplifies `is_number_integer()` for all
20133 JSON types.,is_number_integer}
20135 @sa see @ref is_number() -- check if value is a number
20136 @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20138 @sa see @ref is_number_float() -- check if value is a floating-point number
20140 @since version 1.0.0
20142 constexpr bool is_number_integer() const noexcept
20144 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
20148 @brief return whether value is an unsigned integer number
20150 This function returns true if and only if the JSON value is an unsigned
20151 integer number. This excludes floating-point and signed integer values.
20153 @return `true` if type is an unsigned integer number, `false` otherwise.
20155 @complexity Constant.
20157 @exceptionsafety No-throw guarantee: this member function never throws
20160 @liveexample{The following code exemplifies `is_number_unsigned()` for all
20161 JSON types.,is_number_unsigned}
20163 @sa see @ref is_number() -- check if value is a number
20164 @sa see @ref is_number_integer() -- check if value is an integer or unsigned
20166 @sa see @ref is_number_float() -- check if value is a floating-point number
20168 @since version 2.0.0
20170 constexpr bool is_number_unsigned() const noexcept
20172 return m_type == value_t::number_unsigned;
20176 @brief return whether value is a floating-point number
20178 This function returns true if and only if the JSON value is a
20179 floating-point number. This excludes signed and unsigned integer values.
20181 @return `true` if type is a floating-point number, `false` otherwise.
20183 @complexity Constant.
20185 @exceptionsafety No-throw guarantee: this member function never throws
20188 @liveexample{The following code exemplifies `is_number_float()` for all
20189 JSON types.,is_number_float}
20191 @sa see @ref is_number() -- check if value is number
20192 @sa see @ref is_number_integer() -- check if value is an integer number
20193 @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20196 @since version 1.0.0
20198 constexpr bool is_number_float() const noexcept
20200 return m_type == value_t::number_float;
20204 @brief return whether value is an object
20206 This function returns true if and only if the JSON value is an object.
20208 @return `true` if type is object, `false` otherwise.
20210 @complexity Constant.
20212 @exceptionsafety No-throw guarantee: this member function never throws
20215 @liveexample{The following code exemplifies `is_object()` for all JSON
20218 @since version 1.0.0
20220 constexpr bool is_object() const noexcept
20222 return m_type == value_t::object;
20226 @brief return whether value is an array
20228 This function returns true if and only if the JSON value is an array.
20230 @return `true` if type is array, `false` otherwise.
20232 @complexity Constant.
20234 @exceptionsafety No-throw guarantee: this member function never throws
20237 @liveexample{The following code exemplifies `is_array()` for all JSON
20240 @since version 1.0.0
20242 constexpr bool is_array() const noexcept
20244 return m_type == value_t::array;
20248 @brief return whether value is a string
20250 This function returns true if and only if the JSON value is a string.
20252 @return `true` if type is string, `false` otherwise.
20254 @complexity Constant.
20256 @exceptionsafety No-throw guarantee: this member function never throws
20259 @liveexample{The following code exemplifies `is_string()` for all JSON
20262 @since version 1.0.0
20264 constexpr bool is_string() const noexcept
20266 return m_type == value_t::string;
20270 @brief return whether value is a binary array
20272 This function returns true if and only if the JSON value is a binary array.
20274 @return `true` if type is binary array, `false` otherwise.
20276 @complexity Constant.
20278 @exceptionsafety No-throw guarantee: this member function never throws
20281 @liveexample{The following code exemplifies `is_binary()` for all JSON
20284 @since version 3.8.0
20286 constexpr bool is_binary() const noexcept
20288 return m_type == value_t::binary;
20292 @brief return whether value is discarded
20294 This function returns true if and only if the JSON value was discarded
20295 during parsing with a callback function (see @ref parser_callback_t).
20297 @note This function will always be `false` for JSON values after parsing.
20298 That is, discarded values can only occur during parsing, but will be
20299 removed when inside a structured value or replaced by null in other cases.
20301 @return `true` if type is discarded, `false` otherwise.
20303 @complexity Constant.
20305 @exceptionsafety No-throw guarantee: this member function never throws
20308 @liveexample{The following code exemplifies `is_discarded()` for all JSON
20309 types.,is_discarded}
20311 @since version 1.0.0
20313 constexpr bool is_discarded() const noexcept
20315 return m_type == value_t::discarded;
20319 @brief return the type of the JSON value (implicit)
20321 Implicitly return the type of the JSON value as a value from the @ref
20322 value_t enumeration.
20324 @return the type of the JSON value
20326 @complexity Constant.
20328 @exceptionsafety No-throw guarantee: this member function never throws
20331 @liveexample{The following code exemplifies the @ref value_t operator for
20332 all JSON types.,operator__value_t}
20334 @sa see @ref type() -- return the type of the JSON value (explicit)
20335 @sa see @ref type_name() -- return the type as string
20337 @since version 1.0.0
20339 constexpr operator value_t() const noexcept
20351 /// get a boolean (explicit)
20352 boolean_t get_impl(boolean_t* /*unused*/) const
20354 if (JSON_HEDLEY_LIKELY(is_boolean()))
20356 return m_value.boolean;
20359 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
20362 /// get a pointer to the value (object)
20363 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20365 return is_object() ? m_value.object : nullptr;
20368 /// get a pointer to the value (object)
20369 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20371 return is_object() ? m_value.object : nullptr;
20374 /// get a pointer to the value (array)
20375 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20377 return is_array() ? m_value.array : nullptr;
20380 /// get a pointer to the value (array)
20381 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20383 return is_array() ? m_value.array : nullptr;
20386 /// get a pointer to the value (string)
20387 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20389 return is_string() ? m_value.string : nullptr;
20392 /// get a pointer to the value (string)
20393 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20395 return is_string() ? m_value.string : nullptr;
20398 /// get a pointer to the value (boolean)
20399 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20401 return is_boolean() ? &m_value.boolean : nullptr;
20404 /// get a pointer to the value (boolean)
20405 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20407 return is_boolean() ? &m_value.boolean : nullptr;
20410 /// get a pointer to the value (integer number)
20411 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
20413 return is_number_integer() ? &m_value.number_integer : nullptr;
20416 /// get a pointer to the value (integer number)
20417 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20419 return is_number_integer() ? &m_value.number_integer : nullptr;
20422 /// get a pointer to the value (unsigned number)
20423 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
20425 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20428 /// get a pointer to the value (unsigned number)
20429 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20431 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20434 /// get a pointer to the value (floating-point number)
20435 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
20437 return is_number_float() ? &m_value.number_float : nullptr;
20440 /// get a pointer to the value (floating-point number)
20441 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20443 return is_number_float() ? &m_value.number_float : nullptr;
20446 /// get a pointer to the value (binary)
20447 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20449 return is_binary() ? m_value.binary : nullptr;
20452 /// get a pointer to the value (binary)
20453 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20455 return is_binary() ? m_value.binary : nullptr;
20459 @brief helper function to implement get_ref()
20461 This function helps to implement get_ref() without code duplication for
20462 const and non-const overloads
20464 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
20466 @throw type_error.303 if ReferenceType does not match underlying value
20467 type of the current JSON
20469 template<typename ReferenceType, typename ThisType>
20470 static ReferenceType get_ref_impl(ThisType& obj)
20472 // delegate the call to get_ptr<>()
20473 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20475 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20480 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
20484 /// @name value access
20485 /// Direct access to the stored value of a JSON value.
20489 @brief get a pointer value (implicit)
20491 Implicit pointer access to the internally stored JSON value. No copies are
20494 @warning Writing data to the pointee of the result yields an undefined
20497 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
20498 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
20499 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
20502 @return pointer to the internally stored JSON value if the requested
20503 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
20505 @complexity Constant.
20507 @liveexample{The example below shows how pointers to internal values of a
20508 JSON value can be requested. Note that no type conversions are made and a
20509 `nullptr` is returned if the value and the requested pointer type does not
20512 @since version 1.0.0
20514 template<typename PointerType, typename std::enable_if<
20515 std::is_pointer<PointerType>::value, int>::type = 0>
20516 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20518 // delegate the call to get_impl_ptr<>()
20519 return get_impl_ptr(static_cast<PointerType>(nullptr));
20523 @brief get a pointer value (implicit)
20526 template < typename PointerType, typename std::enable_if <
20527 std::is_pointer<PointerType>::value&&
20528 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20529 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20531 // delegate the call to get_impl_ptr<>() const
20532 return get_impl_ptr(static_cast<PointerType>(nullptr));
20537 @brief get a value (explicit)
20539 Explicit type conversion between the JSON value and a compatible value
20540 which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
20541 and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
20542 The value is converted by calling the @ref json_serializer<ValueType>
20543 `from_json()` method.
20545 The function is equivalent to executing
20548 JSONSerializer<ValueType>::from_json(*this, ret);
20552 This overloads is chosen if:
20553 - @a ValueType is not @ref basic_json,
20554 - @ref json_serializer<ValueType> has a `from_json()` method of the form
20555 `void from_json(const basic_json&, ValueType&)`, and
20556 - @ref json_serializer<ValueType> does not have a `from_json()` method of
20557 the form `ValueType from_json(const basic_json&)`
20559 @tparam ValueType the returned value type
20561 @return copy of the JSON value, converted to @a ValueType
20563 @throw what @ref json_serializer<ValueType> `from_json()` method throws
20565 @liveexample{The example below shows several conversions from JSON values
20566 to other types. There a few things to note: (1) Floating-point numbers can
20567 be converted to integers\, (2) A JSON array can be converted to a standard
20568 `std::vector<short>`\, (3) A JSON object can be converted to C++
20569 associative containers such as `std::unordered_map<std::string\,
20570 json>`.,get__ValueType_const}
20572 @since version 2.1.0
20574 template < typename ValueType,
20575 detail::enable_if_t <
20576 detail::is_default_constructible<ValueType>::value&&
20577 detail::has_from_json<basic_json_t, ValueType>::value,
20579 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20580 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20582 auto ret = ValueType();
20583 JSONSerializer<ValueType>::from_json(*this, ret);
20588 @brief get a value (explicit); special case
20590 Explicit type conversion between the JSON value and a compatible value
20591 which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
20592 and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
20593 The value is converted by calling the @ref json_serializer<ValueType>
20594 `from_json()` method.
20596 The function is equivalent to executing
20598 return JSONSerializer<ValueType>::from_json(*this);
20601 This overloads is chosen if:
20602 - @a ValueType is not @ref basic_json and
20603 - @ref json_serializer<ValueType> has a `from_json()` method of the form
20604 `ValueType from_json(const basic_json&)`
20606 @note If @ref json_serializer<ValueType> has both overloads of
20607 `from_json()`, this one is chosen.
20609 @tparam ValueType the returned value type
20611 @return copy of the JSON value, converted to @a ValueType
20613 @throw what @ref json_serializer<ValueType> `from_json()` method throws
20615 @since version 2.1.0
20617 template < typename ValueType,
20618 detail::enable_if_t <
20619 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
20621 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20622 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20624 return JSONSerializer<ValueType>::from_json(*this);
20628 @brief get special-case overload
20630 This overloads converts the current @ref basic_json in a different
20631 @ref basic_json type
20633 @tparam BasicJsonType == @ref basic_json
20635 @return a copy of *this, converted into @a BasicJsonType
20637 @complexity Depending on the implementation of the called `from_json()`
20640 @since version 3.2.0
20642 template < typename BasicJsonType,
20643 detail::enable_if_t <
20644 detail::is_basic_json<BasicJsonType>::value,
20646 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20652 @brief get special-case overload
20654 This overloads avoids a lot of template boilerplate, it can be seen as the
20657 @tparam BasicJsonType == @ref basic_json
20659 @return a copy of *this
20661 @complexity Constant.
20663 @since version 2.1.0
20665 template<typename BasicJsonType,
20666 detail::enable_if_t<
20667 std::is_same<BasicJsonType, basic_json_t>::value,
20669 basic_json get_impl(detail::priority_tag<3> /*unused*/) const
20675 @brief get a pointer value (explicit)
20678 template<typename PointerType,
20679 detail::enable_if_t<
20680 std::is_pointer<PointerType>::value,
20682 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20683 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20685 // delegate the call to get_ptr
20686 return get_ptr<PointerType>();
20691 @brief get a (pointer) value (explicit)
20693 Performs explicit type conversion between the JSON value and a compatible value if required.
20695 - If the requested type is a pointer to the internally stored JSON value that pointer is returned.
20696 No copies are made.
20698 - If the requested type is the current @ref basic_json, or a different @ref basic_json convertible
20699 from the current @ref basic_json.
20701 - Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`
20704 @tparam ValueTypeCV the provided value type
20705 @tparam ValueType the returned value type
20707 @return copy of the JSON value, converted to @tparam ValueType if necessary
20709 @throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
20711 @since version 2.1.0
20713 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20714 #if defined(JSON_HAS_CPP_14)
20717 auto get() const noexcept(
20718 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20719 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20721 // we cannot static_assert on ValueTypeCV being non-const, because
20722 // there is support for get<const basic_json_t>(), which is why we
20723 // still need the uncvref
20724 static_assert(!std::is_reference<ValueTypeCV>::value,
20725 "get() cannot be used with reference types, you might want to use get_ref()");
20726 return get_impl<ValueType>(detail::priority_tag<4> {});
20730 @brief get a pointer value (explicit)
20732 Explicit pointer access to the internally stored JSON value. No copies are
20735 @warning The pointer becomes invalid if the underlying JSON object
20738 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
20739 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
20740 @ref number_unsigned_t, or @ref number_float_t.
20742 @return pointer to the internally stored JSON value if the requested
20743 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
20745 @complexity Constant.
20747 @liveexample{The example below shows how pointers to internal values of a
20748 JSON value can be requested. Note that no type conversions are made and a
20749 `nullptr` is returned if the value and the requested pointer type does not
20750 match.,get__PointerType}
20752 @sa see @ref get_ptr() for explicit pointer-member access
20754 @since version 1.0.0
20756 template<typename PointerType, typename std::enable_if<
20757 std::is_pointer<PointerType>::value, int>::type = 0>
20758 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20760 // delegate the call to get_ptr
20761 return get_ptr<PointerType>();
20765 @brief get a value (explicit)
20767 Explicit type conversion between the JSON value and a compatible value.
20768 The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
20769 `from_json()` method.
20771 The function is equivalent to executing
20774 JSONSerializer<ValueType>::from_json(*this, v);
20777 This overloads is chosen if:
20778 - @a ValueType is not @ref basic_json,
20779 - @ref json_serializer<ValueType> has a `from_json()` method of the form
20780 `void from_json(const basic_json&, ValueType&)`, and
20782 @tparam ValueType the input parameter type.
20784 @return the input parameter, allowing chaining calls.
20786 @throw what @ref json_serializer<ValueType> `from_json()` method throws
20788 @liveexample{The example below shows several conversions from JSON values
20789 to other types. There a few things to note: (1) Floating-point numbers can
20790 be converted to integers\, (2) A JSON array can be converted to a standard
20791 `std::vector<short>`\, (3) A JSON object can be converted to C++
20792 associative containers such as `std::unordered_map<std::string\,
20795 @since version 3.3.0
20797 template < typename ValueType,
20798 detail::enable_if_t <
20799 !detail::is_basic_json<ValueType>::value&&
20800 detail::has_from_json<basic_json_t, ValueType>::value,
20802 ValueType & get_to(ValueType& v) const noexcept(noexcept(
20803 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20805 JSONSerializer<ValueType>::from_json(*this, v);
20809 // specialization to allow to call get_to with a basic_json value
20810 // see https://github.com/nlohmann/json/issues/2175
20811 template<typename ValueType,
20812 detail::enable_if_t <
20813 detail::is_basic_json<ValueType>::value,
20815 ValueType & get_to(ValueType& v) const
20822 typename T, std::size_t N,
20823 typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20824 detail::enable_if_t <
20825 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
20826 Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20827 noexcept(noexcept(JSONSerializer<Array>::from_json(
20828 std::declval<const basic_json_t&>(), v)))
20830 JSONSerializer<Array>::from_json(*this, v);
20835 @brief get a reference value (implicit)
20837 Implicit reference access to the internally stored JSON value. No copies
20840 @warning Writing data to the referee of the result yields an undefined
20843 @tparam ReferenceType reference type; must be a reference to @ref array_t,
20844 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
20845 @ref number_float_t. Enforced by static assertion.
20847 @return reference to the internally stored JSON value if the requested
20848 reference type @a ReferenceType fits to the JSON value; throws
20849 type_error.303 otherwise
20851 @throw type_error.303 in case passed type @a ReferenceType is incompatible
20852 with the stored JSON value; see example below
20854 @complexity Constant.
20856 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
20858 @since version 1.1.0
20860 template<typename ReferenceType, typename std::enable_if<
20861 std::is_reference<ReferenceType>::value, int>::type = 0>
20862 ReferenceType get_ref()
20864 // delegate call to get_ref_impl
20865 return get_ref_impl<ReferenceType>(*this);
20869 @brief get a reference value (implicit)
20872 template < typename ReferenceType, typename std::enable_if <
20873 std::is_reference<ReferenceType>::value&&
20874 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
20875 ReferenceType get_ref() const
20877 // delegate call to get_ref_impl
20878 return get_ref_impl<ReferenceType>(*this);
20882 @brief get a value (implicit)
20884 Implicit type conversion between the JSON value and a compatible value.
20885 The call is realized by calling @ref get() const.
20887 @tparam ValueType non-pointer type compatible to the JSON value, for
20888 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
20889 `std::vector` types for JSON arrays. The character type of @ref string_t
20890 as well as an initializer list of this type is excluded to avoid
20891 ambiguities as these types implicitly convert to `std::string`.
20893 @return copy of the JSON value, converted to type @a ValueType
20895 @throw type_error.302 in case passed type @a ValueType is incompatible
20896 to the JSON value type (e.g., the JSON value is of type boolean, but a
20897 string is requested); see example below
20899 @complexity Linear in the size of the JSON value.
20901 @liveexample{The example below shows several conversions from JSON values
20902 to other types. There a few things to note: (1) Floating-point numbers can
20903 be converted to integers\, (2) A JSON array can be converted to a standard
20904 `std::vector<short>`\, (3) A JSON object can be converted to C++
20905 associative containers such as `std::unordered_map<std::string\,
20906 json>`.,operator__ValueType}
20908 @since version 1.0.0
20910 template < typename ValueType, typename std::enable_if <
20911 detail::conjunction <
20912 detail::negation<std::is_pointer<ValueType>>,
20913 detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
20914 detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
20915 detail::negation<detail::is_basic_json<ValueType>>,
20916 detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,
20918 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20919 detail::negation<std::is_same<ValueType, std::string_view>>,
20921 detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>
20922 >::value, int >::type = 0 >
20923 JSON_EXPLICIT operator ValueType() const
20925 // delegate the call to get<>() const
20926 return get<ValueType>();
20930 @return reference to the binary value
20932 @throw type_error.302 if the value is not binary
20934 @sa see @ref is_binary() to check if the value is binary
20936 @since version 3.8.0
20938 binary_t& get_binary()
20942 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20945 return *get_ptr<binary_t*>();
20948 /// @copydoc get_binary()
20949 const binary_t& get_binary() const
20953 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20956 return *get_ptr<const binary_t*>();
20962 ////////////////////
20963 // element access //
20964 ////////////////////
20966 /// @name element access
20967 /// Access to the JSON value.
20971 @brief access specified array element with bounds checking
20973 Returns a reference to the element at specified location @a idx, with
20976 @param[in] idx index of the element to access
20978 @return reference to the element at index @a idx
20980 @throw type_error.304 if the JSON value is not an array; in this case,
20981 calling `at` with an index makes no sense. See example below.
20982 @throw out_of_range.401 if the index @a idx is out of range of the array;
20983 that is, `idx >= size()`. See example below.
20985 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20986 changes in the JSON value.
20988 @complexity Constant.
20990 @since version 1.0.0
20992 @liveexample{The example below shows how array elements can be read and
20993 written using `at()`. It also demonstrates the different exceptions that
20994 can be thrown.,at__size_type}
20996 reference at(size_type idx)
20998 // at only works for arrays
20999 if (JSON_HEDLEY_LIKELY(is_array()))
21003 return set_parent(m_value.array->at(idx));
21005 JSON_CATCH (std::out_of_range&)
21007 // create better exception explanation
21008 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21013 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21018 @brief access specified array element with bounds checking
21020 Returns a const reference to the element at specified location @a idx,
21021 with bounds checking.
21023 @param[in] idx index of the element to access
21025 @return const reference to the element at index @a idx
21027 @throw type_error.304 if the JSON value is not an array; in this case,
21028 calling `at` with an index makes no sense. See example below.
21029 @throw out_of_range.401 if the index @a idx is out of range of the array;
21030 that is, `idx >= size()`. See example below.
21032 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21033 changes in the JSON value.
21035 @complexity Constant.
21037 @since version 1.0.0
21039 @liveexample{The example below shows how array elements can be read using
21040 `at()`. It also demonstrates the different exceptions that can be thrown.,
21041 at__size_type_const}
21043 const_reference at(size_type idx) const
21045 // at only works for arrays
21046 if (JSON_HEDLEY_LIKELY(is_array()))
21050 return m_value.array->at(idx);
21052 JSON_CATCH (std::out_of_range&)
21054 // create better exception explanation
21055 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21060 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21065 @brief access specified object element with bounds checking
21067 Returns a reference to the element at with specified key @a key, with
21070 @param[in] key key of the element to access
21072 @return reference to the element at key @a key
21074 @throw type_error.304 if the JSON value is not an object; in this case,
21075 calling `at` with a key makes no sense. See example below.
21076 @throw out_of_range.403 if the key @a key is is not stored in the object;
21077 that is, `find(key) == end()`. See example below.
21079 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21080 changes in the JSON value.
21082 @complexity Logarithmic in the size of the container.
21084 @sa see @ref operator[](const typename object_t::key_type&) for unchecked
21085 access by reference
21086 @sa see @ref value() for access by value with a default value
21088 @since version 1.0.0
21090 @liveexample{The example below shows how object elements can be read and
21091 written using `at()`. It also demonstrates the different exceptions that
21092 can be thrown.,at__object_t_key_type}
21094 reference at(const typename object_t::key_type& key)
21096 // at only works for objects
21097 if (JSON_HEDLEY_LIKELY(is_object()))
21101 return set_parent(m_value.object->at(key));
21103 JSON_CATCH (std::out_of_range&)
21105 // create better exception explanation
21106 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21111 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21116 @brief access specified object element with bounds checking
21118 Returns a const reference to the element at with specified key @a key,
21119 with bounds checking.
21121 @param[in] key key of the element to access
21123 @return const reference to the element at key @a key
21125 @throw type_error.304 if the JSON value is not an object; in this case,
21126 calling `at` with a key makes no sense. See example below.
21127 @throw out_of_range.403 if the key @a key is is not stored in the object;
21128 that is, `find(key) == end()`. See example below.
21130 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21131 changes in the JSON value.
21133 @complexity Logarithmic in the size of the container.
21135 @sa see @ref operator[](const typename object_t::key_type&) for unchecked
21136 access by reference
21137 @sa see @ref value() for access by value with a default value
21139 @since version 1.0.0
21141 @liveexample{The example below shows how object elements can be read using
21142 `at()`. It also demonstrates the different exceptions that can be thrown.,
21143 at__object_t_key_type_const}
21145 const_reference at(const typename object_t::key_type& key) const
21147 // at only works for objects
21148 if (JSON_HEDLEY_LIKELY(is_object()))
21152 return m_value.object->at(key);
21154 JSON_CATCH (std::out_of_range&)
21156 // create better exception explanation
21157 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21162 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21167 @brief access specified array element
21169 Returns a reference to the element at specified location @a idx.
21171 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
21172 then the array is silently filled up with `null` values to make `idx` a
21173 valid reference to the last stored element.
21175 @param[in] idx index of the element to access
21177 @return reference to the element at index @a idx
21179 @throw type_error.305 if the JSON value is not an array or null; in that
21180 cases, using the [] operator with an index makes no sense.
21182 @complexity Constant if @a idx is in the range of the array. Otherwise
21183 linear in `idx - size()`.
21185 @liveexample{The example below shows how array elements can be read and
21186 written using `[]` operator. Note the addition of `null`
21187 values.,operatorarray__size_type}
21189 @since version 1.0.0
21191 reference operator[](size_type idx)
21193 // implicitly convert null value to an empty array
21196 m_type = value_t::array;
21197 m_value.array = create<array_t>();
21198 assert_invariant();
21201 // operator[] only works for arrays
21202 if (JSON_HEDLEY_LIKELY(is_array()))
21204 // fill up array with null values if given idx is outside range
21205 if (idx >= m_value.array->size())
21207 #if JSON_DIAGNOSTICS
21208 // remember array size & capacity before resizing
21209 const auto old_size = m_value.array->size();
21210 const auto old_capacity = m_value.array->capacity();
21212 m_value.array->resize(idx + 1);
21214 #if JSON_DIAGNOSTICS
21215 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
21217 // capacity has changed: update all parents
21222 // set parent for values added above
21223 set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
21226 assert_invariant();
21229 return m_value.array->operator[](idx);
21232 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21236 @brief access specified array element
21238 Returns a const reference to the element at specified location @a idx.
21240 @param[in] idx index of the element to access
21242 @return const reference to the element at index @a idx
21244 @throw type_error.305 if the JSON value is not an array; in that case,
21245 using the [] operator with an index makes no sense.
21247 @complexity Constant.
21249 @liveexample{The example below shows how array elements can be read using
21250 the `[]` operator.,operatorarray__size_type_const}
21252 @since version 1.0.0
21254 const_reference operator[](size_type idx) const
21256 // const operator[] only works for arrays
21257 if (JSON_HEDLEY_LIKELY(is_array()))
21259 return m_value.array->operator[](idx);
21262 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21266 @brief access specified object element
21268 Returns a reference to the element at with specified key @a key.
21270 @note If @a key is not found in the object, then it is silently added to
21271 the object and filled with a `null` value to make `key` a valid reference.
21272 In case the value was `null` before, it is converted to an object.
21274 @param[in] key key of the element to access
21276 @return reference to the element at key @a key
21278 @throw type_error.305 if the JSON value is not an object or null; in that
21279 cases, using the [] operator with a key makes no sense.
21281 @complexity Logarithmic in the size of the container.
21283 @liveexample{The example below shows how object elements can be read and
21284 written using the `[]` operator.,operatorarray__key_type}
21286 @sa see @ref at(const typename object_t::key_type&) for access by reference
21287 with range checking
21288 @sa see @ref value() for access by value with a default value
21290 @since version 1.0.0
21292 reference operator[](const typename object_t::key_type& key)
21294 // implicitly convert null value to an empty object
21297 m_type = value_t::object;
21298 m_value.object = create<object_t>();
21299 assert_invariant();
21302 // operator[] only works for objects
21303 if (JSON_HEDLEY_LIKELY(is_object()))
21305 return set_parent(m_value.object->operator[](key));
21308 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21312 @brief read-only access specified object element
21314 Returns a const reference to the element at with specified key @a key. No
21315 bounds checking is performed.
21317 @warning If the element with key @a key does not exist, the behavior is
21320 @param[in] key key of the element to access
21322 @return const reference to the element at key @a key
21324 @pre The element with key @a key must exist. **This precondition is
21325 enforced with an assertion.**
21327 @throw type_error.305 if the JSON value is not an object; in that case,
21328 using the [] operator with a key makes no sense.
21330 @complexity Logarithmic in the size of the container.
21332 @liveexample{The example below shows how object elements can be read using
21333 the `[]` operator.,operatorarray__key_type_const}
21335 @sa see @ref at(const typename object_t::key_type&) for access by reference
21336 with range checking
21337 @sa see @ref value() for access by value with a default value
21339 @since version 1.0.0
21341 const_reference operator[](const typename object_t::key_type& key) const
21343 // const operator[] only works for objects
21344 if (JSON_HEDLEY_LIKELY(is_object()))
21346 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21347 return m_value.object->find(key)->second;
21350 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21354 @brief access specified object element
21356 Returns a reference to the element at with specified key @a key.
21358 @note If @a key is not found in the object, then it is silently added to
21359 the object and filled with a `null` value to make `key` a valid reference.
21360 In case the value was `null` before, it is converted to an object.
21362 @param[in] key key of the element to access
21364 @return reference to the element at key @a key
21366 @throw type_error.305 if the JSON value is not an object or null; in that
21367 cases, using the [] operator with a key makes no sense.
21369 @complexity Logarithmic in the size of the container.
21371 @liveexample{The example below shows how object elements can be read and
21372 written using the `[]` operator.,operatorarray__key_type}
21374 @sa see @ref at(const typename object_t::key_type&) for access by reference
21375 with range checking
21376 @sa see @ref value() for access by value with a default value
21378 @since version 1.1.0
21380 template<typename T>
21381 JSON_HEDLEY_NON_NULL(2)
21382 reference operator[](T* key)
21384 // implicitly convert null to object
21387 m_type = value_t::object;
21388 m_value = value_t::object;
21389 assert_invariant();
21392 // at only works for objects
21393 if (JSON_HEDLEY_LIKELY(is_object()))
21395 return set_parent(m_value.object->operator[](key));
21398 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21402 @brief read-only access specified object element
21404 Returns a const reference to the element at with specified key @a key. No
21405 bounds checking is performed.
21407 @warning If the element with key @a key does not exist, the behavior is
21410 @param[in] key key of the element to access
21412 @return const reference to the element at key @a key
21414 @pre The element with key @a key must exist. **This precondition is
21415 enforced with an assertion.**
21417 @throw type_error.305 if the JSON value is not an object; in that case,
21418 using the [] operator with a key makes no sense.
21420 @complexity Logarithmic in the size of the container.
21422 @liveexample{The example below shows how object elements can be read using
21423 the `[]` operator.,operatorarray__key_type_const}
21425 @sa see @ref at(const typename object_t::key_type&) for access by reference
21426 with range checking
21427 @sa see @ref value() for access by value with a default value
21429 @since version 1.1.0
21431 template<typename T>
21432 JSON_HEDLEY_NON_NULL(2)
21433 const_reference operator[](T* key) const
21435 // at only works for objects
21436 if (JSON_HEDLEY_LIKELY(is_object()))
21438 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21439 return m_value.object->find(key)->second;
21442 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21446 @brief access specified object element with default value
21448 Returns either a copy of an object's element at the specified key @a key
21449 or a given default value if no element with key @a key exists.
21451 The function is basically equivalent to executing
21455 } catch(out_of_range) {
21456 return default_value;
21460 @note Unlike @ref at(const typename object_t::key_type&), this function
21461 does not throw if the given key @a key was not found.
21463 @note Unlike @ref operator[](const typename object_t::key_type& key), this
21464 function does not implicitly add an element to the position defined by @a
21465 key. This function is furthermore also applicable to const objects.
21467 @param[in] key key of the element to access
21468 @param[in] default_value the value to return if @a key is not found
21470 @tparam ValueType type compatible to JSON values, for instance `int` for
21471 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
21472 JSON arrays. Note the type of the expected value at @a key and the default
21473 value @a default_value must be compatible.
21475 @return copy of the element at key @a key or @a default_value if @a key
21478 @throw type_error.302 if @a default_value does not match the type of the
21480 @throw type_error.306 if the JSON value is not an object; in that case,
21481 using `value()` with a key makes no sense.
21483 @complexity Logarithmic in the size of the container.
21485 @liveexample{The example below shows how object elements can be queried
21486 with a default value.,basic_json__value}
21488 @sa see @ref at(const typename object_t::key_type&) for access by reference
21489 with range checking
21490 @sa see @ref operator[](const typename object_t::key_type&) for unchecked
21491 access by reference
21493 @since version 1.0.0
21495 // using std::is_convertible in a std::enable_if will fail when using explicit conversions
21496 template < class ValueType, typename std::enable_if <
21497 detail::is_getable<basic_json_t, ValueType>::value
21498 && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
21499 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21501 // at only works for objects
21502 if (JSON_HEDLEY_LIKELY(is_object()))
21504 // if key is found, return value and given default value otherwise
21505 const auto it = find(key);
21508 return it->template get<ValueType>();
21511 return default_value;
21514 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21518 @brief overload for a default value of type const char*
21519 @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
21521 string_t value(const typename object_t::key_type& key, const char* default_value) const
21523 return value(key, string_t(default_value));
21527 @brief access specified object element via JSON Pointer with default value
21529 Returns either a copy of an object's element at the specified key @a key
21530 or a given default value if no element with key @a key exists.
21532 The function is basically equivalent to executing
21536 } catch(out_of_range) {
21537 return default_value;
21541 @note Unlike @ref at(const json_pointer&), this function does not throw
21542 if the given key @a key was not found.
21544 @param[in] ptr a JSON pointer to the element to access
21545 @param[in] default_value the value to return if @a ptr found no value
21547 @tparam ValueType type compatible to JSON values, for instance `int` for
21548 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
21549 JSON arrays. Note the type of the expected value at @a key and the default
21550 value @a default_value must be compatible.
21552 @return copy of the element at key @a key or @a default_value if @a key
21555 @throw type_error.302 if @a default_value does not match the type of the
21557 @throw type_error.306 if the JSON value is not an object; in that case,
21558 using `value()` with a key makes no sense.
21560 @complexity Logarithmic in the size of the container.
21562 @liveexample{The example below shows how object elements can be queried
21563 with a default value.,basic_json__value_ptr}
21565 @sa see @ref operator[](const json_pointer&) for unchecked access by reference
21567 @since version 2.0.2
21569 template<class ValueType, typename std::enable_if<
21570 detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
21571 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21573 // at only works for objects
21574 if (JSON_HEDLEY_LIKELY(is_object()))
21576 // if pointer resolves a value, return it or use default value
21579 return ptr.get_checked(this).template get<ValueType>();
21581 JSON_INTERNAL_CATCH (out_of_range&)
21583 return default_value;
21587 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21591 @brief overload for a default value of type const char*
21592 @copydoc basic_json::value(const json_pointer&, ValueType) const
21594 JSON_HEDLEY_NON_NULL(3)
21595 string_t value(const json_pointer& ptr, const char* default_value) const
21597 return value(ptr, string_t(default_value));
21601 @brief access the first element
21603 Returns a reference to the first element in the container. For a JSON
21604 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
21606 @return In case of a structured type (array or object), a reference to the
21607 first element is returned. In case of number, string, boolean, or binary
21608 values, a reference to the value is returned.
21610 @complexity Constant.
21612 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
21613 or an empty array or object (undefined behavior, **guarded by
21615 @post The JSON value remains unchanged.
21617 @throw invalid_iterator.214 when called on `null` value
21619 @liveexample{The following code shows an example for `front()`.,front}
21621 @sa see @ref back() -- access the last element
21623 @since version 1.0.0
21631 @copydoc basic_json::front()
21633 const_reference front() const
21639 @brief access the last element
21641 Returns a reference to the last element in the container. For a JSON
21642 container `c`, the expression `c.back()` is equivalent to
21644 auto tmp = c.end();
21649 @return In case of a structured type (array or object), a reference to the
21650 last element is returned. In case of number, string, boolean, or binary
21651 values, a reference to the value is returned.
21653 @complexity Constant.
21655 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
21656 or an empty array or object (undefined behavior, **guarded by
21658 @post The JSON value remains unchanged.
21660 @throw invalid_iterator.214 when called on a `null` value. See example
21663 @liveexample{The following code shows an example for `back()`.,back}
21665 @sa see @ref front() -- access the first element
21667 @since version 1.0.0
21677 @copydoc basic_json::back()
21679 const_reference back() const
21687 @brief remove element given an iterator
21689 Removes the element specified by iterator @a pos. The iterator @a pos must
21690 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
21691 but is not dereferenceable) cannot be used as a value for @a pos.
21693 If called on a primitive type other than `null`, the resulting JSON value
21696 @param[in] pos iterator to the element to remove
21697 @return Iterator following the last removed element. If the iterator @a
21698 pos refers to the last element, the `end()` iterator is returned.
21700 @tparam IteratorType an @ref iterator or @ref const_iterator
21702 @post Invalidates iterators and references at or after the point of the
21703 erase, including the `end()` iterator.
21705 @throw type_error.307 if called on a `null` value; example: `"cannot use
21706 erase() with null"`
21707 @throw invalid_iterator.202 if called on an iterator which does not belong
21708 to the current JSON value; example: `"iterator does not fit current
21710 @throw invalid_iterator.205 if called on a primitive type with invalid
21711 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
21714 @complexity The complexity depends on the type:
21715 - objects: amortized constant
21716 - arrays: linear in distance between @a pos and the end of the container
21717 - strings and binary: linear in the length of the member
21718 - other types: constant
21720 @liveexample{The example shows the result of `erase()` for different JSON
21721 types.,erase__IteratorType}
21723 @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21725 @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21726 from an object at the given key
21727 @sa see @ref erase(const size_type) -- removes the element from an array at
21730 @since version 1.0.0
21732 template < class IteratorType, typename std::enable_if <
21733 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21734 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21736 IteratorType erase(IteratorType pos)
21738 // make sure iterator fits the current value
21739 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21741 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
21744 IteratorType result = end();
21748 case value_t::boolean:
21749 case value_t::number_float:
21750 case value_t::number_integer:
21751 case value_t::number_unsigned:
21752 case value_t::string:
21753 case value_t::binary:
21755 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21757 JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
21762 AllocatorType<string_t> alloc;
21763 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21764 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21765 m_value.string = nullptr;
21767 else if (is_binary())
21769 AllocatorType<binary_t> alloc;
21770 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21771 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21772 m_value.binary = nullptr;
21775 m_type = value_t::null;
21776 assert_invariant();
21780 case value_t::object:
21782 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21786 case value_t::array:
21788 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21792 case value_t::null:
21793 case value_t::discarded:
21795 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21802 @brief remove elements given an iterator range
21804 Removes the element specified by the range `[first; last)`. The iterator
21805 @a first does not need to be dereferenceable if `first == last`: erasing
21806 an empty range is a no-op.
21808 If called on a primitive type other than `null`, the resulting JSON value
21811 @param[in] first iterator to the beginning of the range to remove
21812 @param[in] last iterator past the end of the range to remove
21813 @return Iterator following the last removed element. If the iterator @a
21814 second refers to the last element, the `end()` iterator is returned.
21816 @tparam IteratorType an @ref iterator or @ref const_iterator
21818 @post Invalidates iterators and references at or after the point of the
21819 erase, including the `end()` iterator.
21821 @throw type_error.307 if called on a `null` value; example: `"cannot use
21822 erase() with null"`
21823 @throw invalid_iterator.203 if called on iterators which does not belong
21824 to the current JSON value; example: `"iterators do not fit current value"`
21825 @throw invalid_iterator.204 if called on a primitive type with invalid
21826 iterators (i.e., if `first != begin()` and `last != end()`); example:
21827 `"iterators out of range"`
21829 @complexity The complexity depends on the type:
21830 - objects: `log(size()) + std::distance(first, last)`
21831 - arrays: linear in the distance between @a first and @a last, plus linear
21832 in the distance between @a last and end of the container
21833 - strings and binary: linear in the length of the member
21834 - other types: constant
21836 @liveexample{The example shows the result of `erase()` for different JSON
21837 types.,erase__IteratorType_IteratorType}
21839 @sa see @ref erase(IteratorType) -- removes the element at a given position
21840 @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21841 from an object at the given key
21842 @sa see @ref erase(const size_type) -- removes the element from an array at
21845 @since version 1.0.0
21847 template < class IteratorType, typename std::enable_if <
21848 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21849 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21851 IteratorType erase(IteratorType first, IteratorType last)
21853 // make sure iterator fits the current value
21854 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21856 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
21859 IteratorType result = end();
21863 case value_t::boolean:
21864 case value_t::number_float:
21865 case value_t::number_integer:
21866 case value_t::number_unsigned:
21867 case value_t::string:
21868 case value_t::binary:
21870 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21871 || !last.m_it.primitive_iterator.is_end()))
21873 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
21878 AllocatorType<string_t> alloc;
21879 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21880 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21881 m_value.string = nullptr;
21883 else if (is_binary())
21885 AllocatorType<binary_t> alloc;
21886 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21887 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21888 m_value.binary = nullptr;
21891 m_type = value_t::null;
21892 assert_invariant();
21896 case value_t::object:
21898 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21899 last.m_it.object_iterator);
21903 case value_t::array:
21905 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21906 last.m_it.array_iterator);
21910 case value_t::null:
21911 case value_t::discarded:
21913 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21920 @brief remove element from a JSON object given a key
21922 Removes elements from a JSON object with the key value @a key.
21924 @param[in] key value of the elements to remove
21926 @return Number of elements removed. If @a ObjectType is the default
21927 `std::map` type, the return value will always be `0` (@a key was not
21928 found) or `1` (@a key was found).
21930 @post References and iterators to the erased elements are invalidated.
21931 Other references and iterators are not affected.
21933 @throw type_error.307 when called on a type other than JSON object;
21934 example: `"cannot use erase() with null"`
21936 @complexity `log(size()) + count(key)`
21938 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
21940 @sa see @ref erase(IteratorType) -- removes the element at a given position
21941 @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21943 @sa see @ref erase(const size_type) -- removes the element from an array at
21946 @since version 1.0.0
21948 size_type erase(const typename object_t::key_type& key)
21950 // this erase only works for objects
21951 if (JSON_HEDLEY_LIKELY(is_object()))
21953 return m_value.object->erase(key);
21956 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21960 @brief remove element from a JSON array given an index
21962 Removes element from a JSON array at the index @a idx.
21964 @param[in] idx index of the element to remove
21966 @throw type_error.307 when called on a type other than JSON object;
21967 example: `"cannot use erase() with null"`
21968 @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
21971 @complexity Linear in distance between @a idx and the end of the container.
21973 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
21975 @sa see @ref erase(IteratorType) -- removes the element at a given position
21976 @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21978 @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21979 from an object at the given key
21981 @since version 1.0.0
21983 void erase(const size_type idx)
21985 // this erase only works for arrays
21986 if (JSON_HEDLEY_LIKELY(is_array()))
21988 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21990 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21993 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21997 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
22012 @brief find an element in a JSON object
22014 Finds an element in a JSON object with key equivalent to @a key. If the
22015 element is not found or the JSON value is not an object, end() is
22018 @note This method always returns @ref end() when executed on a JSON type
22019 that is not an object.
22021 @param[in] key key value of the element to search for.
22023 @return Iterator to an element with key equivalent to @a key. If no such
22024 element is found or the JSON value is not an object, past-the-end (see
22025 @ref end()) iterator is returned.
22027 @complexity Logarithmic in the size of the JSON object.
22029 @liveexample{The example shows how `find()` is used.,find__key_type}
22031 @sa see @ref contains(KeyT&&) const -- checks whether a key exists
22033 @since version 1.0.0
22035 template<typename KeyT>
22036 iterator find(KeyT&& key)
22038 auto result = end();
22042 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
22049 @brief find an element in a JSON object
22050 @copydoc find(KeyT&&)
22052 template<typename KeyT>
22053 const_iterator find(KeyT&& key) const
22055 auto result = cend();
22059 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
22066 @brief returns the number of occurrences of a key in a JSON object
22068 Returns the number of elements with key @a key. If ObjectType is the
22069 default `std::map` type, the return value will always be `0` (@a key was
22070 not found) or `1` (@a key was found).
22072 @note This method always returns `0` when executed on a JSON type that is
22075 @param[in] key key value of the element to count
22077 @return Number of elements with key @a key. If the JSON value is not an
22078 object, the return value will be `0`.
22080 @complexity Logarithmic in the size of the JSON object.
22082 @liveexample{The example shows how `count()` is used.,count}
22084 @since version 1.0.0
22086 template<typename KeyT>
22087 size_type count(KeyT&& key) const
22089 // return 0 for all nonobject types
22090 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
22094 @brief check the existence of an element in a JSON object
22096 Check whether an element exists in a JSON object with key equivalent to
22097 @a key. If the element is not found or the JSON value is not an object,
22100 @note This method always returns false when executed on a JSON type
22101 that is not an object.
22103 @param[in] key key value to check its existence.
22105 @return true if an element with specified @a key exists. If no such
22106 element with such key is found or the JSON value is not an object,
22109 @complexity Logarithmic in the size of the JSON object.
22111 @liveexample{The following code shows an example for `contains()`.,contains}
22113 @sa see @ref find(KeyT&&) -- returns an iterator to an object element
22114 @sa see @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
22116 @since version 3.6.0
22118 template < typename KeyT, typename std::enable_if <
22119 !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
22120 bool contains(KeyT && key) const
22122 return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
22126 @brief check the existence of an element in a JSON object given a JSON pointer
22128 Check whether the given JSON pointer @a ptr can be resolved in the current
22131 @note This method can be executed on any JSON value type.
22133 @param[in] ptr JSON pointer to check its existence.
22135 @return true if the JSON pointer can be resolved to a stored value, false
22138 @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
22140 @throw parse_error.106 if an array index begins with '0'
22141 @throw parse_error.109 if an array index was not a number
22143 @complexity Logarithmic in the size of the JSON object.
22145 @liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
22147 @sa see @ref contains(KeyT &&) const -- checks the existence of a key
22149 @since version 3.7.0
22151 bool contains(const json_pointer& ptr) const
22153 return ptr.contains(this);
22163 /// @name iterators
22167 @brief returns an iterator to the first element
22169 Returns an iterator to the first element.
22171 @image html range-begin-end.svg "Illustration from cppreference.com"
22173 @return iterator to the first element
22175 @complexity Constant.
22177 @requirement This function helps `basic_json` satisfying the
22178 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22180 - The complexity is constant.
22182 @liveexample{The following code shows an example for `begin()`.,begin}
22184 @sa see @ref cbegin() -- returns a const iterator to the beginning
22185 @sa see @ref end() -- returns an iterator to the end
22186 @sa see @ref cend() -- returns a const iterator to the end
22188 @since version 1.0.0
22190 iterator begin() noexcept
22192 iterator result(this);
22193 result.set_begin();
22198 @copydoc basic_json::cbegin()
22200 const_iterator begin() const noexcept
22206 @brief returns a const iterator to the first element
22208 Returns a const iterator to the first element.
22210 @image html range-begin-end.svg "Illustration from cppreference.com"
22212 @return const iterator to the first element
22214 @complexity Constant.
22216 @requirement This function helps `basic_json` satisfying the
22217 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22219 - The complexity is constant.
22220 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
22222 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
22224 @sa see @ref begin() -- returns an iterator to the beginning
22225 @sa see @ref end() -- returns an iterator to the end
22226 @sa see @ref cend() -- returns a const iterator to the end
22228 @since version 1.0.0
22230 const_iterator cbegin() const noexcept
22232 const_iterator result(this);
22233 result.set_begin();
22238 @brief returns an iterator to one past the last element
22240 Returns an iterator to one past the last element.
22242 @image html range-begin-end.svg "Illustration from cppreference.com"
22244 @return iterator one past the last element
22246 @complexity Constant.
22248 @requirement This function helps `basic_json` satisfying the
22249 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22251 - The complexity is constant.
22253 @liveexample{The following code shows an example for `end()`.,end}
22255 @sa see @ref cend() -- returns a const iterator to the end
22256 @sa see @ref begin() -- returns an iterator to the beginning
22257 @sa see @ref cbegin() -- returns a const iterator to the beginning
22259 @since version 1.0.0
22261 iterator end() noexcept
22263 iterator result(this);
22269 @copydoc basic_json::cend()
22271 const_iterator end() const noexcept
22277 @brief returns a const iterator to one past the last element
22279 Returns a const iterator to one past the last element.
22281 @image html range-begin-end.svg "Illustration from cppreference.com"
22283 @return const iterator one past the last element
22285 @complexity Constant.
22287 @requirement This function helps `basic_json` satisfying the
22288 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22290 - The complexity is constant.
22291 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
22293 @liveexample{The following code shows an example for `cend()`.,cend}
22295 @sa see @ref end() -- returns an iterator to the end
22296 @sa see @ref begin() -- returns an iterator to the beginning
22297 @sa see @ref cbegin() -- returns a const iterator to the beginning
22299 @since version 1.0.0
22301 const_iterator cend() const noexcept
22303 const_iterator result(this);
22309 @brief returns an iterator to the reverse-beginning
22311 Returns an iterator to the reverse-beginning; that is, the last element.
22313 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22315 @complexity Constant.
22317 @requirement This function helps `basic_json` satisfying the
22318 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22320 - The complexity is constant.
22321 - Has the semantics of `reverse_iterator(end())`.
22323 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
22325 @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22326 @sa see @ref rend() -- returns a reverse iterator to the end
22327 @sa see @ref crend() -- returns a const reverse iterator to the end
22329 @since version 1.0.0
22331 reverse_iterator rbegin() noexcept
22333 return reverse_iterator(end());
22337 @copydoc basic_json::crbegin()
22339 const_reverse_iterator rbegin() const noexcept
22345 @brief returns an iterator to the reverse-end
22347 Returns an iterator to the reverse-end; that is, one before the first
22350 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22352 @complexity Constant.
22354 @requirement This function helps `basic_json` satisfying the
22355 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22357 - The complexity is constant.
22358 - Has the semantics of `reverse_iterator(begin())`.
22360 @liveexample{The following code shows an example for `rend()`.,rend}
22362 @sa see @ref crend() -- returns a const reverse iterator to the end
22363 @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22364 @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22366 @since version 1.0.0
22368 reverse_iterator rend() noexcept
22370 return reverse_iterator(begin());
22374 @copydoc basic_json::crend()
22376 const_reverse_iterator rend() const noexcept
22382 @brief returns a const reverse iterator to the last element
22384 Returns a const iterator to the reverse-beginning; that is, the last
22387 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22389 @complexity Constant.
22391 @requirement This function helps `basic_json` satisfying the
22392 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22394 - The complexity is constant.
22395 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
22397 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
22399 @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22400 @sa see @ref rend() -- returns a reverse iterator to the end
22401 @sa see @ref crend() -- returns a const reverse iterator to the end
22403 @since version 1.0.0
22405 const_reverse_iterator crbegin() const noexcept
22407 return const_reverse_iterator(cend());
22411 @brief returns a const reverse iterator to one before the first
22413 Returns a const reverse iterator to the reverse-end; that is, one before
22416 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22418 @complexity Constant.
22420 @requirement This function helps `basic_json` satisfying the
22421 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22423 - The complexity is constant.
22424 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
22426 @liveexample{The following code shows an example for `crend()`.,crend}
22428 @sa see @ref rend() -- returns a reverse iterator to the end
22429 @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22430 @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22432 @since version 1.0.0
22434 const_reverse_iterator crend() const noexcept
22436 return const_reverse_iterator(cbegin());
22441 @brief wrapper to access iterator member functions in range-based for
22443 This function allows to access @ref iterator::key() and @ref
22444 iterator::value() during range-based for loops. In these loops, a
22445 reference to the JSON values is returned, so there is no access to the
22446 underlying iterator.
22448 For loop without iterator_wrapper:
22451 for (auto it = j_object.begin(); it != j_object.end(); ++it)
22453 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22457 Range-based for loop without iterator proxy:
22460 for (auto it : j_object)
22462 // "it" is of type json::reference and has no key() member
22463 std::cout << "value: " << it << '\n';
22467 Range-based for loop with iterator proxy:
22470 for (auto it : json::iterator_wrapper(j_object))
22472 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22476 @note When iterating over an array, `key()` will return the index of the
22477 element as string (see example).
22479 @param[in] ref reference to a JSON value
22480 @return iteration proxy object wrapping @a ref with an interface to use in
22481 range-based for loops
22483 @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
22485 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
22486 changes in the JSON value.
22488 @complexity Constant.
22490 @note The name of this function is not yet final and may change in the
22493 @deprecated This stream operator is deprecated and will be removed in
22494 future 4.0.0 of the library. Please use @ref items() instead;
22495 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
22497 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22498 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22500 return ref.items();
22504 @copydoc iterator_wrapper(reference)
22506 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22507 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22509 return ref.items();
22513 @brief helper to access iterator member functions in range-based for
22515 This function allows to access @ref iterator::key() and @ref
22516 iterator::value() during range-based for loops. In these loops, a
22517 reference to the JSON values is returned, so there is no access to the
22518 underlying iterator.
22520 For loop without `items()` function:
22523 for (auto it = j_object.begin(); it != j_object.end(); ++it)
22525 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22529 Range-based for loop without `items()` function:
22532 for (auto it : j_object)
22534 // "it" is of type json::reference and has no key() member
22535 std::cout << "value: " << it << '\n';
22539 Range-based for loop with `items()` function:
22542 for (auto& el : j_object.items())
22544 std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
22548 The `items()` function also allows to use
22549 [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
22553 for (auto& [key, val] : j_object.items())
22555 std::cout << "key: " << key << ", value:" << val << '\n';
22559 @note When iterating over an array, `key()` will return the index of the
22560 element as string (see example). For primitive types (e.g., numbers),
22561 `key()` returns an empty string.
22563 @warning Using `items()` on temporary objects is dangerous. Make sure the
22564 object's lifetime exceeds the iteration. See
22565 <https://github.com/nlohmann/json/issues/2040> for more
22568 @return iteration proxy object wrapping @a ref with an interface to use in
22569 range-based for loops
22571 @liveexample{The following code shows how the function is used.,items}
22573 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
22574 changes in the JSON value.
22576 @complexity Constant.
22578 @since version 3.1.0, structured bindings support since 3.5.0.
22580 iteration_proxy<iterator> items() noexcept
22582 return iteration_proxy<iterator>(*this);
22588 iteration_proxy<const_iterator> items() const noexcept
22590 return iteration_proxy<const_iterator>(*this);
22604 @brief checks whether the container is empty.
22606 Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
22608 @return The return value depends on the different types and is
22609 defined as follows:
22610 Value type | return value
22611 ----------- | -------------
22617 object | result of function `object_t::empty()`
22618 array | result of function `array_t::empty()`
22620 @liveexample{The following code uses `empty()` to check if a JSON
22621 object contains any elements.,empty}
22623 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22624 the Container concept; that is, their `empty()` functions have constant
22627 @iterators No changes.
22629 @exceptionsafety No-throw guarantee: this function never throws exceptions.
22631 @note This function does not return whether a string stored as JSON value
22632 is empty - it returns whether the JSON container itself is empty which is
22633 false in the case of a string.
22635 @requirement This function helps `basic_json` satisfying the
22636 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22638 - The complexity is constant.
22639 - Has the semantics of `begin() == end()`.
22641 @sa see @ref size() -- returns the number of elements
22643 @since version 1.0.0
22645 bool empty() const noexcept
22649 case value_t::null:
22651 // null values are empty
22655 case value_t::array:
22657 // delegate call to array_t::empty()
22658 return m_value.array->empty();
22661 case value_t::object:
22663 // delegate call to object_t::empty()
22664 return m_value.object->empty();
22667 case value_t::string:
22668 case value_t::boolean:
22669 case value_t::number_integer:
22670 case value_t::number_unsigned:
22671 case value_t::number_float:
22672 case value_t::binary:
22673 case value_t::discarded:
22676 // all other types are nonempty
22683 @brief returns the number of elements
22685 Returns the number of elements in a JSON value.
22687 @return The return value depends on the different types and is
22688 defined as follows:
22689 Value type | return value
22690 ----------- | -------------
22696 object | result of function object_t::size()
22697 array | result of function array_t::size()
22699 @liveexample{The following code calls `size()` on the different value
22702 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22703 the Container concept; that is, their size() functions have constant
22706 @iterators No changes.
22708 @exceptionsafety No-throw guarantee: this function never throws exceptions.
22710 @note This function does not return the length of a string stored as JSON
22711 value - it returns the number of elements in the JSON value which is 1 in
22712 the case of a string.
22714 @requirement This function helps `basic_json` satisfying the
22715 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22717 - The complexity is constant.
22718 - Has the semantics of `std::distance(begin(), end())`.
22720 @sa see @ref empty() -- checks whether the container is empty
22721 @sa see @ref max_size() -- returns the maximal number of elements
22723 @since version 1.0.0
22725 size_type size() const noexcept
22729 case value_t::null:
22731 // null values are empty
22735 case value_t::array:
22737 // delegate call to array_t::size()
22738 return m_value.array->size();
22741 case value_t::object:
22743 // delegate call to object_t::size()
22744 return m_value.object->size();
22747 case value_t::string:
22748 case value_t::boolean:
22749 case value_t::number_integer:
22750 case value_t::number_unsigned:
22751 case value_t::number_float:
22752 case value_t::binary:
22753 case value_t::discarded:
22756 // all other types have size 1
22763 @brief returns the maximum possible number of elements
22765 Returns the maximum number of elements a JSON value is able to hold due to
22766 system or library implementation limitations, i.e. `std::distance(begin(),
22767 end())` for the JSON value.
22769 @return The return value depends on the different types and is
22770 defined as follows:
22771 Value type | return value
22772 ----------- | -------------
22773 null | `0` (same as `size()`)
22774 boolean | `1` (same as `size()`)
22775 string | `1` (same as `size()`)
22776 number | `1` (same as `size()`)
22777 binary | `1` (same as `size()`)
22778 object | result of function `object_t::max_size()`
22779 array | result of function `array_t::max_size()`
22781 @liveexample{The following code calls `max_size()` on the different value
22782 types. Note the output is implementation specific.,max_size}
22784 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22785 the Container concept; that is, their `max_size()` functions have constant
22788 @iterators No changes.
22790 @exceptionsafety No-throw guarantee: this function never throws exceptions.
22792 @requirement This function helps `basic_json` satisfying the
22793 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22795 - The complexity is constant.
22796 - Has the semantics of returning `b.size()` where `b` is the largest
22797 possible JSON value.
22799 @sa see @ref size() -- returns the number of elements
22801 @since version 1.0.0
22803 size_type max_size() const noexcept
22807 case value_t::array:
22809 // delegate call to array_t::max_size()
22810 return m_value.array->max_size();
22813 case value_t::object:
22815 // delegate call to object_t::max_size()
22816 return m_value.object->max_size();
22819 case value_t::null:
22820 case value_t::string:
22821 case value_t::boolean:
22822 case value_t::number_integer:
22823 case value_t::number_unsigned:
22824 case value_t::number_float:
22825 case value_t::binary:
22826 case value_t::discarded:
22829 // all other types have max_size() == size()
22842 /// @name modifiers
22846 @brief clears the contents
22848 Clears the content of a JSON value and resets it to the default value as
22849 if @ref basic_json(value_t) would have been called with the current value
22850 type from @ref type():
22852 Value type | initial value
22853 ----------- | -------------
22858 binary | An empty byte vector
22862 @post Has the same effect as calling
22864 *this = basic_json(type());
22867 @liveexample{The example below shows the effect of `clear()` to different
22870 @complexity Linear in the size of the JSON value.
22872 @iterators All iterators, pointers and references related to this container
22875 @exceptionsafety No-throw guarantee: this function never throws exceptions.
22877 @sa see @ref basic_json(value_t) -- constructor that creates an object with the
22878 same value than calling `clear()`
22880 @since version 1.0.0
22882 void clear() noexcept
22886 case value_t::number_integer:
22888 m_value.number_integer = 0;
22892 case value_t::number_unsigned:
22894 m_value.number_unsigned = 0;
22898 case value_t::number_float:
22900 m_value.number_float = 0.0;
22904 case value_t::boolean:
22906 m_value.boolean = false;
22910 case value_t::string:
22912 m_value.string->clear();
22916 case value_t::binary:
22918 m_value.binary->clear();
22922 case value_t::array:
22924 m_value.array->clear();
22928 case value_t::object:
22930 m_value.object->clear();
22934 case value_t::null:
22935 case value_t::discarded:
22942 @brief add an object to an array
22944 Appends the given element @a val to the end of the JSON value. If the
22945 function is called on a JSON null value, an empty array is created before
22948 @param[in] val the value to add to the JSON array
22950 @throw type_error.308 when called on a type other than JSON array or
22951 null; example: `"cannot use push_back() with number"`
22953 @complexity Amortized constant.
22955 @liveexample{The example shows how `push_back()` and `+=` can be used to
22956 add elements to a JSON array. Note how the `null` value was silently
22957 converted to a JSON array.,push_back}
22959 @since version 1.0.0
22961 void push_back(basic_json&& val)
22963 // push_back only works for null objects or arrays
22964 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22966 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22969 // transform null object into an array
22972 m_type = value_t::array;
22973 m_value = value_t::array;
22974 assert_invariant();
22977 // add element to array (move semantics)
22978 const auto old_capacity = m_value.array->capacity();
22979 m_value.array->push_back(std::move(val));
22980 set_parent(m_value.array->back(), old_capacity);
22981 // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
22985 @brief add an object to an array
22986 @copydoc push_back(basic_json&&)
22988 reference operator+=(basic_json&& val)
22990 push_back(std::move(val));
22995 @brief add an object to an array
22996 @copydoc push_back(basic_json&&)
22998 void push_back(const basic_json& val)
23000 // push_back only works for null objects or arrays
23001 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23003 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
23006 // transform null object into an array
23009 m_type = value_t::array;
23010 m_value = value_t::array;
23011 assert_invariant();
23014 // add element to array
23015 const auto old_capacity = m_value.array->capacity();
23016 m_value.array->push_back(val);
23017 set_parent(m_value.array->back(), old_capacity);
23021 @brief add an object to an array
23022 @copydoc push_back(basic_json&&)
23024 reference operator+=(const basic_json& val)
23031 @brief add an object to an object
23033 Inserts the given element @a val to the JSON object. If the function is
23034 called on a JSON null value, an empty object is created before inserting
23037 @param[in] val the value to add to the JSON object
23039 @throw type_error.308 when called on a type other than JSON object or
23040 null; example: `"cannot use push_back() with number"`
23042 @complexity Logarithmic in the size of the container, O(log(`size()`)).
23044 @liveexample{The example shows how `push_back()` and `+=` can be used to
23045 add elements to a JSON object. Note how the `null` value was silently
23046 converted to a JSON object.,push_back__object_t__value}
23048 @since version 1.0.0
23050 void push_back(const typename object_t::value_type& val)
23052 // push_back only works for null objects or objects
23053 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23055 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
23058 // transform null object into an object
23061 m_type = value_t::object;
23062 m_value = value_t::object;
23063 assert_invariant();
23066 // add element to object
23067 auto res = m_value.object->insert(val);
23068 set_parent(res.first->second);
23072 @brief add an object to an object
23073 @copydoc push_back(const typename object_t::value_type&)
23075 reference operator+=(const typename object_t::value_type& val)
23082 @brief add an object to an object
23084 This function allows to use `push_back` with an initializer list. In case
23086 1. the current value is an object,
23087 2. the initializer list @a init contains only two elements, and
23088 3. the first element of @a init is a string,
23090 @a init is converted into an object element and added using
23091 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
23092 is converted to a JSON value and added using @ref push_back(basic_json&&).
23094 @param[in] init an initializer list
23096 @complexity Linear in the size of the initializer list @a init.
23098 @note This function is required to resolve an ambiguous overload error,
23099 because pairs like `{"key", "value"}` can be both interpreted as
23100 `object_t::value_type` or `std::initializer_list<basic_json>`, see
23101 https://github.com/nlohmann/json/issues/235 for more information.
23103 @liveexample{The example shows how initializer lists are treated as
23104 objects when possible.,push_back__initializer_list}
23106 void push_back(initializer_list_t init)
23108 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
23110 basic_json&& key = init.begin()->moved_or_copied();
23111 push_back(typename object_t::value_type(
23112 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
23116 push_back(basic_json(init));
23121 @brief add an object to an object
23122 @copydoc push_back(initializer_list_t)
23124 reference operator+=(initializer_list_t init)
23131 @brief add an object to an array
23133 Creates a JSON value from the passed parameters @a args to the end of the
23134 JSON value. If the function is called on a JSON null value, an empty array
23135 is created before appending the value created from @a args.
23137 @param[in] args arguments to forward to a constructor of @ref basic_json
23138 @tparam Args compatible types to create a @ref basic_json object
23140 @return reference to the inserted element
23142 @throw type_error.311 when called on a type other than JSON array or
23143 null; example: `"cannot use emplace_back() with number"`
23145 @complexity Amortized constant.
23147 @liveexample{The example shows how `push_back()` can be used to add
23148 elements to a JSON array. Note how the `null` value was silently converted
23149 to a JSON array.,emplace_back}
23151 @since version 2.0.8, returns reference since 3.7.0
23153 template<class... Args>
23154 reference emplace_back(Args&& ... args)
23156 // emplace_back only works for null objects or arrays
23157 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23159 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
23162 // transform null object into an array
23165 m_type = value_t::array;
23166 m_value = value_t::array;
23167 assert_invariant();
23170 // add element to array (perfect forwarding)
23171 const auto old_capacity = m_value.array->capacity();
23172 m_value.array->emplace_back(std::forward<Args>(args)...);
23173 return set_parent(m_value.array->back(), old_capacity);
23177 @brief add an object to an object if key does not exist
23179 Inserts a new element into a JSON object constructed in-place with the
23180 given @a args if there is no element with the key in the container. If the
23181 function is called on a JSON null value, an empty object is created before
23182 appending the value created from @a args.
23184 @param[in] args arguments to forward to a constructor of @ref basic_json
23185 @tparam Args compatible types to create a @ref basic_json object
23187 @return a pair consisting of an iterator to the inserted element, or the
23188 already-existing element if no insertion happened, and a bool
23189 denoting whether the insertion took place.
23191 @throw type_error.311 when called on a type other than JSON object or
23192 null; example: `"cannot use emplace() with number"`
23194 @complexity Logarithmic in the size of the container, O(log(`size()`)).
23196 @liveexample{The example shows how `emplace()` can be used to add elements
23197 to a JSON object. Note how the `null` value was silently converted to a
23198 JSON object. Further note how no value is added if there was already one
23199 value stored with the same key.,emplace}
23201 @since version 2.0.8
23203 template<class... Args>
23204 std::pair<iterator, bool> emplace(Args&& ... args)
23206 // emplace only works for null objects or arrays
23207 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23209 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
23212 // transform null object into an object
23215 m_type = value_t::object;
23216 m_value = value_t::object;
23217 assert_invariant();
23220 // add element to array (perfect forwarding)
23221 auto res = m_value.object->emplace(std::forward<Args>(args)...);
23222 set_parent(res.first->second);
23224 // create result iterator and set iterator to the result of emplace
23226 it.m_it.object_iterator = res.first;
23228 // return pair of iterator and boolean
23229 return {it, res.second};
23232 /// Helper for insertion of an iterator
23233 /// @note: This uses std::distance to support GCC 4.8,
23234 /// see https://github.com/nlohmann/json/pull/1257
23235 template<typename... Args>
23236 iterator insert_iterator(const_iterator pos, Args&& ... args)
23238 iterator result(this);
23239 JSON_ASSERT(m_value.array != nullptr);
23241 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
23242 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
23243 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
23245 // This could have been written as:
23246 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
23247 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
23254 @brief inserts element
23256 Inserts element @a val before iterator @a pos.
23258 @param[in] pos iterator before which the content will be inserted; may be
23260 @param[in] val element to insert
23261 @return iterator pointing to the inserted @a val.
23263 @throw type_error.309 if called on JSON values other than arrays;
23264 example: `"cannot use insert() with string"`
23265 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23266 example: `"iterator does not fit current value"`
23268 @complexity Constant plus linear in the distance between @a pos and end of
23271 @liveexample{The example shows how `insert()` is used.,insert}
23273 @since version 1.0.0
23275 iterator insert(const_iterator pos, const basic_json& val)
23277 // insert only works for arrays
23278 if (JSON_HEDLEY_LIKELY(is_array()))
23280 // check if iterator pos fits to this JSON value
23281 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23283 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23286 // insert to array and return iterator
23287 return insert_iterator(pos, val);
23290 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23294 @brief inserts element
23295 @copydoc insert(const_iterator, const basic_json&)
23297 iterator insert(const_iterator pos, basic_json&& val)
23299 return insert(pos, val);
23303 @brief inserts elements
23305 Inserts @a cnt copies of @a val before iterator @a pos.
23307 @param[in] pos iterator before which the content will be inserted; may be
23309 @param[in] cnt number of copies of @a val to insert
23310 @param[in] val element to insert
23311 @return iterator pointing to the first element inserted, or @a pos if
23314 @throw type_error.309 if called on JSON values other than arrays; example:
23315 `"cannot use insert() with string"`
23316 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23317 example: `"iterator does not fit current value"`
23319 @complexity Linear in @a cnt plus linear in the distance between @a pos
23320 and end of the container.
23322 @liveexample{The example shows how `insert()` is used.,insert__count}
23324 @since version 1.0.0
23326 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
23328 // insert only works for arrays
23329 if (JSON_HEDLEY_LIKELY(is_array()))
23331 // check if iterator pos fits to this JSON value
23332 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23334 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23337 // insert to array and return iterator
23338 return insert_iterator(pos, cnt, val);
23341 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23345 @brief inserts elements
23347 Inserts elements from range `[first, last)` before iterator @a pos.
23349 @param[in] pos iterator before which the content will be inserted; may be
23351 @param[in] first begin of the range of elements to insert
23352 @param[in] last end of the range of elements to insert
23354 @throw type_error.309 if called on JSON values other than arrays; example:
23355 `"cannot use insert() with string"`
23356 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23357 example: `"iterator does not fit current value"`
23358 @throw invalid_iterator.210 if @a first and @a last do not belong to the
23359 same JSON value; example: `"iterators do not fit"`
23360 @throw invalid_iterator.211 if @a first or @a last are iterators into
23361 container for which insert is called; example: `"passed iterators may not
23362 belong to container"`
23364 @return iterator pointing to the first element inserted, or @a pos if
23367 @complexity Linear in `std::distance(first, last)` plus linear in the
23368 distance between @a pos and end of the container.
23370 @liveexample{The example shows how `insert()` is used.,insert__range}
23372 @since version 1.0.0
23374 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
23376 // insert only works for arrays
23377 if (JSON_HEDLEY_UNLIKELY(!is_array()))
23379 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23382 // check if iterator pos fits to this JSON value
23383 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23385 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23388 // check if range iterators belong to the same JSON object
23389 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23391 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23394 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
23396 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
23399 // insert to array and return iterator
23400 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
23404 @brief inserts elements
23406 Inserts elements from initializer list @a ilist before iterator @a pos.
23408 @param[in] pos iterator before which the content will be inserted; may be
23410 @param[in] ilist initializer list to insert the values from
23412 @throw type_error.309 if called on JSON values other than arrays; example:
23413 `"cannot use insert() with string"`
23414 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23415 example: `"iterator does not fit current value"`
23417 @return iterator pointing to the first element inserted, or @a pos if
23420 @complexity Linear in `ilist.size()` plus linear in the distance between
23421 @a pos and end of the container.
23423 @liveexample{The example shows how `insert()` is used.,insert__ilist}
23425 @since version 1.0.0
23427 iterator insert(const_iterator pos, initializer_list_t ilist)
23429 // insert only works for arrays
23430 if (JSON_HEDLEY_UNLIKELY(!is_array()))
23432 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23435 // check if iterator pos fits to this JSON value
23436 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23438 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23441 // insert to array and return iterator
23442 return insert_iterator(pos, ilist.begin(), ilist.end());
23446 @brief inserts elements
23448 Inserts elements from range `[first, last)`.
23450 @param[in] first begin of the range of elements to insert
23451 @param[in] last end of the range of elements to insert
23453 @throw type_error.309 if called on JSON values other than objects; example:
23454 `"cannot use insert() with string"`
23455 @throw invalid_iterator.202 if iterator @a first or @a last does does not
23456 point to an object; example: `"iterators first and last must point to
23458 @throw invalid_iterator.210 if @a first and @a last do not belong to the
23459 same JSON value; example: `"iterators do not fit"`
23461 @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
23462 of elements to insert.
23464 @liveexample{The example shows how `insert()` is used.,insert__range_object}
23466 @since version 3.0.0
23468 void insert(const_iterator first, const_iterator last)
23470 // insert only works for objects
23471 if (JSON_HEDLEY_UNLIKELY(!is_object()))
23473 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23476 // check if range iterators belong to the same JSON object
23477 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23479 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23482 // passed iterators must belong to objects
23483 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23485 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23488 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
23492 @brief updates a JSON object from another object, overwriting existing keys
23494 Inserts all values from JSON object @a j and overwrites existing keys.
23496 @param[in] j JSON object to read values from
23497 @param[in] merge_objects when true, existing keys are not overwritten, but
23498 contents of objects are merged recursively
23501 @throw type_error.312 if called on JSON values other than objects; example:
23502 `"cannot use update() with string"`
23504 @complexity O(N*log(size() + N)), where N is the number of elements to
23507 @liveexample{The example shows how `update()` is used.,update}
23509 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
23511 @since version 3.0.0, `merge_objects` parameter added in 3.10.4.
23513 void update(const_reference j, bool merge_objects = false)
23515 update(j.begin(), j.end(), merge_objects);
23519 @brief updates a JSON object from another object, overwriting existing keys
23521 Inserts all values from from range `[first, last)` and overwrites existing
23524 @param[in] first begin of the range of elements to insert
23525 @param[in] last end of the range of elements to insert
23526 @param[in] merge_objects when true, existing keys are not overwritten, but
23527 contents of objects are merged recursively
23530 @throw type_error.312 if called on JSON values other than objects; example:
23531 `"cannot use update() with string"`
23532 @throw type_error.312 if iterator @a first or @a last does does not
23533 point to an object; example: `"cannot use update() with string"`
23534 @throw invalid_iterator.210 if @a first and @a last do not belong to the
23535 same JSON value; example: `"iterators do not fit"`
23537 @complexity O(N*log(size() + N)), where N is the number of elements to
23540 @liveexample{The example shows how `update()` is used__range.,update}
23542 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
23544 @since version 3.0.0, `merge_objects` parameter added in 3.10.4.
23546 void update(const_iterator first, const_iterator last, bool merge_objects = false)
23548 // implicitly convert null value to an empty object
23551 m_type = value_t::object;
23552 m_value.object = create<object_t>();
23553 assert_invariant();
23556 if (JSON_HEDLEY_UNLIKELY(!is_object()))
23558 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23561 // check if range iterators belong to the same JSON object
23562 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23564 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23567 // passed iterators must belong to objects
23568 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23570 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(first.m_object->type_name()), *first.m_object));
23573 for (auto it = first; it != last; ++it)
23575 if (merge_objects && it.value().is_object())
23577 auto it2 = m_value.object->find(it.key());
23578 if (it2 != m_value.object->end())
23580 it2->second.update(it.value(), true);
23584 m_value.object->operator[](it.key()) = it.value();
23585 #if JSON_DIAGNOSTICS
23586 m_value.object->operator[](it.key()).m_parent = this;
23592 @brief exchanges the values
23594 Exchanges the contents of the JSON value with those of @a other. Does not
23595 invoke any move, copy, or swap operations on individual elements. All
23596 iterators and references remain valid. The past-the-end iterator is
23599 @param[in,out] other JSON value to exchange the contents with
23601 @complexity Constant.
23603 @liveexample{The example below shows how JSON values can be swapped with
23604 `swap()`.,swap__reference}
23606 @since version 1.0.0
23608 void swap(reference other) noexcept (
23609 std::is_nothrow_move_constructible<value_t>::value&&
23610 std::is_nothrow_move_assignable<value_t>::value&&
23611 std::is_nothrow_move_constructible<json_value>::value&&
23612 std::is_nothrow_move_assignable<json_value>::value
23615 std::swap(m_type, other.m_type);
23616 std::swap(m_value, other.m_value);
23619 other.set_parents();
23620 assert_invariant();
23624 @brief exchanges the values
23626 Exchanges the contents of the JSON value from @a left with those of @a right. Does not
23627 invoke any move, copy, or swap operations on individual elements. All
23628 iterators and references remain valid. The past-the-end iterator is
23629 invalidated. implemented as a friend function callable via ADL.
23631 @param[in,out] left JSON value to exchange the contents with
23632 @param[in,out] right JSON value to exchange the contents with
23634 @complexity Constant.
23636 @liveexample{The example below shows how JSON values can be swapped with
23637 `swap()`.,swap__reference}
23639 @since version 1.0.0
23641 friend void swap(reference left, reference right) noexcept (
23642 std::is_nothrow_move_constructible<value_t>::value&&
23643 std::is_nothrow_move_assignable<value_t>::value&&
23644 std::is_nothrow_move_constructible<json_value>::value&&
23645 std::is_nothrow_move_assignable<json_value>::value
23652 @brief exchanges the values
23654 Exchanges the contents of a JSON array with those of @a other. Does not
23655 invoke any move, copy, or swap operations on individual elements. All
23656 iterators and references remain valid. The past-the-end iterator is
23659 @param[in,out] other array to exchange the contents with
23661 @throw type_error.310 when JSON value is not an array; example: `"cannot
23662 use swap() with string"`
23664 @complexity Constant.
23666 @liveexample{The example below shows how arrays can be swapped with
23667 `swap()`.,swap__array_t}
23669 @since version 1.0.0
23671 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
23673 // swap only works for arrays
23674 if (JSON_HEDLEY_LIKELY(is_array()))
23676 std::swap(*(m_value.array), other);
23680 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23685 @brief exchanges the values
23687 Exchanges the contents of a JSON object with those of @a other. Does not
23688 invoke any move, copy, or swap operations on individual elements. All
23689 iterators and references remain valid. The past-the-end iterator is
23692 @param[in,out] other object to exchange the contents with
23694 @throw type_error.310 when JSON value is not an object; example:
23695 `"cannot use swap() with string"`
23697 @complexity Constant.
23699 @liveexample{The example below shows how objects can be swapped with
23700 `swap()`.,swap__object_t}
23702 @since version 1.0.0
23704 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
23706 // swap only works for objects
23707 if (JSON_HEDLEY_LIKELY(is_object()))
23709 std::swap(*(m_value.object), other);
23713 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23718 @brief exchanges the values
23720 Exchanges the contents of a JSON string with those of @a other. Does not
23721 invoke any move, copy, or swap operations on individual elements. All
23722 iterators and references remain valid. The past-the-end iterator is
23725 @param[in,out] other string to exchange the contents with
23727 @throw type_error.310 when JSON value is not a string; example: `"cannot
23728 use swap() with boolean"`
23730 @complexity Constant.
23732 @liveexample{The example below shows how strings can be swapped with
23733 `swap()`.,swap__string_t}
23735 @since version 1.0.0
23737 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
23739 // swap only works for strings
23740 if (JSON_HEDLEY_LIKELY(is_string()))
23742 std::swap(*(m_value.string), other);
23746 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23751 @brief exchanges the values
23753 Exchanges the contents of a JSON string with those of @a other. Does not
23754 invoke any move, copy, or swap operations on individual elements. All
23755 iterators and references remain valid. The past-the-end iterator is
23758 @param[in,out] other binary to exchange the contents with
23760 @throw type_error.310 when JSON value is not a string; example: `"cannot
23761 use swap() with boolean"`
23763 @complexity Constant.
23765 @liveexample{The example below shows how strings can be swapped with
23766 `swap()`.,swap__binary_t}
23768 @since version 3.8.0
23770 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
23772 // swap only works for strings
23773 if (JSON_HEDLEY_LIKELY(is_binary()))
23775 std::swap(*(m_value.binary), other);
23779 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23783 /// @copydoc swap(binary_t&)
23784 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
23786 // swap only works for strings
23787 if (JSON_HEDLEY_LIKELY(is_binary()))
23789 std::swap(*(m_value.binary), other);
23793 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23800 //////////////////////////////////////////
23801 // lexicographical comparison operators //
23802 //////////////////////////////////////////
23804 /// @name lexicographical comparison operators
23808 @brief comparison: equal
23810 Compares two JSON values for equality according to the following rules:
23811 - Two JSON values are equal if (1) they are from the same type and (2)
23812 their stored values are the same according to their respective
23814 - Integer and floating-point numbers are automatically converted before
23815 comparison. Note that two NaN values are always treated as unequal.
23816 - Two JSON null values are equal.
23818 @note Floating-point inside JSON values numbers are compared with
23819 `json::number_float_t::operator==` which is `double::operator==` by
23820 default. To compare floating-point while respecting an epsilon, an alternative
23821 [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39)
23822 could be used, for instance
23824 template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
23825 inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
23827 return std::abs(a - b) <= epsilon;
23830 Or you can self-defined operator equal function like this:
23832 bool my_equal(const_reference lhs, const_reference rhs) {
23833 const auto lhs_type lhs.type();
23834 const auto rhs_type rhs.type();
23835 if (lhs_type == rhs_type) {
23837 // self_defined case
23838 case value_t::number_float:
23839 return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();
23840 // other cases remain the same with the original
23847 @note NaN values never compare equal to themselves or to other NaN values.
23849 @param[in] lhs first JSON value to consider
23850 @param[in] rhs second JSON value to consider
23851 @return whether the values @a lhs and @a rhs are equal
23853 @exceptionsafety No-throw guarantee: this function never throws exceptions.
23855 @complexity Linear.
23857 @liveexample{The example demonstrates comparing several JSON
23858 types.,operator__equal}
23860 @since version 1.0.0
23862 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23865 #pragma GCC diagnostic push
23866 #pragma GCC diagnostic ignored "-Wfloat-equal"
23868 const auto lhs_type = lhs.type();
23869 const auto rhs_type = rhs.type();
23871 if (lhs_type == rhs_type)
23875 case value_t::array:
23876 return *lhs.m_value.array == *rhs.m_value.array;
23878 case value_t::object:
23879 return *lhs.m_value.object == *rhs.m_value.object;
23881 case value_t::null:
23884 case value_t::string:
23885 return *lhs.m_value.string == *rhs.m_value.string;
23887 case value_t::boolean:
23888 return lhs.m_value.boolean == rhs.m_value.boolean;
23890 case value_t::number_integer:
23891 return lhs.m_value.number_integer == rhs.m_value.number_integer;
23893 case value_t::number_unsigned:
23894 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
23896 case value_t::number_float:
23897 return lhs.m_value.number_float == rhs.m_value.number_float;
23899 case value_t::binary:
23900 return *lhs.m_value.binary == *rhs.m_value.binary;
23902 case value_t::discarded:
23907 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23909 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
23911 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23913 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
23915 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23917 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
23919 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23921 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
23923 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23925 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
23927 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23929 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23934 #pragma GCC diagnostic pop
23939 @brief comparison: equal
23940 @copydoc operator==(const_reference, const_reference)
23942 template<typename ScalarType, typename std::enable_if<
23943 std::is_scalar<ScalarType>::value, int>::type = 0>
23944 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23946 return lhs == basic_json(rhs);
23950 @brief comparison: equal
23951 @copydoc operator==(const_reference, const_reference)
23953 template<typename ScalarType, typename std::enable_if<
23954 std::is_scalar<ScalarType>::value, int>::type = 0>
23955 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23957 return basic_json(lhs) == rhs;
23961 @brief comparison: not equal
23963 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
23965 @param[in] lhs first JSON value to consider
23966 @param[in] rhs second JSON value to consider
23967 @return whether the values @a lhs and @a rhs are not equal
23969 @complexity Linear.
23971 @exceptionsafety No-throw guarantee: this function never throws exceptions.
23973 @liveexample{The example demonstrates comparing several JSON
23974 types.,operator__notequal}
23976 @since version 1.0.0
23978 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23980 return !(lhs == rhs);
23984 @brief comparison: not equal
23985 @copydoc operator!=(const_reference, const_reference)
23987 template<typename ScalarType, typename std::enable_if<
23988 std::is_scalar<ScalarType>::value, int>::type = 0>
23989 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23991 return lhs != basic_json(rhs);
23995 @brief comparison: not equal
23996 @copydoc operator!=(const_reference, const_reference)
23998 template<typename ScalarType, typename std::enable_if<
23999 std::is_scalar<ScalarType>::value, int>::type = 0>
24000 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
24002 return basic_json(lhs) != rhs;
24006 @brief comparison: less than
24008 Compares whether one JSON value @a lhs is less than another JSON value @a
24009 rhs according to the following rules:
24010 - If @a lhs and @a rhs have the same type, the values are compared using
24011 the default `<` operator.
24012 - Integer and floating-point numbers are automatically converted before
24014 - In case @a lhs and @a rhs have different types, the values are ignored
24015 and the order of the types is considered, see
24016 @ref operator<(const value_t, const value_t).
24018 @param[in] lhs first JSON value to consider
24019 @param[in] rhs second JSON value to consider
24020 @return whether @a lhs is less than @a rhs
24022 @complexity Linear.
24024 @exceptionsafety No-throw guarantee: this function never throws exceptions.
24026 @liveexample{The example demonstrates comparing several JSON
24027 types.,operator__less}
24029 @since version 1.0.0
24031 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
24033 const auto lhs_type = lhs.type();
24034 const auto rhs_type = rhs.type();
24036 if (lhs_type == rhs_type)
24040 case value_t::array:
24041 // note parentheses are necessary, see
24042 // https://github.com/nlohmann/json/issues/1530
24043 return (*lhs.m_value.array) < (*rhs.m_value.array);
24045 case value_t::object:
24046 return (*lhs.m_value.object) < (*rhs.m_value.object);
24048 case value_t::null:
24051 case value_t::string:
24052 return (*lhs.m_value.string) < (*rhs.m_value.string);
24054 case value_t::boolean:
24055 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
24057 case value_t::number_integer:
24058 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
24060 case value_t::number_unsigned:
24061 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
24063 case value_t::number_float:
24064 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
24066 case value_t::binary:
24067 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
24069 case value_t::discarded:
24074 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
24076 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
24078 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
24080 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
24082 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
24084 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
24086 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
24088 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
24090 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
24092 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
24094 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
24096 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
24099 // We only reach this line if we cannot compare values. In that case,
24100 // we compare types. Note we have to call the operator explicitly,
24101 // because MSVC has problems otherwise.
24102 return operator<(lhs_type, rhs_type);
24106 @brief comparison: less than
24107 @copydoc operator<(const_reference, const_reference)
24109 template<typename ScalarType, typename std::enable_if<
24110 std::is_scalar<ScalarType>::value, int>::type = 0>
24111 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
24113 return lhs < basic_json(rhs);
24117 @brief comparison: less than
24118 @copydoc operator<(const_reference, const_reference)
24120 template<typename ScalarType, typename std::enable_if<
24121 std::is_scalar<ScalarType>::value, int>::type = 0>
24122 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
24124 return basic_json(lhs) < rhs;
24128 @brief comparison: less than or equal
24130 Compares whether one JSON value @a lhs is less than or equal to another
24131 JSON value by calculating `not (rhs < lhs)`.
24133 @param[in] lhs first JSON value to consider
24134 @param[in] rhs second JSON value to consider
24135 @return whether @a lhs is less than or equal to @a rhs
24137 @complexity Linear.
24139 @exceptionsafety No-throw guarantee: this function never throws exceptions.
24141 @liveexample{The example demonstrates comparing several JSON
24142 types.,operator__greater}
24144 @since version 1.0.0
24146 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
24148 return !(rhs < lhs);
24152 @brief comparison: less than or equal
24153 @copydoc operator<=(const_reference, const_reference)
24155 template<typename ScalarType, typename std::enable_if<
24156 std::is_scalar<ScalarType>::value, int>::type = 0>
24157 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
24159 return lhs <= basic_json(rhs);
24163 @brief comparison: less than or equal
24164 @copydoc operator<=(const_reference, const_reference)
24166 template<typename ScalarType, typename std::enable_if<
24167 std::is_scalar<ScalarType>::value, int>::type = 0>
24168 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
24170 return basic_json(lhs) <= rhs;
24174 @brief comparison: greater than
24176 Compares whether one JSON value @a lhs is greater than another
24177 JSON value by calculating `not (lhs <= rhs)`.
24179 @param[in] lhs first JSON value to consider
24180 @param[in] rhs second JSON value to consider
24181 @return whether @a lhs is greater than to @a rhs
24183 @complexity Linear.
24185 @exceptionsafety No-throw guarantee: this function never throws exceptions.
24187 @liveexample{The example demonstrates comparing several JSON
24188 types.,operator__lessequal}
24190 @since version 1.0.0
24192 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
24194 return !(lhs <= rhs);
24198 @brief comparison: greater than
24199 @copydoc operator>(const_reference, const_reference)
24201 template<typename ScalarType, typename std::enable_if<
24202 std::is_scalar<ScalarType>::value, int>::type = 0>
24203 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
24205 return lhs > basic_json(rhs);
24209 @brief comparison: greater than
24210 @copydoc operator>(const_reference, const_reference)
24212 template<typename ScalarType, typename std::enable_if<
24213 std::is_scalar<ScalarType>::value, int>::type = 0>
24214 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
24216 return basic_json(lhs) > rhs;
24220 @brief comparison: greater than or equal
24222 Compares whether one JSON value @a lhs is greater than or equal to another
24223 JSON value by calculating `not (lhs < rhs)`.
24225 @param[in] lhs first JSON value to consider
24226 @param[in] rhs second JSON value to consider
24227 @return whether @a lhs is greater than or equal to @a rhs
24229 @complexity Linear.
24231 @exceptionsafety No-throw guarantee: this function never throws exceptions.
24233 @liveexample{The example demonstrates comparing several JSON
24234 types.,operator__greaterequal}
24236 @since version 1.0.0
24238 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
24240 return !(lhs < rhs);
24244 @brief comparison: greater than or equal
24245 @copydoc operator>=(const_reference, const_reference)
24247 template<typename ScalarType, typename std::enable_if<
24248 std::is_scalar<ScalarType>::value, int>::type = 0>
24249 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
24251 return lhs >= basic_json(rhs);
24255 @brief comparison: greater than or equal
24256 @copydoc operator>=(const_reference, const_reference)
24258 template<typename ScalarType, typename std::enable_if<
24259 std::is_scalar<ScalarType>::value, int>::type = 0>
24260 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
24262 return basic_json(lhs) >= rhs;
24267 ///////////////////
24268 // serialization //
24269 ///////////////////
24271 /// @name serialization
24275 @brief serialize to stream
24277 Serialize the given JSON value @a j to the output stream @a o. The JSON
24278 value will be serialized using the @ref dump member function.
24280 - The indentation of the output can be controlled with the member variable
24281 `width` of the output stream @a o. For instance, using the manipulator
24282 `std::setw(4)` on @a o sets the indentation level to `4` and the
24283 serialization result is the same as calling `dump(4)`.
24285 - The indentation character can be controlled with the member variable
24286 `fill` of the output stream @a o. For instance, the manipulator
24287 `std::setfill('\\t')` sets indentation to use a tab character rather than
24288 the default space character.
24290 @param[in,out] o stream to serialize to
24291 @param[in] j JSON value to serialize
24293 @return the stream @a o
24295 @throw type_error.316 if a string stored inside the JSON value is not
24298 @complexity Linear.
24300 @liveexample{The example below shows the serialization with different
24301 parameters to `width` to adjust the indentation level.,operator_serialize}
24303 @since version 1.0.0; indentation character added in version 3.0.0
24305 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
24307 // read width member and use it as indentation parameter if nonzero
24308 const bool pretty_print = o.width() > 0;
24309 const auto indentation = pretty_print ? o.width() : 0;
24311 // reset width to 0 for subsequent calls to this stream
24314 // do the actual serialization
24315 serializer s(detail::output_adapter<char>(o), o.fill());
24316 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
24321 @brief serialize to stream
24322 @deprecated This stream operator is deprecated and will be removed in
24323 future 4.0.0 of the library. Please use
24324 @ref operator<<(std::ostream&, const basic_json&)
24325 instead; that is, replace calls like `j >> o;` with `o << j;`.
24326 @since version 1.0.0; deprecated since version 3.0.0
24328 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
24329 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
24333 #endif // JSON_NO_IO
24337 /////////////////////
24338 // deserialization //
24339 /////////////////////
24341 /// @name deserialization
24345 @brief deserialize from a compatible input
24347 @tparam InputType A compatible input, for instance
24348 - an std::istream object
24350 - a C-style array of characters
24351 - a pointer to a null-terminated string of single byte characters
24352 - an object obj for which begin(obj) and end(obj) produces a valid pair of
24355 @param[in] i input to read from
24356 @param[in] cb a parser callback function of type @ref parser_callback_t
24357 which is used to control the deserialization by filtering unwanted values
24359 @param[in] allow_exceptions whether to throw exceptions in case of a
24360 parse error (optional, true by default)
24361 @param[in] ignore_comments whether comments should be ignored and treated
24362 like whitespace (true) or yield a parse error (true); (optional, false by
24365 @return deserialized JSON value; in case of a parse error and
24366 @a allow_exceptions set to `false`, the return value will be
24367 value_t::discarded.
24369 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24370 of input; expected string literal""`
24371 @throw parse_error.102 if to_unicode fails or surrogate error
24372 @throw parse_error.103 if to_unicode fails
24374 @complexity Linear in the length of the input. The parser is a predictive
24375 LL(1) parser. The complexity can be higher if the parser callback function
24376 @a cb or reading from the input @a i has a super-linear complexity.
24378 @note A UTF-8 byte order mark is silently ignored.
24380 @liveexample{The example below demonstrates the `parse()` function reading
24381 from an array.,parse__array__parser_callback_t}
24383 @liveexample{The example below demonstrates the `parse()` function with
24384 and without callback function.,parse__string__parser_callback_t}
24386 @liveexample{The example below demonstrates the `parse()` function with
24387 and without callback function.,parse__istream__parser_callback_t}
24389 @liveexample{The example below demonstrates the `parse()` function reading
24390 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
24392 @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to
24395 template<typename InputType>
24396 JSON_HEDLEY_WARN_UNUSED_RESULT
24397 static basic_json parse(InputType&& i,
24398 const parser_callback_t cb = nullptr,
24399 const bool allow_exceptions = true,
24400 const bool ignore_comments = false)
24403 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
24408 @brief deserialize from a pair of character iterators
24410 The value_type of the iterator must be a integral type with size of 1, 2 or
24411 4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.
24413 @param[in] first iterator to start of character range
24414 @param[in] last iterator to end of character range
24415 @param[in] cb a parser callback function of type @ref parser_callback_t
24416 which is used to control the deserialization by filtering unwanted values
24418 @param[in] allow_exceptions whether to throw exceptions in case of a
24419 parse error (optional, true by default)
24420 @param[in] ignore_comments whether comments should be ignored and treated
24421 like whitespace (true) or yield a parse error (true); (optional, false by
24424 @return deserialized JSON value; in case of a parse error and
24425 @a allow_exceptions set to `false`, the return value will be
24426 value_t::discarded.
24428 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24429 of input; expected string literal""`
24430 @throw parse_error.102 if to_unicode fails or surrogate error
24431 @throw parse_error.103 if to_unicode fails
24433 template<typename IteratorType>
24434 JSON_HEDLEY_WARN_UNUSED_RESULT
24435 static basic_json parse(IteratorType first,
24437 const parser_callback_t cb = nullptr,
24438 const bool allow_exceptions = true,
24439 const bool ignore_comments = false)
24442 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
24446 JSON_HEDLEY_WARN_UNUSED_RESULT
24447 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
24448 static basic_json parse(detail::span_input_adapter&& i,
24449 const parser_callback_t cb = nullptr,
24450 const bool allow_exceptions = true,
24451 const bool ignore_comments = false)
24454 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
24459 @brief check if the input is valid JSON
24461 Unlike the @ref parse(InputType&&, const parser_callback_t,const bool)
24462 function, this function neither throws an exception in case of invalid JSON
24463 input (i.e., a parse error) nor creates diagnostic information.
24465 @tparam InputType A compatible input, for instance
24466 - an std::istream object
24468 - a C-style array of characters
24469 - a pointer to a null-terminated string of single byte characters
24470 - an object obj for which begin(obj) and end(obj) produces a valid pair of
24473 @param[in] i input to read from
24474 @param[in] ignore_comments whether comments should be ignored and treated
24475 like whitespace (true) or yield a parse error (true); (optional, false by
24478 @return Whether the input read from @a i is valid JSON.
24480 @complexity Linear in the length of the input. The parser is a predictive
24483 @note A UTF-8 byte order mark is silently ignored.
24485 @liveexample{The example below demonstrates the `accept()` function reading
24486 from a string.,accept__string}
24488 template<typename InputType>
24489 static bool accept(InputType&& i,
24490 const bool ignore_comments = false)
24492 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
24495 template<typename IteratorType>
24496 static bool accept(IteratorType first, IteratorType last,
24497 const bool ignore_comments = false)
24499 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
24502 JSON_HEDLEY_WARN_UNUSED_RESULT
24503 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
24504 static bool accept(detail::span_input_adapter&& i,
24505 const bool ignore_comments = false)
24507 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
24511 @brief generate SAX events
24513 The SAX event lister must follow the interface of @ref json_sax.
24515 This function reads from a compatible input. Examples are:
24516 - an std::istream object
24518 - a C-style array of characters
24519 - a pointer to a null-terminated string of single byte characters
24520 - an object obj for which begin(obj) and end(obj) produces a valid pair of
24523 @param[in] i input to read from
24524 @param[in,out] sax SAX event listener
24525 @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
24526 @param[in] strict whether the input has to be consumed completely
24527 @param[in] ignore_comments whether comments should be ignored and treated
24528 like whitespace (true) or yield a parse error (true); (optional, false by
24529 default); only applies to the JSON file format.
24531 @return return value of the last processed SAX event
24533 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24534 of input; expected string literal""`
24535 @throw parse_error.102 if to_unicode fails or surrogate error
24536 @throw parse_error.103 if to_unicode fails
24538 @complexity Linear in the length of the input. The parser is a predictive
24539 LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
24540 a super-linear complexity.
24542 @note A UTF-8 byte order mark is silently ignored.
24544 @liveexample{The example below demonstrates the `sax_parse()` function
24545 reading from string and processing the events with a user-defined SAX
24546 event consumer.,sax_parse}
24548 @since version 3.2.0
24550 template <typename InputType, typename SAX>
24551 JSON_HEDLEY_NON_NULL(2)
24552 static bool sax_parse(InputType&& i, SAX* sax,
24553 input_format_t format = input_format_t::json,
24554 const bool strict = true,
24555 const bool ignore_comments = false)
24557 auto ia = detail::input_adapter(std::forward<InputType>(i));
24558 return format == input_format_t::json
24559 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24560 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24563 template<class IteratorType, class SAX>
24564 JSON_HEDLEY_NON_NULL(3)
24565 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
24566 input_format_t format = input_format_t::json,
24567 const bool strict = true,
24568 const bool ignore_comments = false)
24570 auto ia = detail::input_adapter(std::move(first), std::move(last));
24571 return format == input_format_t::json
24572 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24573 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24576 template <typename SAX>
24577 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
24578 JSON_HEDLEY_NON_NULL(2)
24579 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
24580 input_format_t format = input_format_t::json,
24581 const bool strict = true,
24582 const bool ignore_comments = false)
24585 return format == input_format_t::json
24586 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24587 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24588 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24589 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24593 @brief deserialize from stream
24594 @deprecated This stream operator is deprecated and will be removed in
24595 version 4.0.0 of the library. Please use
24596 @ref operator>>(std::istream&, basic_json&)
24597 instead; that is, replace calls like `j << i;` with `i >> j;`.
24598 @since version 1.0.0; deprecated since version 3.0.0
24600 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
24601 friend std::istream& operator<<(basic_json& j, std::istream& i)
24603 return operator>>(i, j);
24607 @brief deserialize from stream
24609 Deserializes an input stream to a JSON value.
24611 @param[in,out] i input stream to read a serialized JSON value from
24612 @param[in,out] j JSON value to write the deserialized input to
24614 @throw parse_error.101 in case of an unexpected token
24615 @throw parse_error.102 if to_unicode fails or surrogate error
24616 @throw parse_error.103 if to_unicode fails
24618 @complexity Linear in the length of the input. The parser is a predictive
24621 @note A UTF-8 byte order mark is silently ignored.
24623 @liveexample{The example below shows how a JSON value is constructed by
24624 reading a serialization from a stream.,operator_deserialize}
24626 @sa parse(std::istream&, const parser_callback_t) for a variant with a
24627 parser callback function to filter values while parsing
24629 @since version 1.0.0
24631 friend std::istream& operator>>(std::istream& i, basic_json& j)
24633 parser(detail::input_adapter(i)).parse(false, j);
24636 #endif // JSON_NO_IO
24639 ///////////////////////////
24640 // convenience functions //
24641 ///////////////////////////
24644 @brief return the type as string
24646 Returns the type name as string to be used in error messages - usually to
24647 indicate that a function was called on a wrong JSON type.
24649 @return a string representation of a the @a m_type member:
24650 Value type | return value
24651 ----------- | -------------
24653 boolean | `"boolean"`
24654 string | `"string"`
24655 number | `"number"` (for all number types)
24656 object | `"object"`
24658 binary | `"binary"`
24659 discarded | `"discarded"`
24661 @exceptionsafety No-throw guarantee: this function never throws exceptions.
24663 @complexity Constant.
24665 @liveexample{The following code exemplifies `type_name()` for all JSON
24668 @sa see @ref type() -- return the type of the JSON value
24669 @sa see @ref operator value_t() -- return the type of the JSON value (implicit)
24671 @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
24674 JSON_HEDLEY_RETURNS_NON_NULL
24675 const char* type_name() const noexcept
24680 case value_t::null:
24682 case value_t::object:
24684 case value_t::array:
24686 case value_t::string:
24688 case value_t::boolean:
24690 case value_t::binary:
24692 case value_t::discarded:
24693 return "discarded";
24694 case value_t::number_integer:
24695 case value_t::number_unsigned:
24696 case value_t::number_float:
24704 JSON_PRIVATE_UNLESS_TESTED:
24705 //////////////////////
24706 // member variables //
24707 //////////////////////
24709 /// the type of the current element
24710 value_t m_type = value_t::null;
24712 /// the value of the current element
24713 json_value m_value = {};
24715 #if JSON_DIAGNOSTICS
24716 /// a pointer to a parent value (for debugging purposes)
24717 basic_json* m_parent = nullptr;
24720 //////////////////////////////////////////
24721 // binary serialization/deserialization //
24722 //////////////////////////////////////////
24724 /// @name binary serialization/deserialization support
24729 @brief create a CBOR serialization of a given JSON value
24731 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
24732 Binary Object Representation) serialization format. CBOR is a binary
24733 serialization format which aims to be more compact than JSON itself, yet
24734 more efficient to parse.
24736 The library uses the following mapping from JSON values types to
24737 CBOR types according to the CBOR specification (RFC 7049):
24739 JSON value type | value/range | CBOR type | first byte
24740 --------------- | ------------------------------------------ | ---------------------------------- | ---------------
24741 null | `null` | Null | 0xF6
24742 boolean | `true` | True | 0xF5
24743 boolean | `false` | False | 0xF4
24744 number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B
24745 number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A
24746 number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
24747 number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
24748 number_integer | -24..-1 | Negative integer | 0x20..0x37
24749 number_integer | 0..23 | Integer | 0x00..0x17
24750 number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
24751 number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
24752 number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
24753 number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
24754 number_unsigned | 0..23 | Integer | 0x00..0x17
24755 number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
24756 number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
24757 number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
24758 number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
24759 number_float | *any value representable by a float* | Single-Precision Float | 0xFA
24760 number_float | *any value NOT representable by a float* | Double-Precision Float | 0xFB
24761 string | *length*: 0..23 | UTF-8 string | 0x60..0x77
24762 string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
24763 string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
24764 string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A
24765 string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B
24766 array | *size*: 0..23 | array | 0x80..0x97
24767 array | *size*: 23..255 | array (1 byte follow) | 0x98
24768 array | *size*: 256..65535 | array (2 bytes follow) | 0x99
24769 array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A
24770 array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B
24771 object | *size*: 0..23 | map | 0xA0..0xB7
24772 object | *size*: 23..255 | map (1 byte follow) | 0xB8
24773 object | *size*: 256..65535 | map (2 bytes follow) | 0xB9
24774 object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA
24775 object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB
24776 binary | *size*: 0..23 | byte string | 0x40..0x57
24777 binary | *size*: 23..255 | byte string (1 byte follow) | 0x58
24778 binary | *size*: 256..65535 | byte string (2 bytes follow) | 0x59
24779 binary | *size*: 65536..4294967295 | byte string (4 bytes follow) | 0x5A
24780 binary | *size*: 4294967296..18446744073709551615 | byte string (8 bytes follow) | 0x5B
24782 Binary values with subtype are mapped to tagged values (0xD8..0xDB)
24783 depending on the subtype, followed by a byte string, see "binary" cells
24784 in the table above.
24786 @note The mapping is **complete** in the sense that any JSON value type
24787 can be converted to a CBOR value.
24789 @note If NaN or Infinity are stored inside a JSON number, they are
24790 serialized properly. This behavior differs from the @ref dump()
24791 function which serializes NaN or Infinity to `null`.
24793 @note The following CBOR types are not used in the conversion:
24794 - UTF-8 strings terminated by "break" (0x7F)
24795 - arrays terminated by "break" (0x9F)
24796 - maps terminated by "break" (0xBF)
24797 - byte strings terminated by "break" (0x5F)
24798 - date/time (0xC0..0xC1)
24799 - bignum (0xC2..0xC3)
24800 - decimal fraction (0xC4)
24802 - expected conversions (0xD5..0xD7)
24803 - simple values (0xE0..0xF3, 0xF8)
24805 - half-precision floats (0xF9)
24808 @param[in] j JSON value to serialize
24809 @return CBOR serialization as byte vector
24811 @complexity Linear in the size of the JSON value @a j.
24813 @liveexample{The example shows the serialization of a JSON value to a byte
24814 vector in CBOR format.,to_cbor}
24817 @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
24818 analogous deserialization
24819 @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
24820 @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
24821 related UBJSON format
24823 @since version 2.0.9; compact representation of floating-point numbers
24824 since version 3.8.0
24826 static std::vector<std::uint8_t> to_cbor(const basic_json& j)
24828 std::vector<std::uint8_t> result;
24829 to_cbor(j, result);
24833 static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24835 binary_writer<std::uint8_t>(o).write_cbor(j);
24838 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
24840 binary_writer<char>(o).write_cbor(j);
24844 @brief create a MessagePack serialization of a given JSON value
24846 Serializes a given JSON value @a j to a byte vector using the MessagePack
24847 serialization format. MessagePack is a binary serialization format which
24848 aims to be more compact than JSON itself, yet more efficient to parse.
24850 The library uses the following mapping from JSON values types to
24851 MessagePack types according to the MessagePack specification:
24853 JSON value type | value/range | MessagePack type | first byte
24854 --------------- | --------------------------------- | ---------------- | ----------
24855 null | `null` | nil | 0xC0
24856 boolean | `true` | true | 0xC3
24857 boolean | `false` | false | 0xC2
24858 number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3
24859 number_integer | -2147483648..-32769 | int32 | 0xD2
24860 number_integer | -32768..-129 | int16 | 0xD1
24861 number_integer | -128..-33 | int8 | 0xD0
24862 number_integer | -32..-1 | negative fixint | 0xE0..0xFF
24863 number_integer | 0..127 | positive fixint | 0x00..0x7F
24864 number_integer | 128..255 | uint 8 | 0xCC
24865 number_integer | 256..65535 | uint 16 | 0xCD
24866 number_integer | 65536..4294967295 | uint 32 | 0xCE
24867 number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF
24868 number_unsigned | 0..127 | positive fixint | 0x00..0x7F
24869 number_unsigned | 128..255 | uint 8 | 0xCC
24870 number_unsigned | 256..65535 | uint 16 | 0xCD
24871 number_unsigned | 65536..4294967295 | uint 32 | 0xCE
24872 number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
24873 number_float | *any value representable by a float* | float 32 | 0xCA
24874 number_float | *any value NOT representable by a float* | float 64 | 0xCB
24875 string | *length*: 0..31 | fixstr | 0xA0..0xBF
24876 string | *length*: 32..255 | str 8 | 0xD9
24877 string | *length*: 256..65535 | str 16 | 0xDA
24878 string | *length*: 65536..4294967295 | str 32 | 0xDB
24879 array | *size*: 0..15 | fixarray | 0x90..0x9F
24880 array | *size*: 16..65535 | array 16 | 0xDC
24881 array | *size*: 65536..4294967295 | array 32 | 0xDD
24882 object | *size*: 0..15 | fix map | 0x80..0x8F
24883 object | *size*: 16..65535 | map 16 | 0xDE
24884 object | *size*: 65536..4294967295 | map 32 | 0xDF
24885 binary | *size*: 0..255 | bin 8 | 0xC4
24886 binary | *size*: 256..65535 | bin 16 | 0xC5
24887 binary | *size*: 65536..4294967295 | bin 32 | 0xC6
24889 @note The mapping is **complete** in the sense that any JSON value type
24890 can be converted to a MessagePack value.
24892 @note The following values can **not** be converted to a MessagePack value:
24893 - strings with more than 4294967295 bytes
24894 - byte strings with more than 4294967295 bytes
24895 - arrays with more than 4294967295 elements
24896 - objects with more than 4294967295 elements
24898 @note Any MessagePack output created @ref to_msgpack can be successfully
24899 parsed by @ref from_msgpack.
24901 @note If NaN or Infinity are stored inside a JSON number, they are
24902 serialized properly. This behavior differs from the @ref dump()
24903 function which serializes NaN or Infinity to `null`.
24905 @param[in] j JSON value to serialize
24906 @return MessagePack serialization as byte vector
24908 @complexity Linear in the size of the JSON value @a j.
24910 @liveexample{The example shows the serialization of a JSON value to a byte
24911 vector in MessagePack format.,to_msgpack}
24913 @sa http://msgpack.org
24914 @sa see @ref from_msgpack for the analogous deserialization
24915 @sa see @ref to_cbor(const basic_json& for the related CBOR format
24916 @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
24917 related UBJSON format
24919 @since version 2.0.9
24921 static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
24923 std::vector<std::uint8_t> result;
24924 to_msgpack(j, result);
24928 static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24930 binary_writer<std::uint8_t>(o).write_msgpack(j);
24933 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
24935 binary_writer<char>(o).write_msgpack(j);
24939 @brief create a UBJSON serialization of a given JSON value
24941 Serializes a given JSON value @a j to a byte vector using the UBJSON
24942 (Universal Binary JSON) serialization format. UBJSON aims to be more compact
24943 than JSON itself, yet more efficient to parse.
24945 The library uses the following mapping from JSON values types to
24946 UBJSON types according to the UBJSON specification:
24948 JSON value type | value/range | UBJSON type | marker
24949 --------------- | --------------------------------- | ----------- | ------
24950 null | `null` | null | `Z`
24951 boolean | `true` | true | `T`
24952 boolean | `false` | false | `F`
24953 number_integer | -9223372036854775808..-2147483649 | int64 | `L`
24954 number_integer | -2147483648..-32769 | int32 | `l`
24955 number_integer | -32768..-129 | int16 | `I`
24956 number_integer | -128..127 | int8 | `i`
24957 number_integer | 128..255 | uint8 | `U`
24958 number_integer | 256..32767 | int16 | `I`
24959 number_integer | 32768..2147483647 | int32 | `l`
24960 number_integer | 2147483648..9223372036854775807 | int64 | `L`
24961 number_unsigned | 0..127 | int8 | `i`
24962 number_unsigned | 128..255 | uint8 | `U`
24963 number_unsigned | 256..32767 | int16 | `I`
24964 number_unsigned | 32768..2147483647 | int32 | `l`
24965 number_unsigned | 2147483648..9223372036854775807 | int64 | `L`
24966 number_unsigned | 2147483649..18446744073709551615 | high-precision | `H`
24967 number_float | *any value* | float64 | `D`
24968 string | *with shortest length indicator* | string | `S`
24969 array | *see notes on optimized format* | array | `[`
24970 object | *see notes on optimized format* | map | `{`
24972 @note The mapping is **complete** in the sense that any JSON value type
24973 can be converted to a UBJSON value.
24975 @note The following values can **not** be converted to a UBJSON value:
24976 - strings with more than 9223372036854775807 bytes (theoretical)
24978 @note The following markers are not used in the conversion:
24979 - `Z`: no-op values are not created.
24980 - `C`: single-byte strings are serialized with `S` markers.
24982 @note Any UBJSON output created @ref to_ubjson can be successfully parsed
24983 by @ref from_ubjson.
24985 @note If NaN or Infinity are stored inside a JSON number, they are
24986 serialized properly. This behavior differs from the @ref dump()
24987 function which serializes NaN or Infinity to `null`.
24989 @note The optimized formats for containers are supported: Parameter
24990 @a use_size adds size information to the beginning of a container and
24991 removes the closing marker. Parameter @a use_type further checks
24992 whether all elements of a container have the same type and adds the
24993 type marker to the beginning of the container. The @a use_type
24994 parameter must only be used together with @a use_size = true. Note
24995 that @a use_size = true alone may result in larger representations -
24996 the benefit of this parameter is that the receiving side is
24997 immediately informed on the number of elements of the container.
24999 @note If the JSON data contains the binary type, the value stored is a list
25000 of integers, as suggested by the UBJSON documentation. In particular,
25001 this means that serialization and the deserialization of a JSON
25002 containing binary values into UBJSON and back will result in a
25003 different JSON object.
25005 @param[in] j JSON value to serialize
25006 @param[in] use_size whether to add size annotations to container types
25007 @param[in] use_type whether to add type annotations to container types
25008 (must be combined with @a use_size = true)
25009 @return UBJSON serialization as byte vector
25011 @complexity Linear in the size of the JSON value @a j.
25013 @liveexample{The example shows the serialization of a JSON value to a byte
25014 vector in UBJSON format.,to_ubjson}
25016 @sa http://ubjson.org
25017 @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
25018 analogous deserialization
25019 @sa see @ref to_cbor(const basic_json& for the related CBOR format
25020 @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
25022 @since version 3.1.0
25024 static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
25025 const bool use_size = false,
25026 const bool use_type = false)
25028 std::vector<std::uint8_t> result;
25029 to_ubjson(j, result, use_size, use_type);
25033 static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,
25034 const bool use_size = false, const bool use_type = false)
25036 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
25039 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
25040 const bool use_size = false, const bool use_type = false)
25042 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
25047 @brief Serializes the given JSON object `j` to BSON and returns a vector
25048 containing the corresponding BSON-representation.
25050 BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
25051 stored as a single entity (a so-called document).
25053 The library uses the following mapping from JSON values types to BSON types:
25055 JSON value type | value/range | BSON type | marker
25056 --------------- | --------------------------------- | ----------- | ------
25057 null | `null` | null | 0x0A
25058 boolean | `true`, `false` | boolean | 0x08
25059 number_integer | -9223372036854775808..-2147483649 | int64 | 0x12
25060 number_integer | -2147483648..2147483647 | int32 | 0x10
25061 number_integer | 2147483648..9223372036854775807 | int64 | 0x12
25062 number_unsigned | 0..2147483647 | int32 | 0x10
25063 number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12
25064 number_unsigned | 9223372036854775808..18446744073709551615| -- | --
25065 number_float | *any value* | double | 0x01
25066 string | *any value* | string | 0x02
25067 array | *any value* | document | 0x04
25068 object | *any value* | document | 0x03
25069 binary | *any value* | binary | 0x05
25071 @warning The mapping is **incomplete**, since only JSON-objects (and things
25072 contained therein) can be serialized to BSON.
25073 Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
25074 and the keys may not contain U+0000, since they are serialized a
25075 zero-terminated c-strings.
25077 @throw out_of_range.407 if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
25078 @throw out_of_range.409 if a key in `j` contains a NULL (U+0000)
25079 @throw type_error.317 if `!j.is_object()`
25081 @pre The input `j` is required to be an object: `j.is_object() == true`.
25083 @note Any BSON output created via @ref to_bson can be successfully parsed
25086 @param[in] j JSON value to serialize
25087 @return BSON serialization as byte vector
25089 @complexity Linear in the size of the JSON value @a j.
25091 @liveexample{The example shows the serialization of a JSON value to a byte
25092 vector in BSON format.,to_bson}
25094 @sa http://bsonspec.org/spec.html
25095 @sa see @ref from_bson(detail::input_adapter&&, const bool strict) for the
25096 analogous deserialization
25097 @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
25098 related UBJSON format
25099 @sa see @ref to_cbor(const basic_json&) for the related CBOR format
25100 @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
25102 static std::vector<std::uint8_t> to_bson(const basic_json& j)
25104 std::vector<std::uint8_t> result;
25105 to_bson(j, result);
25110 @brief Serializes the given JSON object `j` to BSON and forwards the
25111 corresponding BSON-representation to the given output_adapter `o`.
25112 @param j The JSON object to convert to BSON.
25113 @param o The output adapter that receives the binary BSON representation.
25114 @pre The input `j` shall be an object: `j.is_object() == true`
25115 @sa see @ref to_bson(const basic_json&)
25117 static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)
25119 binary_writer<std::uint8_t>(o).write_bson(j);
25123 @copydoc to_bson(const basic_json&, detail::output_adapter<std::uint8_t>)
25125 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
25127 binary_writer<char>(o).write_bson(j);
25132 @brief create a JSON value from an input in CBOR format
25134 Deserializes a given input @a i to a JSON value using the CBOR (Concise
25135 Binary Object Representation) serialization format.
25137 The library maps CBOR types to JSON value types as follows:
25139 CBOR type | JSON value type | first byte
25140 ---------------------- | --------------- | ----------
25141 Integer | number_unsigned | 0x00..0x17
25142 Unsigned integer | number_unsigned | 0x18
25143 Unsigned integer | number_unsigned | 0x19
25144 Unsigned integer | number_unsigned | 0x1A
25145 Unsigned integer | number_unsigned | 0x1B
25146 Negative integer | number_integer | 0x20..0x37
25147 Negative integer | number_integer | 0x38
25148 Negative integer | number_integer | 0x39
25149 Negative integer | number_integer | 0x3A
25150 Negative integer | number_integer | 0x3B
25151 Byte string | binary | 0x40..0x57
25152 Byte string | binary | 0x58
25153 Byte string | binary | 0x59
25154 Byte string | binary | 0x5A
25155 Byte string | binary | 0x5B
25156 UTF-8 string | string | 0x60..0x77
25157 UTF-8 string | string | 0x78
25158 UTF-8 string | string | 0x79
25159 UTF-8 string | string | 0x7A
25160 UTF-8 string | string | 0x7B
25161 UTF-8 string | string | 0x7F
25162 array | array | 0x80..0x97
25163 array | array | 0x98
25164 array | array | 0x99
25165 array | array | 0x9A
25166 array | array | 0x9B
25167 array | array | 0x9F
25168 map | object | 0xA0..0xB7
25169 map | object | 0xB8
25170 map | object | 0xB9
25171 map | object | 0xBA
25172 map | object | 0xBB
25173 map | object | 0xBF
25174 False | `false` | 0xF4
25175 True | `true` | 0xF5
25176 Null | `null` | 0xF6
25177 Half-Precision Float | number_float | 0xF9
25178 Single-Precision Float | number_float | 0xFA
25179 Double-Precision Float | number_float | 0xFB
25181 @warning The mapping is **incomplete** in the sense that not all CBOR
25182 types can be converted to a JSON value. The following CBOR types
25183 are not supported and will yield parse errors (parse_error.112):
25184 - date/time (0xC0..0xC1)
25185 - bignum (0xC2..0xC3)
25186 - decimal fraction (0xC4)
25188 - expected conversions (0xD5..0xD7)
25189 - simple values (0xE0..0xF3, 0xF8)
25192 @warning CBOR allows map keys of any type, whereas JSON only allows
25193 strings as keys in object values. Therefore, CBOR maps with keys
25194 other than UTF-8 strings are rejected (parse_error.113).
25196 @note Any CBOR output created @ref to_cbor can be successfully parsed by
25199 @param[in] i an input in CBOR format convertible to an input adapter
25200 @param[in] strict whether to expect the input to be consumed until EOF
25202 @param[in] allow_exceptions whether to throw exceptions in case of a
25203 parse error (optional, true by default)
25204 @param[in] tag_handler how to treat CBOR tags (optional, error by default)
25206 @return deserialized JSON value; in case of a parse error and
25207 @a allow_exceptions set to `false`, the return value will be
25208 value_t::discarded.
25210 @throw parse_error.110 if the given input ends prematurely or the end of
25211 file was not reached when @a strict was set to true
25212 @throw parse_error.112 if unsupported features from CBOR were
25213 used in the given input @a v or if the input is not valid CBOR
25214 @throw parse_error.113 if a string was expected as map key, but not found
25216 @complexity Linear in the size of the input @a i.
25218 @liveexample{The example shows the deserialization of a byte vector in CBOR
25219 format to a JSON value.,from_cbor}
25222 @sa see @ref to_cbor(const basic_json&) for the analogous serialization
25223 @sa see @ref from_msgpack(InputType&&, const bool, const bool) for the
25224 related MessagePack format
25225 @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
25226 related UBJSON format
25228 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
25229 consume input adapters, removed start_index parameter, and added
25230 @a strict parameter since 3.0.0; added @a allow_exceptions parameter
25231 since 3.2.0; added @a tag_handler parameter since 3.9.0.
25233 template<typename InputType>
25234 JSON_HEDLEY_WARN_UNUSED_RESULT
25235 static basic_json from_cbor(InputType&& i,
25236 const bool strict = true,
25237 const bool allow_exceptions = true,
25238 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25241 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25242 auto ia = detail::input_adapter(std::forward<InputType>(i));
25243 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25244 return res ? result : basic_json(value_t::discarded);
25248 @copydoc from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t)
25250 template<typename IteratorType>
25251 JSON_HEDLEY_WARN_UNUSED_RESULT
25252 static basic_json from_cbor(IteratorType first, IteratorType last,
25253 const bool strict = true,
25254 const bool allow_exceptions = true,
25255 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25258 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25259 auto ia = detail::input_adapter(std::move(first), std::move(last));
25260 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25261 return res ? result : basic_json(value_t::discarded);
25264 template<typename T>
25265 JSON_HEDLEY_WARN_UNUSED_RESULT
25266 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25267 static basic_json from_cbor(const T* ptr, std::size_t len,
25268 const bool strict = true,
25269 const bool allow_exceptions = true,
25270 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25272 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
25276 JSON_HEDLEY_WARN_UNUSED_RESULT
25277 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25278 static basic_json from_cbor(detail::span_input_adapter&& i,
25279 const bool strict = true,
25280 const bool allow_exceptions = true,
25281 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25284 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25286 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25287 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25288 return res ? result : basic_json(value_t::discarded);
25292 @brief create a JSON value from an input in MessagePack format
25294 Deserializes a given input @a i to a JSON value using the MessagePack
25295 serialization format.
25297 The library maps MessagePack types to JSON value types as follows:
25299 MessagePack type | JSON value type | first byte
25300 ---------------- | --------------- | ----------
25301 positive fixint | number_unsigned | 0x00..0x7F
25302 fixmap | object | 0x80..0x8F
25303 fixarray | array | 0x90..0x9F
25304 fixstr | string | 0xA0..0xBF
25305 nil | `null` | 0xC0
25306 false | `false` | 0xC2
25307 true | `true` | 0xC3
25308 float 32 | number_float | 0xCA
25309 float 64 | number_float | 0xCB
25310 uint 8 | number_unsigned | 0xCC
25311 uint 16 | number_unsigned | 0xCD
25312 uint 32 | number_unsigned | 0xCE
25313 uint 64 | number_unsigned | 0xCF
25314 int 8 | number_integer | 0xD0
25315 int 16 | number_integer | 0xD1
25316 int 32 | number_integer | 0xD2
25317 int 64 | number_integer | 0xD3
25318 str 8 | string | 0xD9
25319 str 16 | string | 0xDA
25320 str 32 | string | 0xDB
25321 array 16 | array | 0xDC
25322 array 32 | array | 0xDD
25323 map 16 | object | 0xDE
25324 map 32 | object | 0xDF
25325 bin 8 | binary | 0xC4
25326 bin 16 | binary | 0xC5
25327 bin 32 | binary | 0xC6
25328 ext 8 | binary | 0xC7
25329 ext 16 | binary | 0xC8
25330 ext 32 | binary | 0xC9
25331 fixext 1 | binary | 0xD4
25332 fixext 2 | binary | 0xD5
25333 fixext 4 | binary | 0xD6
25334 fixext 8 | binary | 0xD7
25335 fixext 16 | binary | 0xD8
25336 negative fixint | number_integer | 0xE0-0xFF
25338 @note Any MessagePack output created @ref to_msgpack can be successfully
25339 parsed by @ref from_msgpack.
25341 @param[in] i an input in MessagePack format convertible to an input
25343 @param[in] strict whether to expect the input to be consumed until EOF
25345 @param[in] allow_exceptions whether to throw exceptions in case of a
25346 parse error (optional, true by default)
25348 @return deserialized JSON value; in case of a parse error and
25349 @a allow_exceptions set to `false`, the return value will be
25350 value_t::discarded.
25352 @throw parse_error.110 if the given input ends prematurely or the end of
25353 file was not reached when @a strict was set to true
25354 @throw parse_error.112 if unsupported features from MessagePack were
25355 used in the given input @a i or if the input is not valid MessagePack
25356 @throw parse_error.113 if a string was expected as map key, but not found
25358 @complexity Linear in the size of the input @a i.
25360 @liveexample{The example shows the deserialization of a byte vector in
25361 MessagePack format to a JSON value.,from_msgpack}
25363 @sa http://msgpack.org
25364 @sa see @ref to_msgpack(const basic_json&) for the analogous serialization
25365 @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25366 related CBOR format
25367 @sa see @ref from_ubjson(InputType&&, const bool, const bool) for
25368 the related UBJSON format
25369 @sa see @ref from_bson(InputType&&, const bool, const bool) for
25370 the related BSON format
25372 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
25373 consume input adapters, removed start_index parameter, and added
25374 @a strict parameter since 3.0.0; added @a allow_exceptions parameter
25377 template<typename InputType>
25378 JSON_HEDLEY_WARN_UNUSED_RESULT
25379 static basic_json from_msgpack(InputType&& i,
25380 const bool strict = true,
25381 const bool allow_exceptions = true)
25384 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25385 auto ia = detail::input_adapter(std::forward<InputType>(i));
25386 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25387 return res ? result : basic_json(value_t::discarded);
25391 @copydoc from_msgpack(InputType&&, const bool, const bool)
25393 template<typename IteratorType>
25394 JSON_HEDLEY_WARN_UNUSED_RESULT
25395 static basic_json from_msgpack(IteratorType first, IteratorType last,
25396 const bool strict = true,
25397 const bool allow_exceptions = true)
25400 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25401 auto ia = detail::input_adapter(std::move(first), std::move(last));
25402 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25403 return res ? result : basic_json(value_t::discarded);
25407 template<typename T>
25408 JSON_HEDLEY_WARN_UNUSED_RESULT
25409 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25410 static basic_json from_msgpack(const T* ptr, std::size_t len,
25411 const bool strict = true,
25412 const bool allow_exceptions = true)
25414 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
25417 JSON_HEDLEY_WARN_UNUSED_RESULT
25418 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25419 static basic_json from_msgpack(detail::span_input_adapter&& i,
25420 const bool strict = true,
25421 const bool allow_exceptions = true)
25424 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25426 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25427 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25428 return res ? result : basic_json(value_t::discarded);
25433 @brief create a JSON value from an input in UBJSON format
25435 Deserializes a given input @a i to a JSON value using the UBJSON (Universal
25436 Binary JSON) serialization format.
25438 The library maps UBJSON types to JSON value types as follows:
25440 UBJSON type | JSON value type | marker
25441 ----------- | --------------------------------------- | ------
25442 no-op | *no value, next value is read* | `N`
25443 null | `null` | `Z`
25444 false | `false` | `F`
25445 true | `true` | `T`
25446 float32 | number_float | `d`
25447 float64 | number_float | `D`
25448 uint8 | number_unsigned | `U`
25449 int8 | number_integer | `i`
25450 int16 | number_integer | `I`
25451 int32 | number_integer | `l`
25452 int64 | number_integer | `L`
25453 high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H'
25454 string | string | `S`
25455 char | string | `C`
25456 array | array (optimized values are supported) | `[`
25457 object | object (optimized values are supported) | `{`
25459 @note The mapping is **complete** in the sense that any UBJSON value can
25460 be converted to a JSON value.
25462 @param[in] i an input in UBJSON format convertible to an input adapter
25463 @param[in] strict whether to expect the input to be consumed until EOF
25465 @param[in] allow_exceptions whether to throw exceptions in case of a
25466 parse error (optional, true by default)
25468 @return deserialized JSON value; in case of a parse error and
25469 @a allow_exceptions set to `false`, the return value will be
25470 value_t::discarded.
25472 @throw parse_error.110 if the given input ends prematurely or the end of
25473 file was not reached when @a strict was set to true
25474 @throw parse_error.112 if a parse error occurs
25475 @throw parse_error.113 if a string could not be parsed successfully
25477 @complexity Linear in the size of the input @a i.
25479 @liveexample{The example shows the deserialization of a byte vector in
25480 UBJSON format to a JSON value.,from_ubjson}
25482 @sa http://ubjson.org
25483 @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
25484 analogous serialization
25485 @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25486 related CBOR format
25487 @sa see @ref from_msgpack(InputType&&, const bool, const bool) for
25488 the related MessagePack format
25489 @sa see @ref from_bson(InputType&&, const bool, const bool) for
25490 the related BSON format
25492 @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
25494 template<typename InputType>
25495 JSON_HEDLEY_WARN_UNUSED_RESULT
25496 static basic_json from_ubjson(InputType&& i,
25497 const bool strict = true,
25498 const bool allow_exceptions = true)
25501 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25502 auto ia = detail::input_adapter(std::forward<InputType>(i));
25503 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25504 return res ? result : basic_json(value_t::discarded);
25508 @copydoc from_ubjson(InputType&&, const bool, const bool)
25510 template<typename IteratorType>
25511 JSON_HEDLEY_WARN_UNUSED_RESULT
25512 static basic_json from_ubjson(IteratorType first, IteratorType last,
25513 const bool strict = true,
25514 const bool allow_exceptions = true)
25517 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25518 auto ia = detail::input_adapter(std::move(first), std::move(last));
25519 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25520 return res ? result : basic_json(value_t::discarded);
25523 template<typename T>
25524 JSON_HEDLEY_WARN_UNUSED_RESULT
25525 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25526 static basic_json from_ubjson(const T* ptr, std::size_t len,
25527 const bool strict = true,
25528 const bool allow_exceptions = true)
25530 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
25533 JSON_HEDLEY_WARN_UNUSED_RESULT
25534 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25535 static basic_json from_ubjson(detail::span_input_adapter&& i,
25536 const bool strict = true,
25537 const bool allow_exceptions = true)
25540 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25542 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25543 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25544 return res ? result : basic_json(value_t::discarded);
25549 @brief Create a JSON value from an input in BSON format
25551 Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
25552 serialization format.
25554 The library maps BSON record types to JSON value types as follows:
25556 BSON type | BSON marker byte | JSON value type
25557 --------------- | ---------------- | ---------------------------
25558 double | 0x01 | number_float
25559 string | 0x02 | string
25560 document | 0x03 | object
25561 array | 0x04 | array
25562 binary | 0x05 | binary
25563 undefined | 0x06 | still unsupported
25564 ObjectId | 0x07 | still unsupported
25565 boolean | 0x08 | boolean
25566 UTC Date-Time | 0x09 | still unsupported
25568 Regular Expr. | 0x0B | still unsupported
25569 DB Pointer | 0x0C | still unsupported
25570 JavaScript Code | 0x0D | still unsupported
25571 Symbol | 0x0E | still unsupported
25572 JavaScript Code | 0x0F | still unsupported
25573 int32 | 0x10 | number_integer
25574 Timestamp | 0x11 | still unsupported
25575 128-bit decimal float | 0x13 | still unsupported
25576 Max Key | 0x7F | still unsupported
25577 Min Key | 0xFF | still unsupported
25579 @warning The mapping is **incomplete**. The unsupported mappings
25580 are indicated in the table above.
25582 @param[in] i an input in BSON format convertible to an input adapter
25583 @param[in] strict whether to expect the input to be consumed until EOF
25585 @param[in] allow_exceptions whether to throw exceptions in case of a
25586 parse error (optional, true by default)
25588 @return deserialized JSON value; in case of a parse error and
25589 @a allow_exceptions set to `false`, the return value will be
25590 value_t::discarded.
25592 @throw parse_error.114 if an unsupported BSON record type is encountered
25594 @complexity Linear in the size of the input @a i.
25596 @liveexample{The example shows the deserialization of a byte vector in
25597 BSON format to a JSON value.,from_bson}
25599 @sa http://bsonspec.org/spec.html
25600 @sa see @ref to_bson(const basic_json&) for the analogous serialization
25601 @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25602 related CBOR format
25603 @sa see @ref from_msgpack(InputType&&, const bool, const bool) for
25604 the related MessagePack format
25605 @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
25606 related UBJSON format
25608 template<typename InputType>
25609 JSON_HEDLEY_WARN_UNUSED_RESULT
25610 static basic_json from_bson(InputType&& i,
25611 const bool strict = true,
25612 const bool allow_exceptions = true)
25615 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25616 auto ia = detail::input_adapter(std::forward<InputType>(i));
25617 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25618 return res ? result : basic_json(value_t::discarded);
25622 @copydoc from_bson(InputType&&, const bool, const bool)
25624 template<typename IteratorType>
25625 JSON_HEDLEY_WARN_UNUSED_RESULT
25626 static basic_json from_bson(IteratorType first, IteratorType last,
25627 const bool strict = true,
25628 const bool allow_exceptions = true)
25631 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25632 auto ia = detail::input_adapter(std::move(first), std::move(last));
25633 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25634 return res ? result : basic_json(value_t::discarded);
25637 template<typename T>
25638 JSON_HEDLEY_WARN_UNUSED_RESULT
25639 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25640 static basic_json from_bson(const T* ptr, std::size_t len,
25641 const bool strict = true,
25642 const bool allow_exceptions = true)
25644 return from_bson(ptr, ptr + len, strict, allow_exceptions);
25647 JSON_HEDLEY_WARN_UNUSED_RESULT
25648 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25649 static basic_json from_bson(detail::span_input_adapter&& i,
25650 const bool strict = true,
25651 const bool allow_exceptions = true)
25654 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25656 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25657 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25658 return res ? result : basic_json(value_t::discarded);
25662 //////////////////////////
25663 // JSON Pointer support //
25664 //////////////////////////
25666 /// @name JSON Pointer functions
25670 @brief access specified element via JSON Pointer
25672 Uses a JSON pointer to retrieve a reference to the respective JSON value.
25673 No bound checking is performed. Similar to @ref operator[](const typename
25674 object_t::key_type&), `null` values are created in arrays and objects if
25678 - If the JSON pointer points to an object key that does not exist, it
25679 is created an filled with a `null` value before a reference to it
25681 - If the JSON pointer points to an array index that does not exist, it
25682 is created an filled with a `null` value before a reference to it
25683 is returned. All indices between the current maximum and the given
25684 index are also filled with `null`.
25685 - The special value `-` is treated as a synonym for the index past the
25688 @param[in] ptr a JSON pointer
25690 @return reference to the element pointed to by @a ptr
25692 @complexity Constant.
25694 @throw parse_error.106 if an array index begins with '0'
25695 @throw parse_error.109 if an array index was not a number
25696 @throw out_of_range.404 if the JSON pointer can not be resolved
25698 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
25700 @since version 2.0.0
25702 reference operator[](const json_pointer& ptr)
25704 return ptr.get_unchecked(this);
25708 @brief access specified element via JSON Pointer
25710 Uses a JSON pointer to retrieve a reference to the respective JSON value.
25711 No bound checking is performed. The function does not change the JSON
25712 value; no `null` values are created. In particular, the special value
25713 `-` yields an exception.
25715 @param[in] ptr JSON pointer to the desired element
25717 @return const reference to the element pointed to by @a ptr
25719 @complexity Constant.
25721 @throw parse_error.106 if an array index begins with '0'
25722 @throw parse_error.109 if an array index was not a number
25723 @throw out_of_range.402 if the array index '-' is used
25724 @throw out_of_range.404 if the JSON pointer can not be resolved
25726 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
25728 @since version 2.0.0
25730 const_reference operator[](const json_pointer& ptr) const
25732 return ptr.get_unchecked(this);
25736 @brief access specified element via JSON Pointer
25738 Returns a reference to the element at with specified JSON pointer @a ptr,
25739 with bounds checking.
25741 @param[in] ptr JSON pointer to the desired element
25743 @return reference to the element pointed to by @a ptr
25745 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
25746 begins with '0'. See example below.
25748 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
25749 is not a number. See example below.
25751 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
25752 is out of range. See example below.
25754 @throw out_of_range.402 if the array index '-' is used in the passed JSON
25755 pointer @a ptr. As `at` provides checked access (and no elements are
25756 implicitly inserted), the index '-' is always invalid. See example below.
25758 @throw out_of_range.403 if the JSON pointer describes a key of an object
25759 which cannot be found. See example below.
25761 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
25764 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
25765 changes in the JSON value.
25767 @complexity Constant.
25769 @since version 2.0.0
25771 @liveexample{The behavior is shown in the example.,at_json_pointer}
25773 reference at(const json_pointer& ptr)
25775 return ptr.get_checked(this);
25779 @brief access specified element via JSON Pointer
25781 Returns a const reference to the element at with specified JSON pointer @a
25782 ptr, with bounds checking.
25784 @param[in] ptr JSON pointer to the desired element
25786 @return reference to the element pointed to by @a ptr
25788 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
25789 begins with '0'. See example below.
25791 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
25792 is not a number. See example below.
25794 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
25795 is out of range. See example below.
25797 @throw out_of_range.402 if the array index '-' is used in the passed JSON
25798 pointer @a ptr. As `at` provides checked access (and no elements are
25799 implicitly inserted), the index '-' is always invalid. See example below.
25801 @throw out_of_range.403 if the JSON pointer describes a key of an object
25802 which cannot be found. See example below.
25804 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
25807 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
25808 changes in the JSON value.
25810 @complexity Constant.
25812 @since version 2.0.0
25814 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
25816 const_reference at(const json_pointer& ptr) const
25818 return ptr.get_checked(this);
25822 @brief return flattened JSON value
25824 The function creates a JSON object whose keys are JSON pointers (see [RFC
25825 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
25826 primitive. The original JSON value can be restored using the @ref
25827 unflatten() function.
25829 @return an object that maps JSON pointers to primitive values
25831 @note Empty objects and arrays are flattened to `null` and will not be
25832 reconstructed correctly by the @ref unflatten() function.
25834 @complexity Linear in the size the JSON value.
25836 @liveexample{The following code shows how a JSON object is flattened to an
25837 object whose keys consist of JSON pointers.,flatten}
25839 @sa see @ref unflatten() for the reverse function
25841 @since version 2.0.0
25843 basic_json flatten() const
25845 basic_json result(value_t::object);
25846 json_pointer::flatten("", *this, result);
25851 @brief unflatten a previously flattened JSON value
25853 The function restores the arbitrary nesting of a JSON value that has been
25854 flattened before using the @ref flatten() function. The JSON value must
25855 meet certain constraints:
25856 1. The value must be an object.
25857 2. The keys must be JSON pointers (see
25858 [RFC 6901](https://tools.ietf.org/html/rfc6901))
25859 3. The mapped values must be primitive JSON types.
25861 @return the original JSON from a flattened version
25863 @note Empty objects and arrays are flattened by @ref flatten() to `null`
25864 values and can not unflattened to their original type. Apart from
25865 this example, for a JSON value `j`, the following is always true:
25866 `j == j.flatten().unflatten()`.
25868 @complexity Linear in the size the JSON value.
25870 @throw type_error.314 if value is not an object
25871 @throw type_error.315 if object values are not primitive
25873 @liveexample{The following code shows how a flattened JSON object is
25874 unflattened into the original nested JSON object.,unflatten}
25876 @sa see @ref flatten() for the reverse function
25878 @since version 2.0.0
25880 basic_json unflatten() const
25882 return json_pointer::unflatten(*this);
25887 //////////////////////////
25888 // JSON Patch functions //
25889 //////////////////////////
25891 /// @name JSON Patch functions
25895 @brief applies a JSON patch
25897 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
25898 expressing a sequence of operations to apply to a JSON) document. With
25899 this function, a JSON Patch is applied to the current JSON value by
25900 executing all operations from the patch.
25902 @param[in] json_patch JSON patch document
25903 @return patched document
25905 @note The application of a patch is atomic: Either all operations succeed
25906 and the patched document is returned or an exception is thrown. In
25907 any case, the original value is not changed: the patch is applied
25908 to a copy of the value.
25910 @throw parse_error.104 if the JSON patch does not consist of an array of
25913 @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
25914 attributes are missing); example: `"operation add must have member path"`
25916 @throw out_of_range.401 if an array index is out of range.
25918 @throw out_of_range.403 if a JSON pointer inside the patch could not be
25919 resolved successfully in the current JSON value; example: `"key baz not
25922 @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
25925 @throw other_error.501 if "test" operation was unsuccessful
25927 @complexity Linear in the size of the JSON value and the length of the
25928 JSON patch. As usually only a fraction of the JSON value is affected by
25929 the patch, the complexity can usually be neglected.
25931 @liveexample{The following code shows how a JSON patch is applied to a
25934 @sa see @ref diff -- create a JSON patch by comparing two JSON values
25936 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
25937 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
25939 @since version 2.0.0
25941 basic_json patch(const basic_json& json_patch) const
25943 // make a working copy to apply the patch to
25944 basic_json result = *this;
25946 // the valid JSON Patch operations
25947 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
25949 const auto get_op = [](const std::string & op)
25953 return patch_operations::add;
25955 if (op == "remove")
25957 return patch_operations::remove;
25959 if (op == "replace")
25961 return patch_operations::replace;
25965 return patch_operations::move;
25969 return patch_operations::copy;
25973 return patch_operations::test;
25976 return patch_operations::invalid;
25979 // wrapper for "add" operation; add value at ptr
25980 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
25982 // adding to the root of the target document means replacing it
25989 // make sure the top element of the pointer exists
25990 json_pointer top_pointer = ptr.top();
25991 if (top_pointer != ptr)
25993 result.at(top_pointer);
25996 // get reference to parent of JSON pointer ptr
25997 const auto last_path = ptr.back();
25999 basic_json& parent = result[ptr];
26001 switch (parent.m_type)
26003 case value_t::null:
26004 case value_t::object:
26006 // use operator[] to add value
26007 parent[last_path] = val;
26011 case value_t::array:
26013 if (last_path == "-")
26015 // special case: append to back
26016 parent.push_back(val);
26020 const auto idx = json_pointer::array_index(last_path);
26021 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
26023 // avoid undefined behavior
26024 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
26027 // default case: insert add offset
26028 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
26033 // if there exists a parent it cannot be primitive
26034 case value_t::string: // LCOV_EXCL_LINE
26035 case value_t::boolean: // LCOV_EXCL_LINE
26036 case value_t::number_integer: // LCOV_EXCL_LINE
26037 case value_t::number_unsigned: // LCOV_EXCL_LINE
26038 case value_t::number_float: // LCOV_EXCL_LINE
26039 case value_t::binary: // LCOV_EXCL_LINE
26040 case value_t::discarded: // LCOV_EXCL_LINE
26041 default: // LCOV_EXCL_LINE
26042 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
26046 // wrapper for "remove" operation; remove value at ptr
26047 const auto operation_remove = [this, &result](json_pointer & ptr)
26049 // get reference to parent of JSON pointer ptr
26050 const auto last_path = ptr.back();
26052 basic_json& parent = result.at(ptr);
26055 if (parent.is_object())
26057 // perform range check
26058 auto it = parent.find(last_path);
26059 if (JSON_HEDLEY_LIKELY(it != parent.end()))
26065 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
26068 else if (parent.is_array())
26070 // note erase performs range check
26071 parent.erase(json_pointer::array_index(last_path));
26075 // type check: top level value must be an array
26076 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
26078 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
26081 // iterate and apply the operations
26082 for (const auto& val : json_patch)
26084 // wrapper to get a value for an operation
26085 const auto get_value = [&val](const std::string & op,
26086 const std::string & member,
26087 bool string_type) -> basic_json &
26090 auto it = val.m_value.object->find(member);
26092 // context-sensitive error message
26093 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
26095 // check if desired value is present
26096 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
26098 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
26099 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
26102 // check if result is of type string
26103 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
26105 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
26106 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
26109 // no error: return value
26113 // type check: every element of the array must be an object
26114 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
26116 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
26119 // collect mandatory members
26120 const auto op = get_value("op", "op", true).template get<std::string>();
26121 const auto path = get_value(op, "path", true).template get<std::string>();
26122 json_pointer ptr(path);
26124 switch (get_op(op))
26126 case patch_operations::add:
26128 operation_add(ptr, get_value("add", "value", false));
26132 case patch_operations::remove:
26134 operation_remove(ptr);
26138 case patch_operations::replace:
26140 // the "path" location must exist - use at()
26141 result.at(ptr) = get_value("replace", "value", false);
26145 case patch_operations::move:
26147 const auto from_path = get_value("move", "from", true).template get<std::string>();
26148 json_pointer from_ptr(from_path);
26150 // the "from" location must exist - use at()
26151 basic_json v = result.at(from_ptr);
26153 // The move operation is functionally identical to a
26154 // "remove" operation on the "from" location, followed
26155 // immediately by an "add" operation at the target
26156 // location with the value that was just removed.
26157 operation_remove(from_ptr);
26158 operation_add(ptr, v);
26162 case patch_operations::copy:
26164 const auto from_path = get_value("copy", "from", true).template get<std::string>();
26165 const json_pointer from_ptr(from_path);
26167 // the "from" location must exist - use at()
26168 basic_json v = result.at(from_ptr);
26170 // The copy is functionally identical to an "add"
26171 // operation at the target location using the value
26172 // specified in the "from" member.
26173 operation_add(ptr, v);
26177 case patch_operations::test:
26179 bool success = false;
26182 // check if "value" matches the one at "path"
26183 // the "path" location must exist - use at()
26184 success = (result.at(ptr) == get_value("test", "value", false));
26186 JSON_INTERNAL_CATCH (out_of_range&)
26188 // ignore out of range errors: success remains false
26191 // throw an exception if test fails
26192 if (JSON_HEDLEY_UNLIKELY(!success))
26194 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
26200 case patch_operations::invalid:
26203 // op must be "add", "remove", "replace", "move", "copy", or
26205 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
26214 @brief creates a diff as a JSON patch
26216 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
26217 be changed into the value @a target by calling @ref patch function.
26219 @invariant For two JSON values @a source and @a target, the following code
26220 yields always `true`:
26222 source.patch(diff(source, target)) == target;
26225 @note Currently, only `remove`, `add`, and `replace` operations are
26228 @param[in] source JSON value to compare from
26229 @param[in] target JSON value to compare against
26230 @param[in] path helper value to create JSON pointers
26232 @return a JSON patch to convert the @a source to @a target
26234 @complexity Linear in the lengths of @a source and @a target.
26236 @liveexample{The following code shows how a JSON patch is created as a
26237 diff for two JSON values.,diff}
26239 @sa see @ref patch -- apply a JSON patch
26240 @sa see @ref merge_patch -- apply a JSON Merge Patch
26242 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
26244 @since version 2.0.0
26246 JSON_HEDLEY_WARN_UNUSED_RESULT
26247 static basic_json diff(const basic_json& source, const basic_json& target,
26248 const std::string& path = "")
26251 basic_json result(value_t::array);
26253 // if the values are the same, return empty patch
26254 if (source == target)
26259 if (source.type() != target.type())
26261 // different types: replace value
26264 {"op", "replace"}, {"path", path}, {"value", target}
26269 switch (source.type())
26271 case value_t::array:
26273 // first pass: traverse common elements
26275 while (i < source.size() && i < target.size())
26277 // recursive call to compare array values at index i
26278 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
26279 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26283 // i now reached the end of at least one array
26284 // in a second pass, traverse the remaining elements
26286 // remove my remaining elements
26287 const auto end_index = static_cast<difference_type>(result.size());
26288 while (i < source.size())
26290 // add operations in reverse order to avoid invalid
26292 result.insert(result.begin() + end_index, object(
26295 {"path", path + "/" + std::to_string(i)}
26300 // add other remaining elements
26301 while (i < target.size())
26306 {"path", path + "/-"},
26307 {"value", target[i]}
26315 case value_t::object:
26317 // first pass: traverse this object's elements
26318 for (auto it = source.cbegin(); it != source.cend(); ++it)
26320 // escape the key name to be used in a JSON patch
26321 const auto path_key = path + "/" + detail::escape(it.key());
26323 if (target.find(it.key()) != target.end())
26325 // recursive call to compare object values at key it
26326 auto temp_diff = diff(it.value(), target[it.key()], path_key);
26327 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26331 // found a key that is not in o -> remove it
26332 result.push_back(object(
26334 {"op", "remove"}, {"path", path_key}
26339 // second pass: traverse other object's elements
26340 for (auto it = target.cbegin(); it != target.cend(); ++it)
26342 if (source.find(it.key()) == source.end())
26344 // found a key that is not in this -> add it
26345 const auto path_key = path + "/" + detail::escape(it.key());
26348 {"op", "add"}, {"path", path_key},
26349 {"value", it.value()}
26357 case value_t::null:
26358 case value_t::string:
26359 case value_t::boolean:
26360 case value_t::number_integer:
26361 case value_t::number_unsigned:
26362 case value_t::number_float:
26363 case value_t::binary:
26364 case value_t::discarded:
26367 // both primitive type: replace value
26370 {"op", "replace"}, {"path", path}, {"value", target}
26381 ////////////////////////////////
26382 // JSON Merge Patch functions //
26383 ////////////////////////////////
26385 /// @name JSON Merge Patch functions
26389 @brief applies a JSON Merge Patch
26391 The merge patch format is primarily intended for use with the HTTP PATCH
26392 method as a means of describing a set of modifications to a target
26393 resource's content. This function applies a merge patch to the current
26396 The function implements the following algorithm from Section 2 of
26397 [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
26400 define MergePatch(Target, Patch):
26401 if Patch is an Object:
26402 if Target is not an Object:
26403 Target = {} // Ignore the contents and set it to an empty Object
26404 for each Name/Value pair in Patch:
26406 if Name exists in Target:
26407 remove the Name/Value pair from Target
26409 Target[Name] = MergePatch(Target[Name], Value)
26415 Thereby, `Target` is the current object; that is, the patch is applied to
26418 @param[in] apply_patch the patch to apply
26420 @complexity Linear in the lengths of @a patch.
26422 @liveexample{The following code shows how a JSON Merge Patch is applied to
26423 a JSON document.,merge_patch}
26425 @sa see @ref patch -- apply a JSON patch
26426 @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
26428 @since version 3.0.0
26430 void merge_patch(const basic_json& apply_patch)
26432 if (apply_patch.is_object())
26438 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
26440 if (it.value().is_null())
26446 operator[](it.key()).merge_patch(it.value());
26452 *this = apply_patch;
26460 @brief user-defined to_string function for JSON values
26462 This function implements a user-defined to_string for JSON objects.
26464 @param[in] j a JSON object
26465 @return a std::string object
26468 NLOHMANN_BASIC_JSON_TPL_DECLARATION
26469 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
26473 } // namespace nlohmann
26475 ///////////////////////
26476 // nonmember support //
26477 ///////////////////////
26479 namespace std // NOLINT(cert-dcl58-cpp)
26482 /// hash value for JSON objects
26483 NLOHMANN_BASIC_JSON_TPL_DECLARATION
26484 struct hash<nlohmann::NLOHMANN_BASIC_JSON_TPL>
26487 @brief return a hash value for a JSON object
26489 @since version 1.0.0, extended for arbitrary basic_json types in 3.10.5.
26491 std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
26493 return nlohmann::detail::hash(j);
26497 /// specialization for std::less<value_t>
26498 /// @note: do not remove the space after '<',
26499 /// see https://github.com/nlohmann/json/pull/679
26501 struct less< ::nlohmann::detail::value_t>
26504 @brief compare two value_t enum values
26505 @since version 3.0.0
26507 bool operator()(nlohmann::detail::value_t lhs,
26508 nlohmann::detail::value_t rhs) const noexcept
26510 return nlohmann::detail::operator<(lhs, rhs);
26514 // C++20 prohibit function specialization in the std namespace.
26515 #ifndef JSON_HAS_CPP_20
26518 @brief exchanges the values of two JSON objects
26520 @since version 1.0.0, extended for arbitrary basic_json types in 3.10.5.
26522 NLOHMANN_BASIC_JSON_TPL_DECLARATION
26523 inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
26524 is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
26525 is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
26535 @brief user-defined string literal for JSON values
26537 This operator implements a user-defined string literal for JSON objects. It
26538 can be used by adding `"_json"` to a string literal and returns a JSON object
26539 if no parse error occurred.
26541 @param[in] s a string representation of a JSON object
26542 @param[in] n the length of string @a s
26543 @return a JSON object
26545 @since version 1.0.0
26547 JSON_HEDLEY_NON_NULL(1)
26548 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
26550 return nlohmann::json::parse(s, s + n);
26554 @brief user-defined string literal for JSON pointer
26556 This operator implements a user-defined string literal for JSON Pointers. It
26557 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
26558 object if no parse error occurred.
26560 @param[in] s a string representation of a JSON Pointer
26561 @param[in] n the length of string @a s
26562 @return a JSON pointer object
26564 @since version 2.0.0
26566 JSON_HEDLEY_NON_NULL(1)
26567 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
26569 return nlohmann::json::json_pointer(std::string(s, n));
26572 // #include <nlohmann/detail/macro_unscope.hpp>
26575 // restore clang diagnostic settings
26576 #if defined(__clang__)
26577 #pragma clang diagnostic pop
26582 #undef JSON_INTERNAL_CATCH
26586 #undef JSON_PRIVATE_UNLESS_TESTED
26587 #undef JSON_HAS_CPP_11
26588 #undef JSON_HAS_CPP_14
26589 #undef JSON_HAS_CPP_17
26590 #undef JSON_HAS_CPP_20
26591 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
26592 #undef NLOHMANN_BASIC_JSON_TPL
26593 #undef JSON_EXPLICIT
26594 #undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
26596 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
26599 #undef JSON_HEDLEY_ALWAYS_INLINE
26600 #undef JSON_HEDLEY_ARM_VERSION
26601 #undef JSON_HEDLEY_ARM_VERSION_CHECK
26602 #undef JSON_HEDLEY_ARRAY_PARAM
26603 #undef JSON_HEDLEY_ASSUME
26604 #undef JSON_HEDLEY_BEGIN_C_DECLS
26605 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
26606 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
26607 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
26608 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
26609 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
26610 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
26611 #undef JSON_HEDLEY_CLANG_HAS_WARNING
26612 #undef JSON_HEDLEY_COMPCERT_VERSION
26613 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
26614 #undef JSON_HEDLEY_CONCAT
26615 #undef JSON_HEDLEY_CONCAT3
26616 #undef JSON_HEDLEY_CONCAT3_EX
26617 #undef JSON_HEDLEY_CONCAT_EX
26618 #undef JSON_HEDLEY_CONST
26619 #undef JSON_HEDLEY_CONSTEXPR
26620 #undef JSON_HEDLEY_CONST_CAST
26621 #undef JSON_HEDLEY_CPP_CAST
26622 #undef JSON_HEDLEY_CRAY_VERSION
26623 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
26624 #undef JSON_HEDLEY_C_DECL
26625 #undef JSON_HEDLEY_DEPRECATED
26626 #undef JSON_HEDLEY_DEPRECATED_FOR
26627 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
26628 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
26629 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
26630 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
26631 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
26632 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
26633 #undef JSON_HEDLEY_DIAGNOSTIC_POP
26634 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
26635 #undef JSON_HEDLEY_DMC_VERSION
26636 #undef JSON_HEDLEY_DMC_VERSION_CHECK
26637 #undef JSON_HEDLEY_EMPTY_BASES
26638 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
26639 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
26640 #undef JSON_HEDLEY_END_C_DECLS
26641 #undef JSON_HEDLEY_FLAGS
26642 #undef JSON_HEDLEY_FLAGS_CAST
26643 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
26644 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
26645 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
26646 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
26647 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
26648 #undef JSON_HEDLEY_GCC_HAS_FEATURE
26649 #undef JSON_HEDLEY_GCC_HAS_WARNING
26650 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
26651 #undef JSON_HEDLEY_GCC_VERSION
26652 #undef JSON_HEDLEY_GCC_VERSION_CHECK
26653 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
26654 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
26655 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
26656 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
26657 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
26658 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
26659 #undef JSON_HEDLEY_GNUC_HAS_WARNING
26660 #undef JSON_HEDLEY_GNUC_VERSION
26661 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
26662 #undef JSON_HEDLEY_HAS_ATTRIBUTE
26663 #undef JSON_HEDLEY_HAS_BUILTIN
26664 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
26665 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
26666 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
26667 #undef JSON_HEDLEY_HAS_EXTENSION
26668 #undef JSON_HEDLEY_HAS_FEATURE
26669 #undef JSON_HEDLEY_HAS_WARNING
26670 #undef JSON_HEDLEY_IAR_VERSION
26671 #undef JSON_HEDLEY_IAR_VERSION_CHECK
26672 #undef JSON_HEDLEY_IBM_VERSION
26673 #undef JSON_HEDLEY_IBM_VERSION_CHECK
26674 #undef JSON_HEDLEY_IMPORT
26675 #undef JSON_HEDLEY_INLINE
26676 #undef JSON_HEDLEY_INTEL_CL_VERSION
26677 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
26678 #undef JSON_HEDLEY_INTEL_VERSION
26679 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
26680 #undef JSON_HEDLEY_IS_CONSTANT
26681 #undef JSON_HEDLEY_IS_CONSTEXPR_
26682 #undef JSON_HEDLEY_LIKELY
26683 #undef JSON_HEDLEY_MALLOC
26684 #undef JSON_HEDLEY_MCST_LCC_VERSION
26685 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
26686 #undef JSON_HEDLEY_MESSAGE
26687 #undef JSON_HEDLEY_MSVC_VERSION
26688 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
26689 #undef JSON_HEDLEY_NEVER_INLINE
26690 #undef JSON_HEDLEY_NON_NULL
26691 #undef JSON_HEDLEY_NO_ESCAPE
26692 #undef JSON_HEDLEY_NO_RETURN
26693 #undef JSON_HEDLEY_NO_THROW
26694 #undef JSON_HEDLEY_NULL
26695 #undef JSON_HEDLEY_PELLES_VERSION
26696 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
26697 #undef JSON_HEDLEY_PGI_VERSION
26698 #undef JSON_HEDLEY_PGI_VERSION_CHECK
26699 #undef JSON_HEDLEY_PREDICT
26700 #undef JSON_HEDLEY_PRINTF_FORMAT
26701 #undef JSON_HEDLEY_PRIVATE
26702 #undef JSON_HEDLEY_PUBLIC
26703 #undef JSON_HEDLEY_PURE
26704 #undef JSON_HEDLEY_REINTERPRET_CAST
26705 #undef JSON_HEDLEY_REQUIRE
26706 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
26707 #undef JSON_HEDLEY_REQUIRE_MSG
26708 #undef JSON_HEDLEY_RESTRICT
26709 #undef JSON_HEDLEY_RETURNS_NON_NULL
26710 #undef JSON_HEDLEY_SENTINEL
26711 #undef JSON_HEDLEY_STATIC_ASSERT
26712 #undef JSON_HEDLEY_STATIC_CAST
26713 #undef JSON_HEDLEY_STRINGIFY
26714 #undef JSON_HEDLEY_STRINGIFY_EX
26715 #undef JSON_HEDLEY_SUNPRO_VERSION
26716 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
26717 #undef JSON_HEDLEY_TINYC_VERSION
26718 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
26719 #undef JSON_HEDLEY_TI_ARMCL_VERSION
26720 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
26721 #undef JSON_HEDLEY_TI_CL2000_VERSION
26722 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
26723 #undef JSON_HEDLEY_TI_CL430_VERSION
26724 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
26725 #undef JSON_HEDLEY_TI_CL6X_VERSION
26726 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
26727 #undef JSON_HEDLEY_TI_CL7X_VERSION
26728 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
26729 #undef JSON_HEDLEY_TI_CLPRU_VERSION
26730 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
26731 #undef JSON_HEDLEY_TI_VERSION
26732 #undef JSON_HEDLEY_TI_VERSION_CHECK
26733 #undef JSON_HEDLEY_UNAVAILABLE
26734 #undef JSON_HEDLEY_UNLIKELY
26735 #undef JSON_HEDLEY_UNPREDICTABLE
26736 #undef JSON_HEDLEY_UNREACHABLE
26737 #undef JSON_HEDLEY_UNREACHABLE_RETURN
26738 #undef JSON_HEDLEY_VERSION
26739 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
26740 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
26741 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
26742 #undef JSON_HEDLEY_VERSION_ENCODE
26743 #undef JSON_HEDLEY_WARNING
26744 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
26745 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
26746 #undef JSON_HEDLEY_FALL_THROUGH
26750 #endif // INCLUDE_NLOHMANN_JSON_HPP_