Ark Server API (ASE) - Wiki
Loading...
Searching...
No Matches
json.hpp
Go to the documentation of this file.
1/*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4| | |__ | | | | | | version 3.10.2
5|_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8SPDX-License-Identifier: MIT
9Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10
11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal
13in the Software without restriction, including without limitation the rights
14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15copies of the Software, and to permit persons to whom the Software is
16furnished to do so, subject to the following conditions:
17
18The above copyright notice and this permission notice shall be included in all
19copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27SOFTWARE.
28*/
29
30#ifndef INCLUDE_NLOHMANN_JSON_HPP_
31#define INCLUDE_NLOHMANN_JSON_HPP_
32
33#define NLOHMANN_JSON_VERSION_MAJOR 3
34#define NLOHMANN_JSON_VERSION_MINOR 10
35#define NLOHMANN_JSON_VERSION_PATCH 2
36
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
41#ifndef JSON_NO_IO
42#include <iosfwd> // istream, ostream
43#endif // JSON_NO_IO
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
50
51// #include <nlohmann/adl_serializer.hpp>
52
53
54#include <type_traits>
55#include <utility>
56
57// #include <nlohmann/detail/conversions/from_json.hpp>
58
59
60#include <algorithm> // transform
61#include <array> // array
62#include <forward_list> // forward_list
63#include <iterator> // inserter, front_inserter, end
64#include <map> // map
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
71
72// #include <nlohmann/detail/exceptions.hpp>
73
74
75#include <exception> // exception
76#include <stdexcept> // runtime_error
77#include <string> // to_string
78#include <vector> // vector
79
80// #include <nlohmann/detail/value_t.hpp>
81
82
83#include <array> // array
84#include <cstddef> // size_t
85#include <cstdint> // uint8_t
86#include <string> // string
87
88namespace nlohmann
89{
90 namespace detail
91 {
92 ///////////////////////////
93 // JSON type enumeration //
94 ///////////////////////////
95
96 /*!
97 @brief the JSON type enumeration
98
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.
107
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.
114
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
117
118 @since version 1.0.0
119 */
120 enum class value_t : std::uint8_t
121 {
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
132 };
133
134 /*!
135 @brief comparison operator for JSON types
136
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.
144
145 @since version 1.0.0
146 */
147 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
148 {
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 */,
152 6 /* binary */
153 }
154 };
155
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];
159 }
160 } // namespace detail
161} // namespace nlohmann
162
163// #include <nlohmann/detail/string_escape.hpp>
164
165
166#include <string>
167// #include <nlohmann/detail/macro_scope.hpp>
168
169
170#include <utility> // pair
171// #include <nlohmann/thirdparty/hedley/hedley.hpp>
172
173
174/* Hedley - https://nemequ.github.io/hedley
175 * Created by Evan Nemerson <evan@nemerson.com>
176 *
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
180 * any warranty.
181 *
182 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
183 * SPDX-License-Identifier: CC0-1.0
184 */
185
186#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
187#if defined(JSON_HEDLEY_VERSION)
188#undef JSON_HEDLEY_VERSION
189#endif
190#define JSON_HEDLEY_VERSION 15
191
192#if defined(JSON_HEDLEY_STRINGIFY_EX)
193#undef JSON_HEDLEY_STRINGIFY_EX
194#endif
195#define JSON_HEDLEY_STRINGIFY_EX(x) #x
196
197#if defined(JSON_HEDLEY_STRINGIFY)
198#undef JSON_HEDLEY_STRINGIFY
199#endif
200#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
201
202#if defined(JSON_HEDLEY_CONCAT_EX)
203#undef JSON_HEDLEY_CONCAT_EX
204#endif
205#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
206
207#if defined(JSON_HEDLEY_CONCAT)
208#undef JSON_HEDLEY_CONCAT
209#endif
210#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
211
212#if defined(JSON_HEDLEY_CONCAT3_EX)
213#undef JSON_HEDLEY_CONCAT3_EX
214#endif
215#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
216
217#if defined(JSON_HEDLEY_CONCAT3)
218#undef JSON_HEDLEY_CONCAT3
219#endif
220#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
221
222#if defined(JSON_HEDLEY_VERSION_ENCODE)
223#undef JSON_HEDLEY_VERSION_ENCODE
224#endif
225#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
226
227#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
228#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
229#endif
230#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
231
232#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
233#undef JSON_HEDLEY_VERSION_DECODE_MINOR
234#endif
235#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
236
237#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
238#undef JSON_HEDLEY_VERSION_DECODE_REVISION
239#endif
240#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
241
242#if defined(JSON_HEDLEY_GNUC_VERSION)
243#undef JSON_HEDLEY_GNUC_VERSION
244#endif
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)
249#endif
250
251#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
252#undef JSON_HEDLEY_GNUC_VERSION_CHECK
253#endif
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))
256#else
257#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
258#endif
259
260#if defined(JSON_HEDLEY_MSVC_VERSION)
261#undef JSON_HEDLEY_MSVC_VERSION
262#endif
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)
269#endif
270
271#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
272#undef JSON_HEDLEY_MSVC_VERSION_CHECK
273#endif
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)))
280#else
281#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
282#endif
283
284#if defined(JSON_HEDLEY_INTEL_VERSION)
285#undef JSON_HEDLEY_INTEL_VERSION
286#endif
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)
291#endif
292
293#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
294#undef JSON_HEDLEY_INTEL_VERSION_CHECK
295#endif
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))
298#else
299#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
300#endif
301
302#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
303#undef JSON_HEDLEY_INTEL_CL_VERSION
304#endif
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)
307#endif
308
309#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
310#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
311#endif
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))
314#else
315#define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
316#endif
317
318#if defined(JSON_HEDLEY_PGI_VERSION)
319#undef JSON_HEDLEY_PGI_VERSION
320#endif
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__)
323#endif
324
325#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
326#undef JSON_HEDLEY_PGI_VERSION_CHECK
327#endif
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))
330#else
331#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
332#endif
333
334#if defined(JSON_HEDLEY_SUNPRO_VERSION)
335#undef JSON_HEDLEY_SUNPRO_VERSION
336#endif
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)
345#endif
346
347#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
348#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
349#endif
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))
352#else
353#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
354#endif
355
356#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
357#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
358#endif
359#if defined(__EMSCRIPTEN__)
360#define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
361#endif
362
363#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
364#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
365#endif
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))
368#else
369#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
370#endif
371
372#if defined(JSON_HEDLEY_ARM_VERSION)
373#undef JSON_HEDLEY_ARM_VERSION
374#endif
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)
379#endif
380
381#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
382#undef JSON_HEDLEY_ARM_VERSION_CHECK
383#endif
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))
386#else
387#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
388#endif
389
390#if defined(JSON_HEDLEY_IBM_VERSION)
391#undef JSON_HEDLEY_IBM_VERSION
392#endif
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)
399#endif
400
401#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
402#undef JSON_HEDLEY_IBM_VERSION_CHECK
403#endif
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))
406#else
407#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
408#endif
409
410#if defined(JSON_HEDLEY_TI_VERSION)
411#undef JSON_HEDLEY_TI_VERSION
412#endif
413#if
414 defined(__TI_COMPILER_VERSION__) &&
415 (
416 defined(__TMS470__) || defined(__TI_ARM__) ||
417 defined(__MSP430__) ||
418 defined(__TMS320C2000__)
419 )
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))
422#endif
423#endif
424
425#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
426#undef JSON_HEDLEY_TI_VERSION_CHECK
427#endif
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))
430#else
431#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
432#endif
433
434#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
435#undef JSON_HEDLEY_TI_CL2000_VERSION
436#endif
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))
439#endif
440
441#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
442#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
443#endif
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))
446#else
447#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
448#endif
449
450#if defined(JSON_HEDLEY_TI_CL430_VERSION)
451#undef JSON_HEDLEY_TI_CL430_VERSION
452#endif
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))
455#endif
456
457#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
458#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
459#endif
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))
462#else
463#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
464#endif
465
466#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
467#undef JSON_HEDLEY_TI_ARMCL_VERSION
468#endif
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))
471#endif
472
473#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
474#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
475#endif
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))
478#else
479#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
480#endif
481
482#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
483#undef JSON_HEDLEY_TI_CL6X_VERSION
484#endif
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))
487#endif
488
489#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
490#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
491#endif
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))
494#else
495#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
496#endif
497
498#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
499#undef JSON_HEDLEY_TI_CL7X_VERSION
500#endif
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))
503#endif
504
505#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
506#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
507#endif
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))
510#else
511#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
512#endif
513
514#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
515#undef JSON_HEDLEY_TI_CLPRU_VERSION
516#endif
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))
519#endif
520
521#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
522#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
523#endif
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))
526#else
527#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
528#endif
529
530#if defined(JSON_HEDLEY_CRAY_VERSION)
531#undef JSON_HEDLEY_CRAY_VERSION
532#endif
533#if defined(_CRAYC)
534#if defined(_RELEASE_PATCHLEVEL)
535#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
536#else
537#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
538#endif
539#endif
540
541#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
542#undef JSON_HEDLEY_CRAY_VERSION_CHECK
543#endif
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))
546#else
547#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
548#endif
549
550#if defined(JSON_HEDLEY_IAR_VERSION)
551#undef JSON_HEDLEY_IAR_VERSION
552#endif
553#if defined(__IAR_SYSTEMS_ICC__)
554#if __VER__ > 1000
555#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
556#else
557#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
558#endif
559#endif
560
561#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
562#undef JSON_HEDLEY_IAR_VERSION_CHECK
563#endif
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))
566#else
567#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
568#endif
569
570#if defined(JSON_HEDLEY_TINYC_VERSION)
571#undef JSON_HEDLEY_TINYC_VERSION
572#endif
573#if defined(__TINYC__)
574#define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
575#endif
576
577#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
578#undef JSON_HEDLEY_TINYC_VERSION_CHECK
579#endif
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))
582#else
583#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
584#endif
585
586#if defined(JSON_HEDLEY_DMC_VERSION)
587#undef JSON_HEDLEY_DMC_VERSION
588#endif
589#if defined(__DMC__)
590#define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
591#endif
592
593#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
594#undef JSON_HEDLEY_DMC_VERSION_CHECK
595#endif
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))
598#else
599#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
600#endif
601
602#if defined(JSON_HEDLEY_COMPCERT_VERSION)
603#undef JSON_HEDLEY_COMPCERT_VERSION
604#endif
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)
607#endif
608
609#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
610#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
611#endif
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))
614#else
615#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
616#endif
617
618#if defined(JSON_HEDLEY_PELLES_VERSION)
619#undef JSON_HEDLEY_PELLES_VERSION
620#endif
621#if defined(__POCC__)
622#define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
623#endif
624
625#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
626#undef JSON_HEDLEY_PELLES_VERSION_CHECK
627#endif
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))
630#else
631#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
632#endif
633
634#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
635#undef JSON_HEDLEY_MCST_LCC_VERSION
636#endif
637#if defined(__LCC__) && defined(__LCC_MINOR__)
638#define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
639#endif
640
641#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
642#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
643#endif
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))
646#else
647#define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
648#endif
649
650#if defined(JSON_HEDLEY_GCC_VERSION)
651#undef JSON_HEDLEY_GCC_VERSION
652#endif
653#if
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
670#endif
671
672#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
673#undef JSON_HEDLEY_GCC_VERSION_CHECK
674#endif
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))
677#else
678#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
679#endif
680
681#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
682#undef JSON_HEDLEY_HAS_ATTRIBUTE
683#endif
684#if
685 defined(__has_attribute) &&
686 (
687 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9))
688 )
689# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
690#else
691# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
692#endif
693
694#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
695#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
696#endif
697#if defined(__has_attribute)
698#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
699#else
700#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
701#endif
702
703#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
704#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
705#endif
706#if defined(__has_attribute)
707#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
708#else
709#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
710#endif
711
712#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
713#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
714#endif
715#if
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)
720#else
721#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
722#endif
723
724#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
725#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
726#endif
727#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
728#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
729#elif
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)
735#else
736#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
737#endif
738
739#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
740#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
741#endif
742#if defined(__has_cpp_attribute) && defined(__cplusplus)
743#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
744#else
745#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
746#endif
747
748#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
749#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
750#endif
751#if defined(__has_cpp_attribute) && defined(__cplusplus)
752#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
753#else
754#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
755#endif
756
757#if defined(JSON_HEDLEY_HAS_BUILTIN)
758#undef JSON_HEDLEY_HAS_BUILTIN
759#endif
760#if defined(__has_builtin)
761#define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
762#else
763#define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
764#endif
765
766#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
767#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
768#endif
769#if defined(__has_builtin)
770#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
771#else
772#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
773#endif
774
775#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
776#undef JSON_HEDLEY_GCC_HAS_BUILTIN
777#endif
778#if defined(__has_builtin)
779#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
780#else
781#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
782#endif
783
784#if defined(JSON_HEDLEY_HAS_FEATURE)
785#undef JSON_HEDLEY_HAS_FEATURE
786#endif
787#if defined(__has_feature)
788#define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
789#else
790#define JSON_HEDLEY_HAS_FEATURE(feature) (0)
791#endif
792
793#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
794#undef JSON_HEDLEY_GNUC_HAS_FEATURE
795#endif
796#if defined(__has_feature)
797#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
798#else
799#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
800#endif
801
802#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
803#undef JSON_HEDLEY_GCC_HAS_FEATURE
804#endif
805#if defined(__has_feature)
806#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
807#else
808#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
809#endif
810
811#if defined(JSON_HEDLEY_HAS_EXTENSION)
812#undef JSON_HEDLEY_HAS_EXTENSION
813#endif
814#if defined(__has_extension)
815#define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
816#else
817#define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
818#endif
819
820#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
821#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
822#endif
823#if defined(__has_extension)
824#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
825#else
826#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
827#endif
828
829#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
830#undef JSON_HEDLEY_GCC_HAS_EXTENSION
831#endif
832#if defined(__has_extension)
833#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
834#else
835#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
836#endif
837
838#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
839#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
840#endif
841#if defined(__has_declspec_attribute)
842#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
843#else
844#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
845#endif
846
847#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
848#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
849#endif
850#if defined(__has_declspec_attribute)
851#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
852#else
853#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
854#endif
855
856#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
857#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
858#endif
859#if defined(__has_declspec_attribute)
860#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
861#else
862#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
863#endif
864
865#if defined(JSON_HEDLEY_HAS_WARNING)
866#undef JSON_HEDLEY_HAS_WARNING
867#endif
868#if defined(__has_warning)
869#define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
870#else
871#define JSON_HEDLEY_HAS_WARNING(warning) (0)
872#endif
873
874#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
875#undef JSON_HEDLEY_GNUC_HAS_WARNING
876#endif
877#if defined(__has_warning)
878#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
879#else
880#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
881#endif
882
883#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
884#undef JSON_HEDLEY_GCC_HAS_WARNING
885#endif
886#if defined(__has_warning)
887#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
888#else
889#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
890#endif
891
892#if
893 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) ||
894 defined(__clang__) ||
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)
914#else
915#define JSON_HEDLEY_PRAGMA(value)
916#endif
917
918#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
919#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
920#endif
921#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
922#undef JSON_HEDLEY_DIAGNOSTIC_POP
923#endif
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")
933#elif
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")
941#elif
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)")
953#else
954#define JSON_HEDLEY_DIAGNOSTIC_PUSH
955#define JSON_HEDLEY_DIAGNOSTIC_POP
956#endif
957
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_
962#endif
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\"")
972 xpr
973 JSON_HEDLEY_DIAGNOSTIC_POP
974# else
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\"")
979 xpr
980 JSON_HEDLEY_DIAGNOSTIC_POP
981# endif
982# else
983# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr)
984 JSON_HEDLEY_DIAGNOSTIC_PUSH
985 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"")
986 xpr
987 JSON_HEDLEY_DIAGNOSTIC_POP
988# endif
989# endif
990#endif
992#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
993#endif
994
995#if defined(JSON_HEDLEY_CONST_CAST)
996#undef JSON_HEDLEY_CONST_CAST
997#endif
998#if defined(__cplusplus)
999# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1000#elif
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
1007 ((T) (expr));
1008 JSON_HEDLEY_DIAGNOSTIC_POP
1009 }))
1010#else
1011# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1012#endif
1013
1014#if defined(JSON_HEDLEY_REINTERPRET_CAST)
1015#undef JSON_HEDLEY_REINTERPRET_CAST
1016#endif
1017#if defined(__cplusplus)
1018#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1019#else
1020#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1021#endif
1022
1023#if defined(JSON_HEDLEY_STATIC_CAST)
1024#undef JSON_HEDLEY_STATIC_CAST
1025#endif
1026#if defined(__cplusplus)
1027#define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1028#else
1029#define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1030#endif
1031
1032#if defined(JSON_HEDLEY_CPP_CAST)
1033#undef JSON_HEDLEY_CPP_CAST
1034#endif
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\"")
1040 ((T) (expr))
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
1047# else
1048# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1049# endif
1050#else
1051# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1052#endif
1053
1054#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1055#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1056#endif
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")
1073#elif
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)")
1094#else
1095#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1096#endif
1097
1098#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1099#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1100#endif
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))
1113#elif
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")
1125#else
1126#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1127#endif
1128
1129#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1130#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1131#endif
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)")
1148#elif
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")
1157#else
1158#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1159#endif
1160
1161#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1162#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1163#endif
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\"")
1170#else
1171#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1172#endif
1173
1174#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1175#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1176#endif
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")
1185#else
1186#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1187#endif
1188
1189#if defined(JSON_HEDLEY_DEPRECATED)
1190#undef JSON_HEDLEY_DEPRECATED
1191#endif
1192#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1193#undef JSON_HEDLEY_DEPRECATED_FOR
1194#endif
1195#if
1198#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1199#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1200#elif
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)]])
1218#elif
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__))
1237#elif
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")
1246#else
1247#define JSON_HEDLEY_DEPRECATED(since)
1248#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1249#endif
1250
1251#if defined(JSON_HEDLEY_UNAVAILABLE)
1252#undef JSON_HEDLEY_UNAVAILABLE
1253#endif
1254#if
1255 JSON_HEDLEY_HAS_ATTRIBUTE(warning) ||
1259#define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1260#else
1261#define JSON_HEDLEY_UNAVAILABLE(available_since)
1262#endif
1263
1264#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1265#undef JSON_HEDLEY_WARN_UNUSED_RESULT
1266#endif
1267#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1268#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1269#endif
1270#if
1271 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) ||
1275 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1277 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1279 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1281 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1285 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) ||
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_
1299#else
1300#define JSON_HEDLEY_WARN_UNUSED_RESULT
1301#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1302#endif
1303
1304#if defined(JSON_HEDLEY_SENTINEL)
1305#undef JSON_HEDLEY_SENTINEL
1306#endif
1307#if
1308 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) ||
1313#define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1314#else
1315#define JSON_HEDLEY_SENTINEL(position)
1316#endif
1317
1318#if defined(JSON_HEDLEY_NO_RETURN)
1319#undef JSON_HEDLEY_NO_RETURN
1320#endif
1322#define JSON_HEDLEY_NO_RETURN __noreturn
1323#elif
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]])
1331#elif
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")
1352#elif
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)
1362#else
1363#define JSON_HEDLEY_NO_RETURN
1364#endif
1365
1366#if defined(JSON_HEDLEY_NO_ESCAPE)
1367#undef JSON_HEDLEY_NO_ESCAPE
1368#endif
1369#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1370#define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1371#else
1372#define JSON_HEDLEY_NO_ESCAPE
1373#endif
1374
1375#if defined(JSON_HEDLEY_UNREACHABLE)
1376#undef JSON_HEDLEY_UNREACHABLE
1377#endif
1378#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1379#undef JSON_HEDLEY_UNREACHABLE_RETURN
1380#endif
1381#if defined(JSON_HEDLEY_ASSUME)
1382#undef JSON_HEDLEY_ASSUME
1383#endif
1384#if
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)
1391#elif
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)
1396#else
1397#define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1398#endif
1399#endif
1400#if
1401 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) ||
1408#define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1409#elif defined(JSON_HEDLEY_ASSUME)
1410#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1411#endif
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)))
1415#else
1416#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1417#endif
1418#endif
1419#if defined(JSON_HEDLEY_UNREACHABLE)
1420#if
1423#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1424#else
1425#define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1426#endif
1427#else
1428#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1429#endif
1430#if !defined(JSON_HEDLEY_UNREACHABLE)
1431#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1432#endif
1433
1435#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1436#pragma clang diagnostic ignored "-Wpedantic"
1437#endif
1438#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1439#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1440#endif
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"
1446#endif
1447#endif
1448#if defined(JSON_HEDLEY_NON_NULL)
1449#undef JSON_HEDLEY_NON_NULL
1450#endif
1451#if
1452 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) ||
1456#define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1457#else
1458#define JSON_HEDLEY_NON_NULL(...)
1459#endif
1461
1462#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1463#undef JSON_HEDLEY_PRINTF_FORMAT
1464#endif
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)))
1469#elif
1470 JSON_HEDLEY_HAS_ATTRIBUTE(format) ||
1476 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1478 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1480 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1482 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
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))
1490#else
1491#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1492#endif
1493
1494#if defined(JSON_HEDLEY_CONSTEXPR)
1495#undef JSON_HEDLEY_CONSTEXPR
1496#endif
1497#if defined(__cplusplus)
1498#if __cplusplus >= 201103L
1499#define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1500#endif
1501#endif
1502#if !defined(JSON_HEDLEY_CONSTEXPR)
1503#define JSON_HEDLEY_CONSTEXPR
1504#endif
1505
1506#if defined(JSON_HEDLEY_PREDICT)
1507#undef JSON_HEDLEY_PREDICT
1508#endif
1509#if defined(JSON_HEDLEY_LIKELY)
1510#undef JSON_HEDLEY_LIKELY
1511#endif
1512#if defined(JSON_HEDLEY_UNLIKELY)
1513#undef JSON_HEDLEY_UNLIKELY
1514#endif
1515#if defined(JSON_HEDLEY_UNPREDICTABLE)
1516#undef JSON_HEDLEY_UNPREDICTABLE
1517#endif
1518#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1519#define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1520#endif
1521#if
1522 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) ||
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 )
1530#elif
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)
1550 (__extension__ ({
1551 double hedley_probability_ = (probability);
1552 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr)));
1553 }))
1554# define JSON_HEDLEY_PREDICT_FALSE(expr, probability)
1555 (__extension__ ({
1556 double hedley_probability_ = (probability);
1557 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr)));
1558 }))
1559# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1560# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1561#else
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))
1567#endif
1568#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1569#define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1570#endif
1571
1572#if defined(JSON_HEDLEY_MALLOC)
1573#undef JSON_HEDLEY_MALLOC
1574#endif
1575#if
1576 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) ||
1583 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1585 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1587 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1589 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
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")
1597#elif
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)
1601#else
1602#define JSON_HEDLEY_MALLOC
1603#endif
1604
1605#if defined(JSON_HEDLEY_PURE)
1606#undef JSON_HEDLEY_PURE
1607#endif
1608#if
1616 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1618 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1620 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1622 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
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) &&
1632 (
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)
1636 )
1637# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1638#else
1639# define JSON_HEDLEY_PURE
1640#endif
1641
1642#if defined(JSON_HEDLEY_CONST)
1643#undef JSON_HEDLEY_CONST
1644#endif
1645#if
1653 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1655 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1657 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1659 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1665#define JSON_HEDLEY_CONST __attribute__((__const__))
1666#elif
1667 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1668#define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1669#else
1670#define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1671#endif
1672
1673#if defined(JSON_HEDLEY_RESTRICT)
1674#undef JSON_HEDLEY_RESTRICT
1675#endif
1676#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1677#define JSON_HEDLEY_RESTRICT restrict
1678#elif
1690 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) ||
1692 defined(__clang__) ||
1694#define JSON_HEDLEY_RESTRICT __restrict
1695#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1696#define JSON_HEDLEY_RESTRICT _Restrict
1697#else
1698#define JSON_HEDLEY_RESTRICT
1699#endif
1700
1701#if defined(JSON_HEDLEY_INLINE)
1702#undef JSON_HEDLEY_INLINE
1703#endif
1704#if
1705 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) ||
1706 (defined(__cplusplus) && (__cplusplus >= 199711L))
1707#define JSON_HEDLEY_INLINE inline
1708#elif
1709 defined(JSON_HEDLEY_GCC_VERSION) ||
1710 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1711#define JSON_HEDLEY_INLINE __inline__
1712#elif
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
1724#else
1725#define JSON_HEDLEY_INLINE
1726#endif
1727
1728#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1729#undef JSON_HEDLEY_ALWAYS_INLINE
1730#endif
1731#if
1732 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) ||
1739 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1741 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1743 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1745 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1751# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1752#elif
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) &&
1757 (
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)
1764 )
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")
1768#else
1769# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1770#endif
1771
1772#if defined(JSON_HEDLEY_NEVER_INLINE)
1773#undef JSON_HEDLEY_NEVER_INLINE
1774#endif
1775#if
1776 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) ||
1783 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1785 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1787 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1789 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) ||
1795#define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1796#elif
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)
1810#else
1811#define JSON_HEDLEY_NEVER_INLINE
1812#endif
1813
1814#if defined(JSON_HEDLEY_PRIVATE)
1815#undef JSON_HEDLEY_PRIVATE
1816#endif
1817#if defined(JSON_HEDLEY_PUBLIC)
1818#undef JSON_HEDLEY_PUBLIC
1819#endif
1820#if defined(JSON_HEDLEY_IMPORT)
1821#undef JSON_HEDLEY_IMPORT
1822#endif
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)
1827#else
1828# if
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) ||
1835 (
1836 defined(__TI_EABI__) &&
1837 (
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)
1840 )
1841 ) ||
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")))
1845# else
1846# define JSON_HEDLEY_PRIVATE
1847# define JSON_HEDLEY_PUBLIC
1848# endif
1849# define JSON_HEDLEY_IMPORT extern
1850#endif
1851
1852#if defined(JSON_HEDLEY_NO_THROW)
1853#undef JSON_HEDLEY_NO_THROW
1854#endif
1855#if
1856 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) ||
1860#define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1861#elif
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)
1866#else
1867#define JSON_HEDLEY_NO_THROW
1868#endif
1869
1870#if defined(JSON_HEDLEY_FALL_THROUGH)
1871#undef JSON_HEDLEY_FALL_THROUGH
1872#endif
1873#if
1874 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) ||
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
1884#else
1885#define JSON_HEDLEY_FALL_THROUGH
1886#endif
1887
1888#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1889#undef JSON_HEDLEY_RETURNS_NON_NULL
1890#endif
1891#if
1892 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) ||
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_
1898#else
1899#define JSON_HEDLEY_RETURNS_NON_NULL
1900#endif
1901
1902#if defined(JSON_HEDLEY_ARRAY_PARAM)
1903#undef JSON_HEDLEY_ARRAY_PARAM
1904#endif
1905#if
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)
1912#else
1913#define JSON_HEDLEY_ARRAY_PARAM(name)
1914#endif
1915
1916#if defined(JSON_HEDLEY_IS_CONSTANT)
1917#undef JSON_HEDLEY_IS_CONSTANT
1918#endif
1919#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1920#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1921#endif
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_
1926#endif
1927#if
1928 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) ||
1935 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) ||
1938#define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1939#endif
1940#if !defined(__cplusplus)
1941# if
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*)
1951#else
1952#include <stdint.h>
1953#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1954#endif
1955# elif
1956 (
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)
1968#else
1969#include <stdint.h>
1970#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1971#endif
1972# elif
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) ||
1982 defined(__clang__)
1983# define JSON_HEDLEY_IS_CONSTEXPR_(expr) (
1984 sizeof(void) !=
1985 sizeof(*(
1986 1 ?
1987 ((void*) ((expr) * 0L) ) : \
1988((struct{ char v[sizeof(void) * 2]; } *) 1)
1989 )
1990 )
1991 )
1992# endif
1993#endif
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)
1997#endif
1998#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1999#else
2000#if !defined(JSON_HEDLEY_IS_CONSTANT)
2001#define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2002#endif
2003#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2004#endif
2005
2006#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2007#undef JSON_HEDLEY_BEGIN_C_DECLS
2008#endif
2009#if defined(JSON_HEDLEY_END_C_DECLS)
2010#undef JSON_HEDLEY_END_C_DECLS
2011#endif
2012#if defined(JSON_HEDLEY_C_DECL)
2013#undef JSON_HEDLEY_C_DECL
2014#endif
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"
2019#else
2020#define JSON_HEDLEY_BEGIN_C_DECLS
2021#define JSON_HEDLEY_END_C_DECLS
2022#define JSON_HEDLEY_C_DECL
2023#endif
2024
2025#if defined(JSON_HEDLEY_STATIC_ASSERT)
2026#undef JSON_HEDLEY_STATIC_ASSERT
2027#endif
2028#if
2029 !defined(__cplusplus) && (
2030 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) ||
2031 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) ||
2034 defined(_Static_assert)
2035 )
2036# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2037#elif
2038 (defined(__cplusplus) && (__cplusplus >= 201103L)) ||
2041# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2042#else
2043# define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2044#endif
2045
2046#if defined(JSON_HEDLEY_NULL)
2047#undef JSON_HEDLEY_NULL
2048#endif
2049#if defined(__cplusplus)
2050#if __cplusplus >= 201103L
2051#define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2052#elif defined(NULL)
2053#define JSON_HEDLEY_NULL NULL
2054#else
2055#define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2056#endif
2057#elif defined(NULL)
2058#define JSON_HEDLEY_NULL NULL
2059#else
2060#define JSON_HEDLEY_NULL ((void*) 0)
2061#endif
2062
2063#if defined(JSON_HEDLEY_MESSAGE)
2064#undef JSON_HEDLEY_MESSAGE
2065#endif
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
2072#elif
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))
2082#else
2083# define JSON_HEDLEY_MESSAGE(msg)
2084#endif
2085
2086#if defined(JSON_HEDLEY_WARNING)
2087#undef JSON_HEDLEY_WARNING
2088#endif
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
2095#elif
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)
2100#elif
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))
2104#else
2105# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2106#endif
2107
2108#if defined(JSON_HEDLEY_REQUIRE)
2109#undef JSON_HEDLEY_REQUIRE
2110#endif
2111#if defined(JSON_HEDLEY_REQUIRE_MSG)
2112#undef JSON_HEDLEY_REQUIRE_MSG
2113#endif
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
2126# else
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")))
2129# endif
2130#else
2131# define JSON_HEDLEY_REQUIRE(expr)
2132# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2133#endif
2134
2135#if defined(JSON_HEDLEY_FLAGS)
2136#undef JSON_HEDLEY_FLAGS
2137#endif
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__))
2140#else
2141#define JSON_HEDLEY_FLAGS
2142#endif
2143
2144#if defined(JSON_HEDLEY_FLAGS_CAST)
2145#undef JSON_HEDLEY_FLAGS_CAST
2146#endif
2148# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({
2149 JSON_HEDLEY_DIAGNOSTIC_PUSH
2150 _Pragma("warning(disable:188)")
2151 ((T) (expr));
2152 JSON_HEDLEY_DIAGNOSTIC_POP
2153 }))
2154#else
2155# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2156#endif
2157
2158#if defined(JSON_HEDLEY_EMPTY_BASES)
2159#undef JSON_HEDLEY_EMPTY_BASES
2160#endif
2161#if
2164#define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2165#else
2166#define JSON_HEDLEY_EMPTY_BASES
2167#endif
2168
2169 /* Remaining macros are deprecated. */
2170
2171#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2172#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2173#endif
2174#if defined(__clang__)
2175#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2176#else
2177#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2178#endif
2179
2180#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2181#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2182#endif
2183#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2184
2185#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2186#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2187#endif
2188#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2189
2190#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2191#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2192#endif
2193#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2194
2195#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2196#undef JSON_HEDLEY_CLANG_HAS_FEATURE
2197#endif
2198#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2199
2200#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2201#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2202#endif
2203#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2204
2205#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2206#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2207#endif
2208#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2209
2210#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2211#undef JSON_HEDLEY_CLANG_HAS_WARNING
2212#endif
2213#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2214
2215#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2216
2217
2218// This file contains all internal macro definitions
2219// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2220
2221// exclude unsupported compilers
2222#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2223#if defined(__clang__)
2224#if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2225#error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2226#endif
2227#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2228#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2229#error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2230#endif
2231#endif
2232#endif
2233
2234// C++ language standard detection
2235// if the user manually specified the used c++ version this is skipped
2236#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2237#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2238#define JSON_HAS_CPP_20
2239#define JSON_HAS_CPP_17
2240#define JSON_HAS_CPP_14
2241#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2242#define JSON_HAS_CPP_17
2243#define JSON_HAS_CPP_14
2244#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2245#define JSON_HAS_CPP_14
2246#endif
2247// the cpp 11 flag is always specified because it is the minimal required version
2248#define JSON_HAS_CPP_11
2249#endif
2250
2251// disable documentation warnings on clang
2252#if defined(__clang__)
2253#pragma clang diagnostic push
2254#pragma clang diagnostic ignored "-Wdocumentation"
2255#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2256#endif
2257
2258// allow to disable exceptions
2259#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2260#define JSON_THROW(exception) throw exception
2261#define JSON_TRY try
2262#define JSON_CATCH(exception) catch(exception)
2263#define JSON_INTERNAL_CATCH(exception) catch(exception)
2264#else
2265#include <cstdlib>
2266#define JSON_THROW(exception) std::abort()
2267#define JSON_TRY if(true)
2268#define JSON_CATCH(exception) if(false)
2269#define JSON_INTERNAL_CATCH(exception) if(false)
2270#endif
2271
2272// override exception macros
2273#if defined(JSON_THROW_USER)
2274#undef JSON_THROW
2275#define JSON_THROW JSON_THROW_USER
2276#endif
2277#if defined(JSON_TRY_USER)
2278#undef JSON_TRY
2279#define JSON_TRY JSON_TRY_USER
2280#endif
2281#if defined(JSON_CATCH_USER)
2282#undef JSON_CATCH
2283#define JSON_CATCH JSON_CATCH_USER
2284#undef JSON_INTERNAL_CATCH
2285#define JSON_INTERNAL_CATCH JSON_CATCH_USER
2286#endif
2287#if defined(JSON_INTERNAL_CATCH_USER)
2288#undef JSON_INTERNAL_CATCH
2289#define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2290#endif
2291
2292// allow to override assert
2293#if !defined(JSON_ASSERT)
2294#include <cassert> // assert
2295#define JSON_ASSERT(x) assert(x)
2296#endif
2297
2298// allow to access some private functions (needed by the test suite)
2299#if defined(JSON_TESTS_PRIVATE)
2300#define JSON_PRIVATE_UNLESS_TESTED public
2301#else
2302#define JSON_PRIVATE_UNLESS_TESTED private
2303#endif
2304
2305/*!
2306@brief macro to briefly define a mapping between an enum and JSON
2307@def NLOHMANN_JSON_SERIALIZE_ENUM
2308@since version 3.4.0
2309*/
2310#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)
2311 template<typename BasicJsonType>
2312 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)
2313 {
2314 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");
2315 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;
2316 auto it = std::find_if(std::begin(m), std::end(m),
2317 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool
2318 {
2319 return ej_pair.first == e;
2320 });
2321 j = ((it != std::end(m)) ? it : std::begin(m))->second;
2322 }
2323 template<typename BasicJsonType>
2324 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)
2325 {
2326 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");
2327 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;
2328 auto it = std::find_if(std::begin(m), std::end(m),
2329 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool
2330 {
2331 return ej_pair.second == j;
2332 });
2333 e = ((it != std::end(m)) ? it : std::begin(m))->first;
2334 }
2335
2336// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2337// may be removed in the future once the class is split.
2338
2339#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
2340 template<template<typename, typename, typename...> class ObjectType,
2341 template<typename, typename...> class ArrayType,
2342 class StringType, class BooleanType, class NumberIntegerType,
2343 class NumberUnsignedType, class NumberFloatType,
2344 template<typename> class AllocatorType,
2345 template<typename, typename = void> class JSONSerializer,
2346 class BinaryType>
2347
2348#define NLOHMANN_BASIC_JSON_TPL
2349 basic_json<ObjectType, ArrayType, StringType, BooleanType,
2350 NumberIntegerType, NumberUnsignedType, NumberFloatType,
2351 AllocatorType, JSONSerializer, BinaryType>
2352
2353// Macros to simplify conversion from/to types
2354
2355#define NLOHMANN_JSON_EXPAND( x ) x
2356#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
2357#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__,
2421 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2422#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2423#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2424#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2425#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2426#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2427#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)
2428#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)
2429#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)
2430#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)
2431#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)
2432#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)
2433#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)
2434#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)
2435#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)
2436#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)
2437#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)
2438#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)
2439#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)
2440#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)
2441#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)
2442#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)
2443#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)
2444#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)
2445#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)
2446#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)
2447#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)
2448#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)
2449#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)
2450#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)
2451#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)
2452#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)
2453#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)
2454#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)
2455#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)
2456#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)
2457#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)
2458#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)
2459#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)
2460#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)
2461#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)
2462#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)
2463#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)
2464#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)
2465#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)
2466#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)
2467#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)
2468#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)
2469#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)
2470#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)
2471#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)
2472#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)
2473#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)
2474#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)
2475#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)
2476#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)
2477#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)
2478#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)
2479#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)
2480#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)
2481#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)
2482#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)
2483#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)
2484#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)
2485
2486#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2487#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2488
2489/*!
2490@brief macro
2491@def NLOHMANN_DEFINE_TYPE_INTRUSIVE
2492@since version 3.9.0
2493*/
2494#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...)
2495 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__)) }
2496 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__)) }
2497
2498/*!
2499@brief macro
2500@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
2501@since version 3.9.0
2502*/
2503#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...)
2504 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__)) }
2505 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__)) }
2506
2507#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2508#define JSON_USE_IMPLICIT_CONVERSIONS 1
2509#endif
2510
2512#define JSON_EXPLICIT
2513#else
2514#define JSON_EXPLICIT explicit
2515#endif
2516
2517#ifndef JSON_DIAGNOSTICS
2518#define JSON_DIAGNOSTICS 0
2519#endif
2520
2521
2522namespace nlohmann
2523{
2524 namespace detail
2525 {
2526
2527 /*!
2528 @brief replace all occurrences of a substring by another string
2529
2530 @param[in,out] s the string to manipulate; changed so that all
2531 occurrences of @a f are replaced with @a t
2532 @param[in] f the substring to replace with @a t
2533 @param[in] t the string to replace @a f
2534
2535 @pre The search string @a f must not be empty. **This precondition is
2536 enforced with an assertion.**
2537
2538 @since version 2.0.0
2539 */
2540 inline void replace_substring(std::string& s, const std::string& f,
2541 const std::string& t)
2542 {
2543 JSON_ASSERT(!f.empty());
2544 for (auto pos = s.find(f); // find first occurrence of f
2545 pos != std::string::npos; // make sure f was found
2546 s.replace(pos, f.size(), t), // replace with t, and
2547 pos = s.find(f, pos + t.size())) // find next occurrence of f
2548 {
2549 }
2550 }
2551
2552 /*!
2553 * @brief string escaping as described in RFC 6901 (Sect. 4)
2554 * @param[in] s string to escape
2555 * @return escaped string
2556 *
2557 * Note the order of escaping "~" to "~0" and "/" to "~1" is important.
2558 */
2559 inline std::string escape(std::string s)
2560 {
2561 replace_substring(s, "~", "~0");
2562 replace_substring(s, "/", "~1");
2563 return s;
2564 }
2565
2566 /*!
2567 * @brief string unescaping as described in RFC 6901 (Sect. 4)
2568 * @param[in] s string to unescape
2569 * @return unescaped string
2570 *
2571 * Note the order of escaping "~1" to "/" and "~0" to "~" is important.
2572 */
2573 static void unescape(std::string& s)
2574 {
2575 replace_substring(s, "~1", "/");
2576 replace_substring(s, "~0", "~");
2577 }
2578
2579 } // namespace detail
2580} // namespace nlohmann
2581
2582// #include <nlohmann/detail/input/position_t.hpp>
2583
2584
2585#include <cstddef> // size_t
2586
2587namespace nlohmann
2588{
2589 namespace detail
2590 {
2591 /// struct to capture the start position of the current token
2593 {
2594 /// the total number of characters read
2596 /// the number of characters read in the current line
2598 /// the number of lines read
2599 std::size_t lines_read = 0;
2600
2601 /// conversion to size_t to preserve SAX interface
2602 constexpr operator size_t() const
2603 {
2604 return chars_read_total;
2605 }
2606 };
2607
2608 } // namespace detail
2609} // namespace nlohmann
2610
2611// #include <nlohmann/detail/macro_scope.hpp>
2612
2613
2614namespace nlohmann
2615{
2616 namespace detail
2617 {
2618 ////////////////
2619 // exceptions //
2620 ////////////////
2621
2622 /*!
2623 @brief general exception of the @ref basic_json class
2624
2625 This class is an extension of `std::exception` objects with a member @a id for
2626 exception ids. It is used as the base class for all exceptions thrown by the
2627 @ref basic_json class. This class can hence be used as "wildcard" to catch
2628 exceptions.
2629
2630 Subclasses:
2631 - @ref parse_error for exceptions indicating a parse error
2632 - @ref invalid_iterator for exceptions indicating errors with iterators
2633 - @ref type_error for exceptions indicating executing a member function with
2634 a wrong type
2635 - @ref out_of_range for exceptions indicating access out of the defined range
2636 - @ref other_error for exceptions indicating other library errors
2637
2638 @internal
2639 @note To have nothrow-copy-constructible exceptions, we internally use
2640 `std::runtime_error` which can cope with arbitrary-length error messages.
2641 Intermediate strings are built with static functions and then passed to
2642 the actual constructor.
2643 @endinternal
2644
2645 @liveexample{The following code shows how arbitrary library exceptions can be
2646 caught.,exception}
2647
2648 @since version 3.0.0
2649 */
2650 class exception : public std::exception
2651 {
2652 public:
2653 /// returns the explanatory string
2654 const char* what() const noexcept override
2655 {
2656 return m.what();
2657 }
2658
2659 /// the id of the exception
2660 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
2661
2662 protected:
2664 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2665
2666 static std::string name(const std::string& ename, int id_)
2667 {
2668 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2669 }
2670
2671 template<typename BasicJsonType>
2672 static std::string diagnostics(const BasicJsonType& leaf_element)
2673 {
2676 for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
2677 {
2678 switch (current->m_parent->type())
2679 {
2680 case value_t::array:
2681 {
2682 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
2683 {
2685 {
2687 break;
2688 }
2689 }
2690 break;
2691 }
2692
2693 case value_t::object:
2694 {
2695 for (const auto& element : *current->m_parent->m_value.object)
2696 {
2697 if (&element.second == current)
2698 {
2700 break;
2701 }
2702 }
2703 break;
2704 }
2705
2706 case value_t::null: // LCOV_EXCL_LINE
2707 case value_t::string: // LCOV_EXCL_LINE
2708 case value_t::boolean: // LCOV_EXCL_LINE
2709 case value_t::number_integer: // LCOV_EXCL_LINE
2710 case value_t::number_unsigned: // LCOV_EXCL_LINE
2711 case value_t::number_float: // LCOV_EXCL_LINE
2712 case value_t::binary: // LCOV_EXCL_LINE
2713 case value_t::discarded: // LCOV_EXCL_LINE
2714 default: // LCOV_EXCL_LINE
2715 break; // LCOV_EXCL_LINE
2716 }
2717 }
2718
2719 if (tokens.empty())
2720 {
2721 return "";
2722 }
2723
2724 return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
2725 [](const std::string& a, const std::string& b)
2726 {
2727 return a + "/" + detail::escape(b);
2728 }) + ") ";
2729#else
2730 static_cast<void>(leaf_element);
2731 return "";
2732#endif
2733 }
2734
2735 private:
2736 /// an exception object as storage for error messages
2737 std::runtime_error m;
2738 };
2739
2740 /*!
2741 @brief exception indicating a parse error
2742
2743 This exception is thrown by the library when a parse error occurs. Parse errors
2744 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
2745 as when using JSON Patch.
2746
2747 Member @a byte holds the byte index of the last read character in the input
2748 file.
2749
2750 Exceptions have ids 1xx.
2751
2752 name / id | example message | description
2753 ------------------------------ | --------------- | -------------------------
2754 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.
2755 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.
2756 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.
2757 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.
2758 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.
2759 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`.
2760 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.
2761 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.
2762 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
2763 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.
2764 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.
2765 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.
2766 json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
2767 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.
2768
2769 @note For an input with n bytes, 1 is the index of the first character and n+1
2770 is the index of the terminating null byte or the end of file. This also
2771 holds true when reading a byte vector (CBOR or MessagePack).
2772
2773 @liveexample{The following code shows how a `parse_error` exception can be
2774 caught.,parse_error}
2775
2776 @sa - @ref exception for the base class of the library exceptions
2777 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2778 @sa - @ref type_error for exceptions indicating executing a member function with
2779 a wrong type
2780 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2781 @sa - @ref other_error for exceptions indicating other library errors
2782
2783 @since version 3.0.0
2784 */
2785 class parse_error : public exception
2786 {
2787 public:
2788 /*!
2789 @brief create a parse error exception
2790 @param[in] id_ the id of the exception
2791 @param[in] pos the position where the error occurred (or with
2792 chars_read_total=0 if the position cannot be
2793 determined)
2794 @param[in] what_arg the explanatory string
2795 @return parse_error object
2796 */
2797 template<typename BasicJsonType>
2798 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
2799 {
2800 std::string w = exception::name("parse_error", id_) + "parse error" +
2803 }
2804
2805 template<typename BasicJsonType>
2806 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
2807 {
2808 std::string w = exception::name("parse_error", id_) + "parse error" +
2809 (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2811 return parse_error(id_, byte_, w.c_str());
2812 }
2813
2814 /*!
2815 @brief byte index of the parse error
2816
2817 The byte index of the last read character in the input file.
2818
2819 @note For an input with n bytes, 1 is the index of the first character and
2820 n+1 is the index of the terminating null byte or the end of file.
2821 This also holds true when reading a byte vector (CBOR or MessagePack).
2822 */
2823 const std::size_t byte;
2824
2825 private:
2826 parse_error(int id_, std::size_t byte_, const char* what_arg)
2827 : exception(id_, what_arg), byte(byte_) {}
2828
2829 static std::string position_string(const position_t& pos)
2830 {
2831 return " at line " + std::to_string(pos.lines_read + 1) +
2832 ", column " + std::to_string(pos.chars_read_current_line);
2833 }
2834 };
2835
2836 /*!
2837 @brief exception indicating errors with iterators
2838
2839 This exception is thrown if iterators passed to a library function do not match
2840 the expected semantics.
2841
2842 Exceptions have ids 2xx.
2843
2844 name / id | example message | description
2845 ----------------------------------- | --------------- | -------------------------
2846 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.
2847 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.
2848 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.
2849 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.
2850 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.
2851 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.
2852 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.
2853 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.
2854 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.
2855 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.
2856 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.
2857 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
2858 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
2859 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().
2860
2861 @liveexample{The following code shows how an `invalid_iterator` exception can be
2862 caught.,invalid_iterator}
2863
2864 @sa - @ref exception for the base class of the library exceptions
2865 @sa - @ref parse_error for exceptions indicating a parse error
2866 @sa - @ref type_error for exceptions indicating executing a member function with
2867 a wrong type
2868 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2869 @sa - @ref other_error for exceptions indicating other library errors
2870
2871 @since version 3.0.0
2872 */
2874 {
2875 public:
2876 template<typename BasicJsonType>
2877 static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
2878 {
2879 std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
2880 return invalid_iterator(id_, w.c_str());
2881 }
2882
2883 private:
2885 invalid_iterator(int id_, const char* what_arg)
2886 : exception(id_, what_arg) {}
2887 };
2888
2889 /*!
2890 @brief exception indicating executing a member function with a wrong type
2891
2892 This exception is thrown in case of a type error; that is, a library function is
2893 executed on a JSON value whose type does not match the expected semantics.
2894
2895 Exceptions have ids 3xx.
2896
2897 name / id | example message | description
2898 ----------------------------- | --------------- | -------------------------
2899 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.
2900 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.
2901 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 &.
2902 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
2903 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
2904 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
2905 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
2906 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.
2907 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
2908 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
2909 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.
2910 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
2911 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.
2912 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
2913 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.
2914 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. |
2915 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) |
2916
2917 @liveexample{The following code shows how a `type_error` exception can be
2918 caught.,type_error}
2919
2920 @sa - @ref exception for the base class of the library exceptions
2921 @sa - @ref parse_error for exceptions indicating a parse error
2922 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2923 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2924 @sa - @ref other_error for exceptions indicating other library errors
2925
2926 @since version 3.0.0
2927 */
2928 class type_error : public exception
2929 {
2930 public:
2931 template<typename BasicJsonType>
2932 static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
2933 {
2934 std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
2935 return type_error(id_, w.c_str());
2936 }
2937
2938 private:
2940 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2941 };
2942
2943 /*!
2944 @brief exception indicating access out of the defined range
2945
2946 This exception is thrown in case a library function is called on an input
2947 parameter that exceeds the expected range, for instance in case of array
2948 indices or nonexisting object keys.
2949
2950 Exceptions have ids 4xx.
2951
2952 name / id | example message | description
2953 ------------------------------- | --------------- | -------------------------
2954 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.
2955 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.
2956 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
2957 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
2958 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.
2959 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.
2960 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) |
2961 json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
2962 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 |
2963
2964 @liveexample{The following code shows how an `out_of_range` exception can be
2965 caught.,out_of_range}
2966
2967 @sa - @ref exception for the base class of the library exceptions
2968 @sa - @ref parse_error for exceptions indicating a parse error
2969 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2970 @sa - @ref type_error for exceptions indicating executing a member function with
2971 a wrong type
2972 @sa - @ref other_error for exceptions indicating other library errors
2973
2974 @since version 3.0.0
2975 */
2977 {
2978 public:
2979 template<typename BasicJsonType>
2980 static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
2981 {
2982 std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
2983 return out_of_range(id_, w.c_str());
2984 }
2985
2986 private:
2988 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2989 };
2990
2991 /*!
2992 @brief exception indicating other library errors
2993
2994 This exception is thrown in case of errors that cannot be classified with the
2995 other exception types.
2996
2997 Exceptions have ids 5xx.
2998
2999 name / id | example message | description
3000 ------------------------------ | --------------- | -------------------------
3001 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
3002
3003 @sa - @ref exception for the base class of the library exceptions
3004 @sa - @ref parse_error for exceptions indicating a parse error
3005 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
3006 @sa - @ref type_error for exceptions indicating executing a member function with
3007 a wrong type
3008 @sa - @ref out_of_range for exceptions indicating access out of the defined range
3009
3010 @liveexample{The following code shows how an `other_error` exception can be
3011 caught.,other_error}
3012
3013 @since version 3.0.0
3014 */
3015 class other_error : public exception
3016 {
3017 public:
3018 template<typename BasicJsonType>
3019 static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3020 {
3021 std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
3022 return other_error(id_, w.c_str());
3023 }
3024
3025 private:
3027 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3028 };
3029 } // namespace detail
3030} // namespace nlohmann
3031
3032// #include <nlohmann/detail/macro_scope.hpp>
3033
3034// #include <nlohmann/detail/meta/cpp_future.hpp>
3035
3036
3037#include <cstddef> // size_t
3038#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3039#include <utility> // index_sequence, make_index_sequence, index_sequence_for
3040
3041// #include <nlohmann/detail/macro_scope.hpp>
3042
3043
3044namespace nlohmann
3045{
3046 namespace detail
3047 {
3048
3049 template<typename T>
3050 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3051
3052#ifdef JSON_HAS_CPP_14
3053
3054 // the following utilities are natively available in C++14
3055 using std::enable_if_t;
3056 using std::index_sequence;
3057 using std::make_index_sequence;
3058 using std::index_sequence_for;
3059
3060#else
3061
3062 // alias templates to reduce boilerplate
3063 template<bool B, typename T = void>
3064 using enable_if_t = typename std::enable_if<B, T>::type;
3065
3066 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3067 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3068
3069 //// START OF CODE FROM GOOGLE ABSEIL
3070
3071 // integer_sequence
3072 //
3073 // Class template representing a compile-time integer sequence. An instantiation
3074 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3075 // type through its template arguments (which is a common need when
3076 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3077 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3078 //
3079 // Example:
3080 //
3081 // template< class T, T... Ints >
3082 // void user_function(integer_sequence<T, Ints...>);
3083 //
3084 // int main()
3085 // {
3086 // // user_function's `T` will be deduced to `int` and `Ints...`
3087 // // will be deduced to `0, 1, 2, 3, 4`.
3088 // user_function(make_integer_sequence<int, 5>());
3089 // }
3090 template <typename T, T... Ints>
3092 {
3093 using value_type = T;
3094 static constexpr std::size_t size() noexcept
3095 {
3096 return sizeof...(Ints);
3097 }
3098 };
3099
3100 // index_sequence
3101 //
3102 // A helper template for an `integer_sequence` of `size_t`,
3103 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3104 // `std::index_sequence`.
3105 template <size_t... Ints>
3107
3109 {
3110
3111 template <typename Seq, size_t SeqSize, size_t Rem>
3112 struct Extend;
3113
3114 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3115 template <typename T, T... Ints, size_t SeqSize>
3117 {
3118 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3119 };
3120
3121 template <typename T, T... Ints, size_t SeqSize>
3123 {
3124 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3125 };
3126
3127 // Recursion helper for 'make_integer_sequence<T, N>'.
3128 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3129 template <typename T, size_t N>
3130 struct Gen
3131 {
3132 using type =
3133 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3134 };
3135
3136 template <typename T>
3137 struct Gen<T, 0>
3138 {
3140 };
3141
3142 } // namespace utility_internal
3143
3144 // Compile-time sequences of integers
3145
3146 // make_integer_sequence
3147 //
3148 // This template alias is equivalent to
3149 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3150 // replacement for C++14's `std::make_integer_sequence`.
3151 template <typename T, T N>
3153
3154 // make_index_sequence
3155 //
3156 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3157 // and is designed to be a drop-in replacement for C++14's
3158 // `std::make_index_sequence`.
3159 template <size_t N>
3161
3162 // index_sequence_for
3163 //
3164 // Converts a typename pack into an index sequence of the same length, and
3165 // is designed to be a drop-in replacement for C++14's
3166 // `std::index_sequence_for()`
3167 template <typename... Ts>
3169
3170 //// END OF CODE FROM GOOGLE ABSEIL
3171
3172#endif
3173
3174// dispatch utility (taken from ranges-v3)
3175 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3176 template<> struct priority_tag<0> {};
3177
3178 // taken from ranges-v3
3179 template<typename T>
3181 {
3182 static constexpr T value{};
3183 };
3184
3185 template<typename T>
3186 constexpr T static_const<T>::value;
3187
3188 } // namespace detail
3189} // namespace nlohmann
3190
3191// #include <nlohmann/detail/meta/identity_tag.hpp>
3192
3193
3194namespace nlohmann
3195{
3196 namespace detail
3197 {
3198 // dispatching helper struct
3199 template <class T> struct identity_tag {};
3200 } // namespace detail
3201} // namespace nlohmann
3202
3203// #include <nlohmann/detail/meta/type_traits.hpp>
3204
3205
3206#include <limits> // numeric_limits
3207#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3208#include <utility> // declval
3209#include <tuple> // tuple
3210
3211// #include <nlohmann/detail/iterators/iterator_traits.hpp>
3212
3213
3214#include <iterator> // random_access_iterator_tag
3215
3216// #include <nlohmann/detail/meta/void_t.hpp>
3217
3218
3219namespace nlohmann
3220{
3221 namespace detail
3222 {
3223 template<typename ...Ts> struct make_void
3224 {
3225 using type = void;
3226 };
3227 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
3228 } // namespace detail
3229} // namespace nlohmann
3230
3231// #include <nlohmann/detail/meta/cpp_future.hpp>
3232
3233
3234namespace nlohmann
3235{
3236 namespace detail
3237 {
3238 template<typename It, typename = void>
3240
3241 template<typename It>
3243 It,
3244 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3245 typename It::reference, typename It::iterator_category >>
3246 {
3248 using value_type = typename It::value_type;
3249 using pointer = typename It::pointer;
3250 using reference = typename It::reference;
3252 };
3253
3254 // This is required as some compilers implement std::iterator_traits in a way that
3255 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3256 template<typename T, typename = void>
3258 {
3259 };
3260
3261 template<typename T>
3263 : iterator_types<T>
3264 {
3265 };
3266
3267 template<typename T>
3269 {
3271 using value_type = T;
3273 using pointer = T*;
3274 using reference = T&;
3275 };
3276 } // namespace detail
3277} // namespace nlohmann
3278
3279// #include <nlohmann/detail/macro_scope.hpp>
3280
3281// #include <nlohmann/detail/meta/cpp_future.hpp>
3282
3283// #include <nlohmann/detail/meta/detected.hpp>
3284
3285
3286#include <type_traits>
3287
3288// #include <nlohmann/detail/meta/void_t.hpp>
3289
3290
3291// https://en.cppreference.com/w/cpp/experimental/is_detected
3292namespace nlohmann
3293{
3294 namespace detail
3295 {
3297 {
3298 nonesuch() = delete;
3299 ~nonesuch() = delete;
3300 nonesuch(nonesuch const&) = delete;
3301 nonesuch(nonesuch const&&) = delete;
3302 void operator=(nonesuch const&) = delete;
3303 void operator=(nonesuch&&) = delete;
3304 };
3305
3306 template<class Default,
3307 class AlwaysVoid,
3308 template<class...> class Op,
3309 class... Args>
3311 {
3312 using value_t = std::false_type;
3313 using type = Default;
3314 };
3315
3316 template<class Default, template<class...> class Op, class... Args>
3317 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
3318 {
3320 using type = Op<Args...>;
3321 };
3322
3323 template<template<class...> class Op, class... Args>
3324 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
3325
3326 template<template<class...> class Op, class... Args>
3328
3329 template<template<class...> class Op, class... Args>
3330 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
3331
3332 template<class Default, template<class...> class Op, class... Args>
3333 using detected_or = detector<Default, void, Op, Args...>;
3334
3335 template<class Default, template<class...> class Op, class... Args>
3336 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
3337
3338 template<class Expected, template<class...> class Op, class... Args>
3340
3341 template<class To, template<class...> class Op, class... Args>
3344 } // namespace detail
3345} // namespace nlohmann
3346
3347// #include <nlohmann/json_fwd.hpp>
3348#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3349#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3350
3351#include <cstdint> // int64_t, uint64_t
3352#include <map> // map
3353#include <memory> // allocator
3354#include <string> // string
3355#include <vector> // vector
3356
3357/*!
3358@brief namespace for Niels Lohmann
3359@see https://github.com/nlohmann
3360@since version 1.0.0
3361*/
3362namespace nlohmann
3363{
3364 /*!
3365 @brief default JSONSerializer template argument
3366
3367 This serializer ignores the template arguments and uses ADL
3368 ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
3369 for serialization.
3370 */
3371 template<typename T = void, typename SFINAE = void>
3372 struct adl_serializer;
3373
3374 template<template<typename U, typename V, typename... Args> class ObjectType =
3375 std::map,
3376 template<typename U, typename... Args> class ArrayType = std::vector,
3377 class StringType = std::string, class BooleanType = bool,
3378 class NumberIntegerType = std::int64_t,
3379 class NumberUnsignedType = std::uint64_t,
3380 class NumberFloatType = double,
3381 template<typename U> class AllocatorType = std::allocator,
3382 template<typename T, typename SFINAE = void> class JSONSerializer =
3384 class BinaryType = std::vector<std::uint8_t>>
3385 class basic_json;
3386
3387 /*!
3388 @brief JSON Pointer
3389
3390 A JSON pointer defines a string syntax for identifying a specific value
3391 within a JSON document. It can be used with functions `at` and
3392 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
3393
3394 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
3395
3396 @since version 2.0.0
3397 */
3398 template<typename BasicJsonType>
3399 class json_pointer;
3400
3401 /*!
3402 @brief default JSON class
3403
3404 This type is the default specialization of the @ref basic_json class which
3405 uses the standard template types.
3406
3407 @since version 1.0.0
3408 */
3409 using json = basic_json<>;
3410
3411 template<class Key, class T, class IgnoredLess, class Allocator>
3412 struct ordered_map;
3413
3414 /*!
3415 @brief ordered JSON class
3416
3417 This type preserves the insertion order of object keys.
3418
3419 @since version 3.9.0
3420 */
3422
3423} // namespace nlohmann
3424
3425#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3426
3427
3428namespace nlohmann
3429{
3430 /*!
3431 @brief detail namespace with internal helper functions
3432
3433 This namespace collects functions that should not be exposed,
3434 implementations of some @ref basic_json methods, and meta-programming helpers.
3435
3436 @since version 2.1.0
3437 */
3438 namespace detail
3439 {
3440 /////////////
3441 // helpers //
3442 /////////////
3443
3444 // Note to maintainers:
3445 //
3446 // Every trait in this file expects a non CV-qualified type.
3447 // The only exceptions are in the 'aliases for detected' section
3448 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3449 //
3450 // In this case, T has to be properly CV-qualified to constraint the function arguments
3451 // (e.g. to_json(BasicJsonType&, const T&))
3452
3453 template<typename> struct is_basic_json : std::false_type {};
3454
3457
3458 //////////////////////
3459 // json_ref helpers //
3460 //////////////////////
3461
3462 template<typename>
3463 class json_ref;
3464
3465 template<typename>
3466 struct is_json_ref : std::false_type {};
3467
3468 template<typename T>
3469 struct is_json_ref<json_ref<T>> : std::true_type {};
3470
3471 //////////////////////////
3472 // aliases for detected //
3473 //////////////////////////
3474
3475 template<typename T>
3476 using mapped_type_t = typename T::mapped_type;
3477
3478 template<typename T>
3479 using key_type_t = typename T::key_type;
3480
3481 template<typename T>
3482 using value_type_t = typename T::value_type;
3483
3484 template<typename T>
3485 using difference_type_t = typename T::difference_type;
3486
3487 template<typename T>
3488 using pointer_t = typename T::pointer;
3489
3490 template<typename T>
3491 using reference_t = typename T::reference;
3492
3493 template<typename T>
3494 using iterator_category_t = typename T::iterator_category;
3495
3496 template<typename T>
3497 using iterator_t = typename T::iterator;
3498
3499 template<typename T, typename... Args>
3500 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3501
3502 template<typename T, typename... Args>
3503 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3504
3505 template<typename T, typename U>
3506 using get_template_function = decltype(std::declval<T>().template get<U>());
3507
3508 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3509 template<typename BasicJsonType, typename T, typename = void>
3510 struct has_from_json : std::false_type {};
3511
3512 // trait checking if j.get<T> is valid
3513 // use this trait instead of std::is_constructible or std::is_convertible,
3514 // both rely on, or make use of implicit conversions, and thus fail when T
3515 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3516 template <typename BasicJsonType, typename T>
3518 {
3519 static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3520 };
3521
3522 template<typename BasicJsonType, typename T>
3524 {
3525 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3526
3527 static constexpr bool value =
3529 const BasicJsonType&, T&>::value;
3530 };
3531
3532 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3533 // this overload is used for non-default-constructible user-defined-types
3534 template<typename BasicJsonType, typename T, typename = void>
3535 struct has_non_default_from_json : std::false_type {};
3536
3537 template<typename BasicJsonType, typename T>
3539 {
3540 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3541
3542 static constexpr bool value =
3544 const BasicJsonType&>::value;
3545 };
3546
3547 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3548 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3549 template<typename BasicJsonType, typename T, typename = void>
3550 struct has_to_json : std::false_type {};
3551
3552 template<typename BasicJsonType, typename T>
3554 {
3555 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3556
3557 static constexpr bool value =
3559 T>::value;
3560 };
3561
3562
3563 ///////////////////
3564 // is_ functions //
3565 ///////////////////
3566
3567 // https://en.cppreference.com/w/cpp/types/conjunction
3568 template<class...> struct conjunction : std::true_type { };
3569 template<class B1> struct conjunction<B1> : B1 { };
3570 template<class B1, class... Bn>
3571 struct conjunction<B1, Bn...>
3572 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3573
3574 // https://en.cppreference.com/w/cpp/types/negation
3575 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3576
3577 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3578 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3579 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3580 template <typename T>
3581 struct is_default_constructible : std::is_default_constructible<T> {};
3582
3583 template <typename T1, typename T2>
3584 struct is_default_constructible<std::pair<T1, T2>>
3586
3587 template <typename T1, typename T2>
3588 struct is_default_constructible<const std::pair<T1, T2>>
3590
3591 template <typename... Ts>
3592 struct is_default_constructible<std::tuple<Ts...>>
3594
3595 template <typename... Ts>
3596 struct is_default_constructible<const std::tuple<Ts...>>
3598
3599
3600 template <typename T, typename... Args>
3601 struct is_constructible : std::is_constructible<T, Args...> {};
3602
3603 template <typename T1, typename T2>
3604 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3605
3606 template <typename T1, typename T2>
3607 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3608
3609 template <typename... Ts>
3610 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3611
3612 template <typename... Ts>
3613 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3614
3615
3616 template<typename T, typename = void>
3617 struct is_iterator_traits : std::false_type {};
3618
3619 template<typename T>
3621 {
3622 private:
3624
3625 public:
3626 static constexpr auto value =
3632 };
3633
3634 // The following implementation of is_complete_type is taken from
3635 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3636 // and is written by Xiang Fan who agreed to using it in this library.
3637
3638 template<typename T, typename = void>
3639 struct is_complete_type : std::false_type {};
3640
3641 template<typename T>
3642 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3643
3644 template<typename BasicJsonType, typename CompatibleObjectType,
3645 typename = void>
3646 struct is_compatible_object_type_impl : std::false_type {};
3647
3648 template<typename BasicJsonType, typename CompatibleObjectType>
3653 {
3655
3656 // macOS's is_constructible does not play well with nonesuch...
3657 static constexpr bool value =
3659 typename CompatibleObjectType::key_type>::value &&
3662 };
3663
3664 template<typename BasicJsonType, typename CompatibleObjectType>
3667
3668 template<typename BasicJsonType, typename ConstructibleObjectType,
3669 typename = void>
3671
3672 template<typename BasicJsonType, typename ConstructibleObjectType>
3677 {
3679
3680 static constexpr bool value =
3685 typename object_t::key_type>::value &&
3686 std::is_same <
3687 typename object_t::mapped_type,
3688 typename ConstructibleObjectType::mapped_type >::value)) ||
3694 };
3695
3696 template<typename BasicJsonType, typename ConstructibleObjectType>
3700
3701 template<typename BasicJsonType, typename CompatibleStringType,
3702 typename = void>
3703 struct is_compatible_string_type_impl : std::false_type {};
3704
3705 template<typename BasicJsonType, typename CompatibleStringType>
3710 {
3711 static constexpr auto value =
3713 };
3714
3715 template<typename BasicJsonType, typename ConstructibleStringType>
3718
3719 template<typename BasicJsonType, typename ConstructibleStringType,
3720 typename = void>
3722
3723 template<typename BasicJsonType, typename ConstructibleStringType>
3728 {
3729 static constexpr auto value =
3731 typename BasicJsonType::string_t>::value;
3732 };
3733
3734 template<typename BasicJsonType, typename ConstructibleStringType>
3737
3738 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3739 struct is_compatible_array_type_impl : std::false_type {};
3740
3741 template<typename BasicJsonType, typename CompatibleArrayType>
3746 // This is needed because json_reverse_iterator has a ::iterator type...
3747 // Therefore it is detected as a CompatibleArrayType.
3748 // The real fix would be to have an Iterable concept.
3751 {
3752 static constexpr bool value =
3755 };
3756
3757 template<typename BasicJsonType, typename CompatibleArrayType>
3760
3761 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3762 struct is_constructible_array_type_impl : std::false_type {};
3763
3764 template<typename BasicJsonType, typename ConstructibleArrayType>
3768 typename BasicJsonType::value_type>::value >>
3769 : std::true_type {};
3770
3771 template<typename BasicJsonType, typename ConstructibleArrayType>
3775 typename BasicJsonType::value_type>::value&&
3783 {
3784 static constexpr bool value =
3785 // This is needed because json_reverse_iterator has a ::iterator type,
3786 // furthermore, std::back_insert_iterator (and other iterators) have a
3787 // base class `iterator`... Therefore it is detected as a
3788 // ConstructibleArrayType. The real fix would be to have an Iterable
3789 // concept.
3791
3793 typename BasicJsonType::array_t::value_type>::value ||
3798 };
3799
3800 template<typename BasicJsonType, typename ConstructibleArrayType>
3803
3804 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3805 typename = void>
3806 struct is_compatible_integer_type_impl : std::false_type {};
3807
3808 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3814 {
3815 // is there an assert somewhere on overflows?
3818
3819 static constexpr auto value =
3824 };
3825
3826 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3830
3831 template<typename BasicJsonType, typename CompatibleType, typename = void>
3832 struct is_compatible_type_impl : std::false_type {};
3833
3834 template<typename BasicJsonType, typename CompatibleType>
3838 {
3839 static constexpr bool value =
3841 };
3842
3843 template<typename BasicJsonType, typename CompatibleType>
3846
3847 template<typename T1, typename T2>
3848 struct is_constructible_tuple : std::false_type {};
3849
3850 template<typename T1, typename... Args>
3851 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3852
3853 // a naive helper to check if a type is an ordered_map (exploits the fact that
3854 // ordered_map inherits capacity() from std::vector)
3855 template <typename T>
3857 {
3858 using one = char;
3859
3860 struct two
3861 {
3862 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3863 };
3864
3865 template <typename C> static one test(decltype(&C::capacity));
3866 template <typename C> static two test(...);
3867
3868 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3869 };
3870
3871 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3872 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3873 T conditional_static_cast(U value)
3874 {
3875 return static_cast<T>(value);
3876 }
3877
3878 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3879 T conditional_static_cast(U value)
3880 {
3881 return value;
3882 }
3883
3884 } // namespace detail
3885} // namespace nlohmann
3886
3887// #include <nlohmann/detail/value_t.hpp>
3888
3889
3890namespace nlohmann
3891{
3892 namespace detail
3893 {
3894 template<typename BasicJsonType>
3895 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3896 {
3898 {
3899 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
3900 }
3901 n = nullptr;
3902 }
3903
3904 // overloads for basic_json template parameters
3905 template < typename BasicJsonType, typename ArithmeticType,
3906 enable_if_t < std::is_arithmetic<ArithmeticType>::value &&
3907 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3908 int > = 0 >
3909 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3910 {
3911 switch (static_cast<value_t>(j))
3912 {
3914 {
3915 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3916 break;
3917 }
3918 case value_t::number_integer:
3919 {
3920 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3921 break;
3922 }
3923 case value_t::number_float:
3924 {
3925 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3926 break;
3927 }
3928
3929 case value_t::null:
3930 case value_t::object:
3931 case value_t::array:
3932 case value_t::string:
3933 case value_t::boolean:
3934 case value_t::binary:
3935 case value_t::discarded:
3936 default:
3937 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
3938 }
3939 }
3940
3941 template<typename BasicJsonType>
3942 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3943 {
3945 {
3946 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
3947 }
3948 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3949 }
3950
3951 template<typename BasicJsonType>
3952 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3953 {
3955 {
3956 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3957 }
3958 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3959 }
3960
3961 template <
3962 typename BasicJsonType, typename ConstructibleStringType,
3963 enable_if_t <
3964 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value &&
3965 !std::is_same<typename BasicJsonType::string_t,
3966 ConstructibleStringType>::value,
3967 int > = 0 >
3968 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3969 {
3971 {
3972 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3973 }
3974
3975 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3976 }
3977
3978 template<typename BasicJsonType>
3979 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3980 {
3982 }
3983
3984 template<typename BasicJsonType>
3985 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3986 {
3988 }
3989
3990 template<typename BasicJsonType>
3991 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3992 {
3994 }
3995
3996 template<typename BasicJsonType, typename EnumType,
3997 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3998 void from_json(const BasicJsonType& j, EnumType& e)
3999 {
4000 typename std::underlying_type<EnumType>::type val;
4002 e = static_cast<EnumType>(val);
4003 }
4004
4005 // forward_list doesn't have an insert method
4006 template<typename BasicJsonType, typename T, typename Allocator,
4007 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4008 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4009 {
4011 {
4012 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4013 }
4014 l.clear();
4015 std::transform(j.rbegin(), j.rend(),
4016 std::front_inserter(l), [](const BasicJsonType& i)
4017 {
4018 return i.template get<T>();
4019 });
4020 }
4021
4022 // valarray doesn't have an insert method
4023 template<typename BasicJsonType, typename T,
4024 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4025 void from_json(const BasicJsonType& j, std::valarray<T>& l)
4026 {
4028 {
4029 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4030 }
4031 l.resize(j.size());
4032 std::transform(j.begin(), j.end(), std::begin(l),
4033 [](const BasicJsonType& elem)
4034 {
4035 return elem.template get<T>();
4036 });
4037 }
4038
4039 template<typename BasicJsonType, typename T, std::size_t N>
4040 auto from_json(const BasicJsonType& j, T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4041 -> decltype(j.template get<T>(), void())
4042 {
4043 for (std::size_t i = 0; i < N; ++i)
4044 {
4045 arr[i] = j.at(i).template get<T>();
4046 }
4047 }
4048
4049 template<typename BasicJsonType>
4050 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4051 {
4052 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4053 }
4054
4055 template<typename BasicJsonType, typename T, std::size_t N>
4056 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4057 priority_tag<2> /*unused*/)
4058 -> decltype(j.template get<T>(), void())
4059 {
4060 for (std::size_t i = 0; i < N; ++i)
4061 {
4062 arr[i] = j.at(i).template get<T>();
4063 }
4064 }
4065
4066 template<typename BasicJsonType, typename ConstructibleArrayType,
4067 enable_if_t<
4068 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4069 int> = 0>
4070 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4071 -> decltype(
4072 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4073 j.template get<typename ConstructibleArrayType::value_type>(),
4074 void())
4075 {
4076 using std::end;
4077
4079 ret.reserve(j.size());
4080 std::transform(j.begin(), j.end(),
4081 std::inserter(ret, end(ret)), [](const BasicJsonType& i)
4082 {
4083 // get<BasicJsonType>() returns *this, this won't call a from_json
4084 // method when value_type is BasicJsonType
4085 return i.template get<typename ConstructibleArrayType::value_type>();
4086 });
4087 arr = std::move(ret);
4088 }
4089
4090 template<typename BasicJsonType, typename ConstructibleArrayType,
4091 enable_if_t<
4092 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4093 int> = 0>
4094 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4095 priority_tag<0> /*unused*/)
4096 {
4097 using std::end;
4098
4100 std::transform(
4101 j.begin(), j.end(), std::inserter(ret, end(ret)),
4102 [](const BasicJsonType& i)
4103 {
4104 // get<BasicJsonType>() returns *this, this won't call a from_json
4105 // method when value_type is BasicJsonType
4106 return i.template get<typename ConstructibleArrayType::value_type>();
4107 });
4108 arr = std::move(ret);
4109 }
4110
4111 template < typename BasicJsonType, typename ConstructibleArrayType,
4112 enable_if_t <
4113 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value &&
4114 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value &&
4115 !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value &&
4116 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value &&
4117 !is_basic_json<ConstructibleArrayType>::value,
4118 int > = 0 >
4120 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4121 j.template get<typename ConstructibleArrayType::value_type>(),
4122 void())
4123 {
4125 {
4126 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4127 }
4128
4130 }
4131
4132 template < typename BasicJsonType, typename T, std::size_t... Idx >
4133 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4134 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4135 {
4136 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4137 }
4138
4139 template < typename BasicJsonType, typename T, std::size_t N >
4140 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4142 {
4144 {
4145 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4146 }
4147
4149 }
4150
4151 template<typename BasicJsonType>
4152 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4153 {
4155 {
4156 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
4157 }
4158
4159 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4160 }
4161
4162 template<typename BasicJsonType, typename ConstructibleObjectType,
4163 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4164 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4165 {
4167 {
4168 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
4169 }
4170
4172 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4174 std::transform(
4176 std::inserter(ret, ret.begin()),
4177 [](typename BasicJsonType::object_t::value_type const& p)
4178 {
4179 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4180 });
4181 obj = std::move(ret);
4182 }
4183
4184 // overload for arithmetic types, not chosen for basic_json template arguments
4185 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4186 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4187 // an arithmetic type?
4188 template < typename BasicJsonType, typename ArithmeticType,
4189 enable_if_t <
4190 std::is_arithmetic<ArithmeticType>::value &&
4191 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value &&
4192 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value &&
4193 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value &&
4194 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4195 int > = 0 >
4196 void from_json(const BasicJsonType& j, ArithmeticType& val)
4197 {
4198 switch (static_cast<value_t>(j))
4199 {
4201 {
4202 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4203 break;
4204 }
4205 case value_t::number_integer:
4206 {
4207 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4208 break;
4209 }
4210 case value_t::number_float:
4211 {
4212 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4213 break;
4214 }
4215 case value_t::boolean:
4216 {
4217 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4218 break;
4219 }
4220
4221 case value_t::null:
4222 case value_t::object:
4223 case value_t::array:
4224 case value_t::string:
4225 case value_t::binary:
4226 case value_t::discarded:
4227 default:
4228 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4229 }
4230 }
4231
4232 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4233 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4234 {
4235 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4236 }
4237
4238 template < typename BasicJsonType, class A1, class A2 >
4239 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4240 {
4241 return { std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4242 std::forward<BasicJsonType>(j).at(1).template get<A2>() };
4243 }
4244
4245 template<typename BasicJsonType, typename A1, typename A2>
4246 void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4247 {
4249 }
4250
4251 template<typename BasicJsonType, typename... Args>
4252 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4253 {
4255 }
4256
4257 template<typename BasicJsonType, typename... Args>
4258 void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4259 {
4261 }
4262
4263 template<typename BasicJsonType, typename TupleRelated>
4264 auto from_json(BasicJsonType&& j, TupleRelated&& t)
4266 {
4268 {
4269 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4270 }
4271
4273 }
4274
4275 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4276 typename = enable_if_t < !std::is_constructible <
4277 typename BasicJsonType::string_t, Key >::value >>
4278 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4279 {
4281 {
4282 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4283 }
4284 m.clear();
4285 for (const auto& p : j)
4286 {
4288 {
4289 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4290 }
4291 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4292 }
4293 }
4294
4295 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4296 typename = enable_if_t < !std::is_constructible <
4297 typename BasicJsonType::string_t, Key >::value >>
4298 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4299 {
4301 {
4302 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4303 }
4304 m.clear();
4305 for (const auto& p : j)
4306 {
4308 {
4309 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4310 }
4311 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4312 }
4313 }
4314
4315 struct from_json_fn
4316 {
4317 template<typename BasicJsonType, typename T>
4318 auto operator()(const BasicJsonType& j, T&& val) const
4319 noexcept(noexcept(from_json(j, std::forward<T>(val))))
4320 -> decltype(from_json(j, std::forward<T>(val)))
4321 {
4322 return from_json(j, std::forward<T>(val));
4323 }
4324 };
4325 } // namespace detail
4326
4327 /// namespace to hold default `from_json` function
4328 /// to see why this is required:
4329 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
4330 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4331 {
4332 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4333 } // namespace
4334} // namespace nlohmann
4335
4336// #include <nlohmann/detail/conversions/to_json.hpp>
4337
4338
4339#include <algorithm> // copy
4340#include <iterator> // begin, end
4341#include <string> // string
4342#include <tuple> // tuple, get
4343#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4344#include <utility> // move, forward, declval, pair
4345#include <valarray> // valarray
4346#include <vector> // vector
4347
4348// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4349
4350
4351#include <cstddef> // size_t
4352#include <iterator> // input_iterator_tag
4353#include <string> // string, to_string
4354#include <tuple> // tuple_size, get, tuple_element
4355#include <utility> // move
4356
4357// #include <nlohmann/detail/meta/type_traits.hpp>
4358
4359// #include <nlohmann/detail/value_t.hpp>
4360
4361
4362namespace nlohmann
4363{
4364 namespace detail
4365 {
4366 template<typename string_type>
4367 void int_to_string(string_type& target, std::size_t value)
4368 {
4369 // For ADL
4370 using std::to_string;
4372 }
4373 template<typename IteratorType> class iteration_proxy_value
4374 {
4375 public:
4376 using difference_type = std::ptrdiff_t;
4377 using value_type = iteration_proxy_value;
4378 using pointer = value_type*;
4379 using reference = value_type&;
4380 using iterator_category = std::input_iterator_tag;
4381 using string_type = typename std::remove_cv< typename std::remove_reference<decltype(std::declval<IteratorType>().key()) >::type >::type;
4382
4383 private:
4384 /// the iterator
4385 IteratorType anchor;
4386 /// an index for arrays (used to create key names)
4387 std::size_t array_index = 0;
4388 /// last stringified array index
4389 mutable std::size_t array_index_last = 0;
4390 /// a string representation of the array index
4391 mutable string_type array_index_str = "0";
4392 /// an empty string (to return a reference for primitive values)
4393 const string_type empty_str{};
4394
4395 public:
4396 explicit iteration_proxy_value(IteratorType it) noexcept
4397 : anchor(std::move(it))
4398 {}
4399
4400 /// dereference operator (needed for range-based for)
4402 {
4403 return *this;
4404 }
4405
4406 /// increment operator (needed for range-based for)
4408 {
4409 ++anchor;
4410 ++array_index;
4411
4412 return *this;
4413 }
4414
4415 /// equality operator (needed for InputIterator)
4416 bool operator==(const iteration_proxy_value& o) const
4417 {
4418 return anchor == o.anchor;
4419 }
4420
4421 /// inequality operator (needed for range-based for)
4422 bool operator!=(const iteration_proxy_value& o) const
4423 {
4424 return anchor != o.anchor;
4425 }
4426
4427 /// return key of the iterator
4428 const string_type& key() const
4429 {
4430 JSON_ASSERT(anchor.m_object != nullptr);
4431
4432 switch (anchor.m_object->type())
4433 {
4434 // use integer array index as key
4435 case value_t::array:
4436 {
4438 {
4441 }
4442 return array_index_str;
4443 }
4444
4445 // use key from the object
4446 case value_t::object:
4447 return anchor.key();
4448
4449 // use an empty key for all primitive types
4450 case value_t::null:
4451 case value_t::string:
4452 case value_t::boolean:
4453 case value_t::number_integer:
4455 case value_t::number_float:
4456 case value_t::binary:
4457 case value_t::discarded:
4458 default:
4459 return empty_str;
4460 }
4461 }
4462
4463 /// return value of the iterator
4464 typename IteratorType::reference value() const
4465 {
4466 return anchor.value();
4467 }
4468 };
4469
4470 /// proxy class for the items() function
4471 template<typename IteratorType> class iteration_proxy
4472 {
4473 private:
4474 /// the container to iterate
4475 typename IteratorType::reference container;
4476
4477 public:
4478 /// construct iteration proxy from a container
4479 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4480 : container(cont) {}
4481
4482 /// return iterator begin (needed for range-based for)
4483 iteration_proxy_value<IteratorType> begin() noexcept
4484 {
4486 }
4487
4488 /// return iterator end (needed for range-based for)
4489 iteration_proxy_value<IteratorType> end() noexcept
4490 {
4492 }
4493 };
4494 // Structured Bindings Support
4495 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4496 // And see https://github.com/nlohmann/json/pull/1391
4497 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4498 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
4499 {
4500 return i.key();
4501 }
4502 // Structured Bindings Support
4503 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4504 // And see https://github.com/nlohmann/json/pull/1391
4505 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4506 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4507 {
4508 return i.value();
4509 }
4510 } // namespace detail
4511} // namespace nlohmann
4512
4513// The Addition to the STD Namespace is required to add
4514// Structured Bindings Support to the iteration_proxy_value class
4515// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4516// And see https://github.com/nlohmann/json/pull/1391
4517namespace std
4518{
4519#if defined(__clang__)
4520 // Fix: https://github.com/nlohmann/json/issues/1401
4521#pragma clang diagnostic push
4522#pragma clang diagnostic ignored "-Wmismatched-tags"
4523#endif
4524 template<typename IteratorType>
4525 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4526 : public std::integral_constant<std::size_t, 2> {};
4527
4528 template<std::size_t N, typename IteratorType>
4529 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4530 {
4531 public:
4532 using type = decltype(
4533 get<N>(std::declval <
4534 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
4535 };
4536#if defined(__clang__)
4537#pragma clang diagnostic pop
4538#endif
4539} // namespace std
4540
4541// #include <nlohmann/detail/meta/cpp_future.hpp>
4542
4543// #include <nlohmann/detail/meta/type_traits.hpp>
4544
4545// #include <nlohmann/detail/value_t.hpp>
4546
4547
4548namespace nlohmann
4549{
4550 namespace detail
4551 {
4552 //////////////////
4553 // constructors //
4554 //////////////////
4555
4556 /*
4557 * Note all external_constructor<>::construct functions need to call
4558 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4559 * allocated value (e.g., a string). See bug issue
4560 * https://github.com/nlohmann/json/issues/2865 for more information.
4561 */
4562
4564
4565 template<>
4567 {
4568 template<typename BasicJsonType>
4569 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4570 {
4573 j.m_value = b;
4575 }
4576 };
4577
4578 template<>
4580 {
4581 template<typename BasicJsonType>
4582 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4583 {
4586 j.m_value = s;
4588 }
4589
4590 template<typename BasicJsonType>
4591 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4592 {
4595 j.m_value = std::move(s);
4597 }
4598
4599 template < typename BasicJsonType, typename CompatibleStringType,
4600 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4601 int > = 0 >
4602 static void construct(BasicJsonType& j, const CompatibleStringType& str)
4603 {
4606 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4608 }
4609 };
4610
4611 template<>
4613 {
4614 template<typename BasicJsonType>
4615 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4616 {
4619 j.m_value = typename BasicJsonType::binary_t(b);
4621 }
4622
4623 template<typename BasicJsonType>
4624 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4625 {
4628 j.m_value = typename BasicJsonType::binary_t(std::move(b));
4630 }
4631 };
4632
4633 template<>
4635 {
4636 template<typename BasicJsonType>
4637 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4638 {
4641 j.m_value = val;
4643 }
4644 };
4645
4646 template<>
4648 {
4649 template<typename BasicJsonType>
4650 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4651 {
4654 j.m_value = val;
4656 }
4657 };
4658
4659 template<>
4661 {
4662 template<typename BasicJsonType>
4663 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4664 {
4667 j.m_value = val;
4669 }
4670 };
4671
4672 template<>
4674 {
4675 template<typename BasicJsonType>
4676 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4677 {
4679 j.m_type = value_t::array;
4680 j.m_value = arr;
4681 j.set_parents();
4683 }
4684
4685 template<typename BasicJsonType>
4686 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4687 {
4689 j.m_type = value_t::array;
4690 j.m_value = std::move(arr);
4691 j.set_parents();
4693 }
4694
4695 template < typename BasicJsonType, typename CompatibleArrayType,
4696 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4697 int > = 0 >
4698 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4699 {
4700 using std::begin;
4701 using std::end;
4702
4704 j.m_type = value_t::array;
4705 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4706 j.set_parents();
4708 }
4709
4710 template<typename BasicJsonType>
4711 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4712 {
4714 j.m_type = value_t::array;
4717 for (const bool x : arr)
4718 {
4721 }
4723 }
4724
4725 template<typename BasicJsonType, typename T,
4726 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4727 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4728 {
4730 j.m_type = value_t::array;
4733 if (arr.size() > 0)
4734 {
4736 }
4737 j.set_parents();
4739 }
4740 };
4741
4742 template<>
4744 {
4745 template<typename BasicJsonType>
4746 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4747 {
4750 j.m_value = obj;
4751 j.set_parents();
4753 }
4754
4755 template<typename BasicJsonType>
4756 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4757 {
4760 j.m_value = std::move(obj);
4761 j.set_parents();
4763 }
4764
4765 template < typename BasicJsonType, typename CompatibleObjectType,
4766 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4767 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4768 {
4769 using std::begin;
4770 using std::end;
4771
4774 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4775 j.set_parents();
4777 }
4778 };
4779
4780 /////////////
4781 // to_json //
4782 /////////////
4783
4784 template<typename BasicJsonType, typename T,
4785 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4786 void to_json(BasicJsonType& j, T b) noexcept
4787 {
4789 }
4790
4791 template<typename BasicJsonType, typename CompatibleString,
4792 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4793 void to_json(BasicJsonType& j, const CompatibleString& s)
4794 {
4796 }
4797
4798 template<typename BasicJsonType>
4799 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4800 {
4802 }
4803
4804 template<typename BasicJsonType, typename FloatType,
4805 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4806 void to_json(BasicJsonType& j, FloatType val) noexcept
4807 {
4809 }
4810
4811 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4812 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4813 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4814 {
4816 }
4817
4818 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4819 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4820 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4821 {
4823 }
4824
4825 template<typename BasicJsonType, typename EnumType,
4826 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4827 void to_json(BasicJsonType& j, EnumType e) noexcept
4828 {
4829 using underlying_type = typename std::underlying_type<EnumType>::type;
4831 }
4832
4833 template<typename BasicJsonType>
4834 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4835 {
4837 }
4838
4839 template < typename BasicJsonType, typename CompatibleArrayType,
4840 enable_if_t < is_compatible_array_type<BasicJsonType,
4841 CompatibleArrayType>::value &&
4842 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value &&
4843 !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value &&
4844 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value &&
4845 !is_basic_json<CompatibleArrayType>::value,
4846 int > = 0 >
4847 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4848 {
4850 }
4851
4852 template<typename BasicJsonType>
4853 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4854 {
4856 }
4857
4858 template<typename BasicJsonType, typename T,
4859 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4860 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4861 {
4863 }
4864
4865 template<typename BasicJsonType>
4866 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4867 {
4869 }
4870
4871 template < typename BasicJsonType, typename CompatibleObjectType,
4872 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value && !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4873 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4874 {
4876 }
4877
4878 template<typename BasicJsonType>
4879 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4880 {
4882 }
4883
4884 template <
4885 typename BasicJsonType, typename T, std::size_t N,
4886 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4887 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4888 int > = 0 >
4889 void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4890 {
4892 }
4893
4894 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4895 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4896 {
4897 j = { p.first, p.second };
4898 }
4899
4900 // for https://github.com/nlohmann/json/pull/1134
4901 template<typename BasicJsonType, typename T,
4902 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4903 void to_json(BasicJsonType& j, const T& b)
4904 {
4905 j = { {b.key(), b.value()} };
4906 }
4907
4908 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4909 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4910 {
4911 j = { std::get<Idx>(t)... };
4912 }
4913
4914 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4915 void to_json(BasicJsonType& j, const T& t)
4916 {
4918 }
4919
4920 struct to_json_fn
4921 {
4922 template<typename BasicJsonType, typename T>
4923 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4924 -> decltype(to_json(j, std::forward<T>(val)), void())
4925 {
4926 return to_json(j, std::forward<T>(val));
4927 }
4928 };
4929 } // namespace detail
4930
4931 /// namespace to hold default `to_json` function
4932 /// to see why this is required:
4933 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
4934 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4935 {
4936 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4937 } // namespace
4938} // namespace nlohmann
4939
4940// #include <nlohmann/detail/meta/identity_tag.hpp>
4941
4942// #include <nlohmann/detail/meta/type_traits.hpp>
4943
4944
4945namespace nlohmann
4946{
4947
4948 template<typename ValueType, typename>
4949 struct adl_serializer
4950 {
4951 /*!
4952 @brief convert a JSON value to any value type
4953
4954 This function is usually called by the `get()` function of the
4955 @ref basic_json class (either explicit or via conversion operators).
4956
4957 @note This function is chosen for default-constructible value types.
4958
4959 @param[in] j JSON value to read from
4960 @param[in,out] val value to write to
4961 */
4962 template<typename BasicJsonType, typename TargetType = ValueType>
4963 static auto from_json(BasicJsonType&& j, TargetType& val) noexcept(
4964 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4965 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4966 {
4967 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4968 }
4969
4970 /*!
4971 @brief convert a JSON value to any value type
4972
4973 This function is usually called by the `get()` function of the
4974 @ref basic_json class (either explicit or via conversion operators).
4975
4976 @note This function is chosen for value types which are not default-constructible.
4977
4978 @param[in] j JSON value to read from
4979
4980 @return copy of the JSON value, converted to @a ValueType
4981 */
4982 template<typename BasicJsonType, typename TargetType = ValueType>
4983 static auto from_json(BasicJsonType&& j) noexcept(
4984 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
4985 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
4986 {
4987 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
4988 }
4989
4990 /*!
4991 @brief convert any value type to a JSON value
4992
4993 This function is usually called by the constructors of the @ref basic_json
4994 class.
4995
4996 @param[in,out] j JSON value to write to
4997 @param[in] val value to read from
4998 */
4999 template<typename BasicJsonType, typename TargetType = ValueType>
5000 static auto to_json(BasicJsonType& j, TargetType&& val) noexcept(
5001 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5002 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5003 {
5004 ::nlohmann::to_json(j, std::forward<TargetType>(val));
5005 }
5006 };
5007} // namespace nlohmann
5008
5009// #include <nlohmann/byte_container_with_subtype.hpp>
5010
5011
5012#include <cstdint> // uint8_t, uint64_t
5013#include <tuple> // tie
5014#include <utility> // move
5015
5016namespace nlohmann
5017{
5018
5019 /*!
5020 @brief an internal type for a backed binary type
5021
5022 This type extends the template parameter @a BinaryType provided to `basic_json`
5023 with a subtype used by BSON and MessagePack. This type exists so that the user
5024 does not have to specify a type themselves with a specific naming scheme in
5025 order to override the binary type.
5026
5027 @tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by
5028 default)
5029
5030 @since version 3.8.0; changed type of subtypes to std::uint64_t in 3.10.0.
5031 */
5032 template<typename BinaryType>
5033 class byte_container_with_subtype : public BinaryType
5034 {
5035 public:
5036 /// the type of the underlying container
5037 using container_type = BinaryType;
5038 /// the type of the subtype
5039 using subtype_type = std::uint64_t;
5040
5042 : container_type()
5043 {}
5044
5045 byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
5046 : container_type(b)
5047 {}
5048
5049 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5051 {}
5052
5053 byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
5054 : container_type(b)
5056 , m_has_subtype(true)
5057 {}
5058
5059 byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5062 , m_has_subtype(true)
5063 {}
5064
5065 bool operator==(const byte_container_with_subtype& rhs) const
5066 {
5067 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5068 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5069 }
5070
5071 bool operator!=(const byte_container_with_subtype& rhs) const
5072 {
5073 return !(rhs == *this);
5074 }
5075
5076 /*!
5077 @brief sets the binary subtype
5078
5079 Sets the binary subtype of the value, also flags a binary JSON value as
5080 having a subtype, which has implications for serialization.
5081
5082 @complexity Constant.
5083
5084 @exceptionsafety No-throw guarantee: this member function never throws
5085 exceptions.
5086
5087 @sa see @ref subtype() -- return the binary subtype
5088 @sa see @ref clear_subtype() -- clears the binary subtype
5089 @sa see @ref has_subtype() -- returns whether or not the binary value has a
5090 subtype
5091
5092 @since version 3.8.0
5093 */
5094 void set_subtype(subtype_type subtype_) noexcept
5095 {
5097 m_has_subtype = true;
5098 }
5099
5100 /*!
5101 @brief return the binary subtype
5102
5103 Returns the numerical subtype of the value if it has a subtype. If it does
5104 not have a subtype, this function will return subtype_type(-1) as a sentinel
5105 value.
5106
5107 @return the numerical subtype of the binary value
5108
5109 @complexity Constant.
5110
5111 @exceptionsafety No-throw guarantee: this member function never throws
5112 exceptions.
5113
5114 @sa see @ref set_subtype() -- sets the binary subtype
5115 @sa see @ref clear_subtype() -- clears the binary subtype
5116 @sa see @ref has_subtype() -- returns whether or not the binary value has a
5117 subtype
5118
5119 @since version 3.8.0; fixed return value to properly return
5120 subtype_type(-1) as documented in version 3.10.0
5121 */
5122 constexpr subtype_type subtype() const noexcept
5123 {
5124 return m_has_subtype ? m_subtype : subtype_type(-1);
5125 }
5126
5127 /*!
5128 @brief return whether the value has a subtype
5129
5130 @return whether the value has a subtype
5131
5132 @complexity Constant.
5133
5134 @exceptionsafety No-throw guarantee: this member function never throws
5135 exceptions.
5136
5137 @sa see @ref subtype() -- return the binary subtype
5138 @sa see @ref set_subtype() -- sets the binary subtype
5139 @sa see @ref clear_subtype() -- clears the binary subtype
5140
5141 @since version 3.8.0
5142 */
5143 constexpr bool has_subtype() const noexcept
5144 {
5145 return m_has_subtype;
5146 }
5147
5148 /*!
5149 @brief clears the binary subtype
5150
5151 Clears the binary subtype and flags the value as not having a subtype, which
5152 has implications for serialization; for instance MessagePack will prefer the
5153 bin family over the ext family.
5154
5155 @complexity Constant.
5156
5157 @exceptionsafety No-throw guarantee: this member function never throws
5158 exceptions.
5159
5160 @sa see @ref subtype() -- return the binary subtype
5161 @sa see @ref set_subtype() -- sets the binary subtype
5162 @sa see @ref has_subtype() -- returns whether or not the binary value has a
5163 subtype
5164
5165 @since version 3.8.0
5166 */
5167 void clear_subtype() noexcept
5168 {
5169 m_subtype = 0;
5170 m_has_subtype = false;
5171 }
5172
5173 private:
5174 subtype_type m_subtype = 0;
5175 bool m_has_subtype = false;
5176 };
5177
5178} // namespace nlohmann
5179
5180// #include <nlohmann/detail/conversions/from_json.hpp>
5181
5182// #include <nlohmann/detail/conversions/to_json.hpp>
5183
5184// #include <nlohmann/detail/exceptions.hpp>
5185
5186// #include <nlohmann/detail/hash.hpp>
5187
5188
5189#include <cstdint> // uint8_t
5190#include <cstddef> // size_t
5191#include <functional> // hash
5192
5193// #include <nlohmann/detail/macro_scope.hpp>
5194
5195// #include <nlohmann/detail/value_t.hpp>
5196
5197
5198namespace nlohmann
5199{
5200 namespace detail
5201 {
5202
5203 // boost::hash_combine
5204 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5205 {
5206 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5207 return seed;
5208 }
5209
5210 /*!
5211 @brief hash a JSON value
5212
5213 The hash function tries to rely on std::hash where possible. Furthermore, the
5214 type of the JSON value is taken into account to have different hash values for
5215 null, 0, 0U, and false, etc.
5216
5217 @tparam BasicJsonType basic_json specialization
5218 @param j JSON value to hash
5219 @return hash value of j
5220 */
5221 template<typename BasicJsonType>
5222 std::size_t hash(const BasicJsonType& j)
5223 {
5224 using string_t = typename BasicJsonType::string_t;
5228
5229 const auto type = static_cast<std::size_t>(j.type());
5230 switch (j.type())
5231 {
5232 case BasicJsonType::value_t::null:
5234 {
5235 return combine(type, 0);
5236 }
5237
5239 {
5240 auto seed = combine(type, j.size());
5241 for (const auto& element : j.items())
5242 {
5243 const auto h = std::hash<string_t>{}(element.key());
5244 seed = combine(seed, h);
5246 }
5247 return seed;
5248 }
5249
5251 {
5252 auto seed = combine(type, j.size());
5253 for (const auto& element : j)
5254 {
5256 }
5257 return seed;
5258 }
5259
5261 {
5262 const auto h = std::hash<string_t>{}(j.template get_ref<const string_t&>());
5263 return combine(type, h);
5264 }
5265
5267 {
5268 const auto h = std::hash<bool>{}(j.template get<bool>());
5269 return combine(type, h);
5270 }
5271
5273 {
5274 const auto h = std::hash<number_integer_t>{}(j.template get<number_integer_t>());
5275 return combine(type, h);
5276 }
5277
5279 {
5280 const auto h = std::hash<number_unsigned_t>{}(j.template get<number_unsigned_t>());
5281 return combine(type, h);
5282 }
5283
5285 {
5286 const auto h = std::hash<number_float_t>{}(j.template get<number_float_t>());
5287 return combine(type, h);
5288 }
5289
5291 {
5292 auto seed = combine(type, j.get_binary().size());
5293 const auto h = std::hash<bool>{}(j.get_binary().has_subtype());
5294 seed = combine(seed, h);
5295 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5296 for (const auto byte : j.get_binary())
5297 {
5298 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5299 }
5300 return seed;
5301 }
5302
5303 default: // LCOV_EXCL_LINE
5304 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5305 return 0; // LCOV_EXCL_LINE
5306 }
5307 }
5308
5309 } // namespace detail
5310} // namespace nlohmann
5311
5312// #include <nlohmann/detail/input/binary_reader.hpp>
5313
5314
5315#include <algorithm> // generate_n
5316#include <array> // array
5317#include <cmath> // ldexp
5318#include <cstddef> // size_t
5319#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5320#include <cstdio> // snprintf
5321#include <cstring> // memcpy
5322#include <iterator> // back_inserter
5323#include <limits> // numeric_limits
5324#include <string> // char_traits, string
5325#include <utility> // make_pair, move
5326#include <vector> // vector
5327
5328// #include <nlohmann/detail/exceptions.hpp>
5329
5330// #include <nlohmann/detail/input/input_adapters.hpp>
5331
5332
5333#include <array> // array
5334#include <cstddef> // size_t
5335#include <cstring> // strlen
5336#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5337#include <memory> // shared_ptr, make_shared, addressof
5338#include <numeric> // accumulate
5339#include <string> // string, char_traits
5340#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5341#include <utility> // pair, declval
5342
5343#ifndef JSON_NO_IO
5344#include <cstdio> // FILE *
5345#include <istream> // istream
5346#endif // JSON_NO_IO
5347
5348// #include <nlohmann/detail/iterators/iterator_traits.hpp>
5349
5350// #include <nlohmann/detail/macro_scope.hpp>
5351
5352
5353namespace nlohmann
5354{
5355 namespace detail
5356 {
5357 /// the supported input formats
5359
5360 ////////////////////
5361 // input adapters //
5362 ////////////////////
5363
5364#ifndef JSON_NO_IO
5365/*!
5366Input adapter for stdio file access. This adapter read only 1 byte and do not use any
5367 buffer. This adapter is a very low level adapter.
5368*/
5370 {
5371 public:
5372 using char_type = char;
5373
5375 explicit file_input_adapter(std::FILE* f) noexcept
5376 : m_file(f)
5377 {}
5378
5379 // make class move-only
5385
5386 std::char_traits<char>::int_type get_character() noexcept
5387 {
5388 return std::fgetc(m_file);
5389 }
5390
5391 private:
5392 /// the file pointer to read from
5393 std::FILE* m_file;
5394 };
5395
5396
5397 /*!
5398 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
5399 beginning of input. Does not support changing the underlying std::streambuf
5400 in mid-input. Maintains underlying std::istream and std::streambuf to support
5401 subsequent use of standard std::istream operations to process any input
5402 characters following those used in parsing the JSON input. Clears the
5403 std::istream flags; any input errors (e.g., EOF) will be detected by the first
5404 subsequent call for input from the std::istream.
5405 */
5407 {
5408 public:
5409 using char_type = char;
5410
5412 {
5413 // clear stream flags; we use underlying streambuf I/O, do not
5414 // maintain ifstream flags, except eof
5415 if (is != nullptr)
5416 {
5417 is->clear(is->rdstate() & std::ios::eofbit);
5418 }
5419 }
5420
5421 explicit input_stream_adapter(std::istream& i)
5422 : is(&i), sb(i.rdbuf())
5423 {}
5424
5425 // delete because of pointer members
5429
5431 : is(rhs.is), sb(rhs.sb)
5432 {
5433 rhs.is = nullptr;
5434 rhs.sb = nullptr;
5435 }
5436
5437 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5438 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5439 // end up as the same value, eg. 0xFFFFFFFF.
5440 std::char_traits<char>::int_type get_character()
5441 {
5442 auto res = sb->sbumpc();
5443 // set eof manually, as we don't use the istream interface.
5444 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5445 {
5446 is->clear(is->rdstate() | std::ios::eofbit);
5447 }
5448 return res;
5449 }
5450
5451 private:
5452 /// the associated input stream
5453 std::istream* is = nullptr;
5454 std::streambuf* sb = nullptr;
5455 };
5456#endif // JSON_NO_IO
5457
5458 // General-purpose iterator-based adapter. It might not be as fast as
5459 // theoretically possible for some containers, but it is extremely versatile.
5460 template<typename IteratorType>
5462 {
5463 public:
5464 using char_type = typename std::iterator_traits<IteratorType>::value_type;
5465
5466 iterator_input_adapter(IteratorType first, IteratorType last)
5467 : current(std::move(first)), end(std::move(last))
5468 {}
5469
5470 typename std::char_traits<char_type>::int_type get_character()
5471 {
5473 {
5475 std::advance(current, 1);
5476 return result;
5477 }
5478
5479 return std::char_traits<char_type>::eof();
5480 }
5481
5482 private:
5483 IteratorType current;
5484 IteratorType end;
5485
5486 template<typename BaseInputAdapter, size_t T>
5488
5489 bool empty() const
5490 {
5491 return current == end;
5492 }
5493 };
5494
5495
5496 template<typename BaseInputAdapter, size_t T>
5498
5499 template<typename BaseInputAdapter>
5500 struct wide_string_input_helper<BaseInputAdapter, 4>
5501 {
5502 // UTF-32
5503 static void fill_buffer(BaseInputAdapter& input,
5504 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5505 size_t& utf8_bytes_index,
5506 size_t& utf8_bytes_filled)
5507 {
5508 utf8_bytes_index = 0;
5509
5511 {
5512 utf8_bytes[0] = std::char_traits<char>::eof();
5514 }
5515 else
5516 {
5517 // get the current character
5518 const auto wc = input.get_character();
5519
5520 // UTF-32 to UTF-8 encoding
5521 if (wc < 0x80)
5522 {
5523 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5525 }
5526 else if (wc <= 0x7FF)
5527 {
5528 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5529 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5531 }
5532 else if (wc <= 0xFFFF)
5533 {
5534 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5535 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5536 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5538 }
5539 else if (wc <= 0x10FFFF)
5540 {
5541 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5542 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5543 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5544 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5546 }
5547 else
5548 {
5549 // unknown character
5550 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5552 }
5553 }
5554 }
5555 };
5556
5557 template<typename BaseInputAdapter>
5558 struct wide_string_input_helper<BaseInputAdapter, 2>
5559 {
5560 // UTF-16
5561 static void fill_buffer(BaseInputAdapter& input,
5562 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5563 size_t& utf8_bytes_index,
5564 size_t& utf8_bytes_filled)
5565 {
5566 utf8_bytes_index = 0;
5567
5569 {
5570 utf8_bytes[0] = std::char_traits<char>::eof();
5572 }
5573 else
5574 {
5575 // get the current character
5576 const auto wc = input.get_character();
5577
5578 // UTF-16 to UTF-8 encoding
5579 if (wc < 0x80)
5580 {
5581 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5583 }
5584 else if (wc <= 0x7FF)
5585 {
5586 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5587 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5589 }
5590 else if (0xD800 > wc || wc >= 0xE000)
5591 {
5592 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5593 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5594 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5596 }
5597 else
5598 {
5600 {
5601 const auto wc2 = static_cast<unsigned int>(input.get_character());
5602 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5603 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5604 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5605 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5606 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5608 }
5609 else
5610 {
5611 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5613 }
5614 }
5615 }
5616 }
5617 };
5618
5619 // Wraps another input apdater to convert wide character types into individual bytes.
5620 template<typename BaseInputAdapter, typename WideCharType>
5622 {
5623 public:
5624 using char_type = char;
5625
5626 wide_string_input_adapter(BaseInputAdapter base)
5627 : base_adapter(base) {}
5628
5629 typename std::char_traits<char>::int_type get_character() noexcept
5630 {
5631 // check if buffer needs to be filled
5633 {
5634 fill_buffer<sizeof(WideCharType)>();
5635
5638 }
5639
5640 // use buffer
5643 return utf8_bytes[utf8_bytes_index++];
5644 }
5645
5646 private:
5647 BaseInputAdapter base_adapter;
5648
5649 template<size_t T>
5651 {
5653 }
5654
5655 /// a buffer for UTF-8 bytes
5656 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = { {0, 0, 0, 0} };
5657
5658 /// index to the utf8_codes array for the next valid byte
5660 /// number of valid bytes in the utf8_codes array
5662 };
5663
5664
5665 template<typename IteratorType, typename Enable = void>
5667 {
5668 using iterator_type = IteratorType;
5669 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5670 using adapter_type = iterator_input_adapter<iterator_type>;
5671
5672 static adapter_type create(IteratorType first, IteratorType last)
5673 {
5674 return adapter_type(std::move(first), std::move(last));
5675 }
5676 };
5677
5678 template<typename T>
5680 {
5681 using value_type = typename std::iterator_traits<T>::value_type;
5682 enum
5683 {
5684 value = sizeof(value_type) > 1
5685 };
5686 };
5687
5688 template<typename IteratorType>
5690 {
5695
5697 {
5699 }
5700 };
5701
5702 // General purpose iterator-based input
5703 template<typename IteratorType>
5704 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5705 {
5707 return factory_type::create(first, last);
5708 }
5709
5710 // Convenience shorthand from container to iterator
5711 // Enables ADL on begin(container) and end(container)
5712 // Encloses the using declarations in namespace for not to leak them to outside scope
5713
5715 {
5716
5717 using std::begin;
5718 using std::end;
5719
5720 template<typename ContainerType, typename Enable = void>
5722
5723 template<typename ContainerType>
5726 {
5728
5730 {
5732 }
5733 };
5734
5735 } // namespace container_input_adapter_factory_impl
5736
5737 template<typename ContainerType>
5738 typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
5739 {
5741 }
5742
5743#ifndef JSON_NO_IO
5744 // Special cases with fast paths
5746 {
5747 return file_input_adapter(file);
5748 }
5749
5750 inline input_stream_adapter input_adapter(std::istream& stream)
5751 {
5752 return input_stream_adapter(stream);
5753 }
5754
5755 inline input_stream_adapter input_adapter(std::istream&& stream)
5756 {
5757 return input_stream_adapter(stream);
5758 }
5759#endif // JSON_NO_IO
5760
5761 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5762
5763 // Null-delimited strings, and the like.
5764 template < typename CharT,
5765 typename std::enable_if <
5766 std::is_pointer<CharT>::value &&
5767 !std::is_array<CharT>::value&&
5768 std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
5769 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5770 int >::type = 0 >
5771 contiguous_bytes_input_adapter input_adapter(CharT b)
5772 {
5773 auto length = std::strlen(reinterpret_cast<const char*>(b));
5774 const auto* ptr = reinterpret_cast<const char*>(b);
5775 return input_adapter(ptr, ptr + length);
5776 }
5777
5778 template<typename T, std::size_t N>
5779 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)
5780 {
5781 return input_adapter(array, array + N);
5782 }
5783
5784 // This class only handles inputs of input_buffer_adapter type.
5785 // It's required so that expressions like {ptr, len} can be implicitely casted
5786 // to the correct adapter.
5787 class span_input_adapter
5788 {
5789 public:
5790 template < typename CharT,
5791 typename std::enable_if <
5792 std::is_pointer<CharT>::value&&
5793 std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
5794 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5795 int >::type = 0 >
5796 span_input_adapter(CharT b, std::size_t l)
5797 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5798
5799 template<class IteratorType,
5800 typename std::enable_if<
5801 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5802 int>::type = 0>
5803 span_input_adapter(IteratorType first, IteratorType last)
5804 : ia(input_adapter(first, last)) {}
5805
5806 contiguous_bytes_input_adapter&& get()
5807 {
5808 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5809 }
5810
5811 private:
5812 contiguous_bytes_input_adapter ia;
5813 };
5814 } // namespace detail
5815} // namespace nlohmann
5816
5817// #include <nlohmann/detail/input/json_sax.hpp>
5818
5819
5820#include <cstddef>
5821#include <string> // string
5822#include <utility> // move
5823#include <vector> // vector
5824
5825// #include <nlohmann/detail/exceptions.hpp>
5826
5827// #include <nlohmann/detail/macro_scope.hpp>
5828
5829
5830namespace nlohmann
5831{
5832
5833 /*!
5834 @brief SAX interface
5835
5836 This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
5837 Each function is called in different situations while the input is parsed. The
5838 boolean return value informs the parser whether to continue processing the
5839 input.
5840 */
5841 template<typename BasicJsonType>
5843 {
5844 using number_integer_t = typename BasicJsonType::number_integer_t;
5845 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5846 using number_float_t = typename BasicJsonType::number_float_t;
5847 using string_t = typename BasicJsonType::string_t;
5848 using binary_t = typename BasicJsonType::binary_t;
5849
5850 /*!
5851 @brief a null value was read
5852 @return whether parsing should proceed
5853 */
5854 virtual bool null() = 0;
5855
5856 /*!
5857 @brief a boolean value was read
5858 @param[in] val boolean value
5859 @return whether parsing should proceed
5860 */
5861 virtual bool boolean(bool val) = 0;
5862
5863 /*!
5864 @brief an integer number was read
5865 @param[in] val integer value
5866 @return whether parsing should proceed
5867 */
5868 virtual bool number_integer(number_integer_t val) = 0;
5869
5870 /*!
5871 @brief an unsigned integer number was read
5872 @param[in] val unsigned integer value
5873 @return whether parsing should proceed
5874 */
5875 virtual bool number_unsigned(number_unsigned_t val) = 0;
5876
5877 /*!
5878 @brief an floating-point number was read
5879 @param[in] val floating-point value
5880 @param[in] s raw token value
5881 @return whether parsing should proceed
5882 */
5883 virtual bool number_float(number_float_t val, const string_t& s) = 0;
5884
5885 /*!
5886 @brief a string was read
5887 @param[in] val string value
5888 @return whether parsing should proceed
5889 @note It is safe to move the passed string.
5890 */
5891 virtual bool string(string_t& val) = 0;
5892
5893 /*!
5894 @brief a binary string was read
5895 @param[in] val binary value
5896 @return whether parsing should proceed
5897 @note It is safe to move the passed binary.
5898 */
5899 virtual bool binary(binary_t& val) = 0;
5900
5901 /*!
5902 @brief the beginning of an object was read
5903 @param[in] elements number of object elements or -1 if unknown
5904 @return whether parsing should proceed
5905 @note binary formats may report the number of elements
5906 */
5907 virtual bool start_object(std::size_t elements) = 0;
5908
5909 /*!
5910 @brief an object key was read
5911 @param[in] val object key
5912 @return whether parsing should proceed
5913 @note It is safe to move the passed string.
5914 */
5915 virtual bool key(string_t& val) = 0;
5916
5917 /*!
5918 @brief the end of an object was read
5919 @return whether parsing should proceed
5920 */
5921 virtual bool end_object() = 0;
5922
5923 /*!
5924 @brief the beginning of an array was read
5925 @param[in] elements number of array elements or -1 if unknown
5926 @return whether parsing should proceed
5927 @note binary formats may report the number of elements
5928 */
5929 virtual bool start_array(std::size_t elements) = 0;
5930
5931 /*!
5932 @brief the end of an array was read
5933 @return whether parsing should proceed
5934 */
5935 virtual bool end_array() = 0;
5936
5937 /*!
5938 @brief a parse error occurred
5939 @param[in] position the position in the input where the error occurs
5940 @param[in] last_token the last read token
5941 @param[in] ex an exception object describing the error
5942 @return whether parsing should proceed (must return false)
5943 */
5944 virtual bool parse_error(std::size_t position,
5945 const std::string& last_token,
5946 const detail::exception& ex) = 0;
5947
5948 json_sax() = default;
5949 json_sax(const json_sax&) = default;
5950 json_sax(json_sax&&) noexcept = default;
5951 json_sax& operator=(const json_sax&) = default;
5952 json_sax& operator=(json_sax&&) noexcept = default;
5953 virtual ~json_sax() = default;
5954 };
5955
5956
5957 namespace detail
5958 {
5959 /*!
5960 @brief SAX implementation to create a JSON value from SAX events
5961
5962 This class implements the @ref json_sax interface and processes the SAX events
5963 to create a JSON value which makes it basically a DOM parser. The structure or
5964 hierarchy of the JSON value is managed by the stack `ref_stack` which contains
5965 a pointer to the respective array or object for each recursion depth.
5966
5967 After successful parsing, the value that is passed by reference to the
5968 constructor contains the parsed value.
5969
5970 @tparam BasicJsonType the JSON type
5971 */
5972 template<typename BasicJsonType>
5974 {
5975 public:
5976 using number_integer_t = typename BasicJsonType::number_integer_t;
5977 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5978 using number_float_t = typename BasicJsonType::number_float_t;
5979 using string_t = typename BasicJsonType::string_t;
5980 using binary_t = typename BasicJsonType::binary_t;
5981
5982 /*!
5983 @param[in,out] r reference to a JSON value that is manipulated while
5984 parsing
5985 @param[in] allow_exceptions_ whether parse errors yield exceptions
5986 */
5987 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5989 {}
5990
5991 // make class move-only
5993 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5995 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5997
5998 bool null()
5999 {
6000 handle_value(nullptr);
6001 return true;
6002 }
6003
6004 bool boolean(bool val)
6005 {
6007 return true;
6008 }
6009
6010 bool number_integer(number_integer_t val)
6011 {
6013 return true;
6014 }
6015
6016 bool number_unsigned(number_unsigned_t val)
6017 {
6019 return true;
6020 }
6021
6022 bool number_float(number_float_t val, const string_t& /*unused*/)
6023 {
6025 return true;
6026 }
6027
6028 bool string(string_t& val)
6029 {
6031 return true;
6032 }
6033
6034 bool binary(binary_t& val)
6035 {
6037 return true;
6038 }
6039
6040 bool start_object(std::size_t len)
6041 {
6043
6045 {
6046 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6047 }
6048
6049 return true;
6050 }
6051
6052 bool key(string_t& val)
6053 {
6054 // add null at given key and store the reference for later
6056 return true;
6057 }
6058
6060 {
6063 return true;
6064 }
6065
6066 bool start_array(std::size_t len)
6067 {
6069
6071 {
6072 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6073 }
6074
6075 return true;
6076 }
6077
6079 {
6082 return true;
6083 }
6084
6085 template<class Exception>
6086 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6087 const Exception& ex)
6088 {
6089 errored = true;
6090 static_cast<void>(ex);
6091 if (allow_exceptions)
6092 {
6093 JSON_THROW(ex);
6094 }
6095 return false;
6096 }
6097
6098 constexpr bool is_errored() const
6099 {
6100 return errored;
6101 }
6102
6103 private:
6104 /*!
6105 @invariant If the ref stack is empty, then the passed value will be the new
6106 root.
6107 @invariant If the ref stack contains a value, then it is an array or an
6108 object to which we can add elements
6109 */
6110 template<typename Value>
6112 BasicJsonType* handle_value(Value&& v)
6113 {
6114 if (ref_stack.empty())
6115 {
6117 return &root;
6118 }
6119
6121
6122 if (ref_stack.back()->is_array())
6123 {
6125 return &(ref_stack.back()->m_value.array->back());
6126 }
6127
6131 return object_element;
6132 }
6133
6134 /// the parsed JSON value
6135 BasicJsonType& root;
6136 /// stack to model hierarchy of values
6138 /// helper to hold the reference for the next object element
6139 BasicJsonType* object_element = nullptr;
6140 /// whether a syntax error occurred
6141 bool errored = false;
6142 /// whether to throw exceptions in case of errors
6143 const bool allow_exceptions = true;
6144 };
6145
6146 template<typename BasicJsonType>
6148 {
6149 public:
6150 using number_integer_t = typename BasicJsonType::number_integer_t;
6151 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6152 using number_float_t = typename BasicJsonType::number_float_t;
6153 using string_t = typename BasicJsonType::string_t;
6154 using binary_t = typename BasicJsonType::binary_t;
6155 using parser_callback_t = typename BasicJsonType::parser_callback_t;
6156 using parse_event_t = typename BasicJsonType::parse_event_t;
6157
6159 const parser_callback_t cb,
6160 const bool allow_exceptions_ = true)
6162 {
6163 keep_stack.push_back(true);
6164 }
6165
6166 // make class move-only
6168 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6170 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6172
6173 bool null()
6174 {
6175 handle_value(nullptr);
6176 return true;
6177 }
6178
6179 bool boolean(bool val)
6180 {
6182 return true;
6183 }
6184
6185 bool number_integer(number_integer_t val)
6186 {
6188 return true;
6189 }
6190
6191 bool number_unsigned(number_unsigned_t val)
6192 {
6194 return true;
6195 }
6196
6197 bool number_float(number_float_t val, const string_t& /*unused*/)
6198 {
6200 return true;
6201 }
6202
6203 bool string(string_t& val)
6204 {
6206 return true;
6207 }
6208
6209 bool binary(binary_t& val)
6210 {
6212 return true;
6213 }
6214
6215 bool start_object(std::size_t len)
6216 {
6217 // check callback for object start
6218 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6220
6223
6224 // check object limit
6226 {
6227 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6228 }
6229
6230 return true;
6231 }
6232
6233 bool key(string_t& val)
6234 {
6236
6237 // check callback for key
6238 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6240
6241 // add discarded value at given key and store the reference for later
6242 if (keep && ref_stack.back())
6243 {
6245 }
6246
6247 return true;
6248 }
6249
6251 {
6252 if (ref_stack.back())
6253 {
6254 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6255 {
6256 // discard object
6258 }
6259 else
6260 {
6262 }
6263 }
6264
6269
6271 {
6272 // remove discarded value
6273 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6274 {
6275 if (it->is_discarded())
6276 {
6277 ref_stack.back()->erase(it);
6278 break;
6279 }
6280 }
6281 }
6282
6283 return true;
6284 }
6285
6286 bool start_array(std::size_t len)
6287 {
6288 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6290
6291 auto val = handle_value(BasicJsonType::value_t::array, true);
6293
6294 // check array limit
6296 {
6297 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6298 }
6299
6300 return true;
6301 }
6302
6304 {
6305 bool keep = true;
6306
6307 if (ref_stack.back())
6308 {
6309 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6310 if (keep)
6311 {
6313 }
6314 else
6315 {
6316 // discard array
6318 }
6319 }
6320
6325
6326 // remove discarded value
6327 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6328 {
6330 }
6331
6332 return true;
6333 }
6334
6335 template<class Exception>
6336 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6337 const Exception& ex)
6338 {
6339 errored = true;
6340 static_cast<void>(ex);
6341 if (allow_exceptions)
6342 {
6343 JSON_THROW(ex);
6344 }
6345 return false;
6346 }
6347
6348 constexpr bool is_errored() const
6349 {
6350 return errored;
6351 }
6352
6353 private:
6354 /*!
6355 @param[in] v value to add to the JSON value we build during parsing
6356 @param[in] skip_callback whether we should skip calling the callback
6357 function; this is required after start_array() and
6358 start_object() SAX events, because otherwise we would call the
6359 callback function with an empty array or object, respectively.
6360
6361 @invariant If the ref stack is empty, then the passed value will be the new
6362 root.
6363 @invariant If the ref stack contains a value, then it is an array or an
6364 object to which we can add elements
6365
6366 @return pair of boolean (whether value should be kept) and pointer (to the
6367 passed value in the ref_stack hierarchy; nullptr if not kept)
6368 */
6369 template<typename Value>
6370 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6371 {
6373
6374 // do not handle this value if we know it would be added to a discarded
6375 // container
6376 if (!keep_stack.back())
6377 {
6378 return { false, nullptr };
6379 }
6380
6381 // create value
6382 auto value = BasicJsonType(std::forward<Value>(v));
6383
6384 // check callback
6385 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6386
6387 // do not handle this value if we just learnt it shall be discarded
6388 if (!keep)
6389 {
6390 return { false, nullptr };
6391 }
6392
6393 if (ref_stack.empty())
6394 {
6395 root = std::move(value);
6396 return { true, &root };
6397 }
6398
6399 // skip this value if we already decided to skip the parent
6400 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6401 if (!ref_stack.back())
6402 {
6403 return { false, nullptr };
6404 }
6405
6406 // we now only expect arrays and objects
6408
6409 // array
6410 if (ref_stack.back()->is_array())
6411 {
6413 return { true, &(ref_stack.back()->m_value.array->back()) };
6414 }
6415
6416 // object
6418 // check if we should store an element for the current key
6420 const bool store_element = key_keep_stack.back();
6422
6423 if (!store_element)
6424 {
6425 return { false, nullptr };
6426 }
6427
6430 return { true, object_element };
6431 }
6432
6433 /// the parsed JSON value
6434 BasicJsonType& root;
6435 /// stack to model hierarchy of values
6437 /// stack to manage which values to keep
6439 /// stack to manage which object keys to keep
6441 /// helper to hold the reference for the next object element
6442 BasicJsonType* object_element = nullptr;
6443 /// whether a syntax error occurred
6444 bool errored = false;
6445 /// callback function
6446 const parser_callback_t callback = nullptr;
6447 /// whether to throw exceptions in case of errors
6448 const bool allow_exceptions = true;
6449 /// a discarded value for the callback
6450 BasicJsonType discarded = BasicJsonType::value_t::discarded;
6451 };
6452
6453 template<typename BasicJsonType>
6455 {
6456 public:
6457 using number_integer_t = typename BasicJsonType::number_integer_t;
6458 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6459 using number_float_t = typename BasicJsonType::number_float_t;
6460 using string_t = typename BasicJsonType::string_t;
6461 using binary_t = typename BasicJsonType::binary_t;
6462
6463 bool null()
6464 {
6465 return true;
6466 }
6467
6468 bool boolean(bool /*unused*/)
6469 {
6470 return true;
6471 }
6472
6473 bool number_integer(number_integer_t /*unused*/)
6474 {
6475 return true;
6476 }
6477
6478 bool number_unsigned(number_unsigned_t /*unused*/)
6479 {
6480 return true;
6481 }
6482
6483 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6484 {
6485 return true;
6486 }
6487
6488 bool string(string_t& /*unused*/)
6489 {
6490 return true;
6491 }
6492
6493 bool binary(binary_t& /*unused*/)
6494 {
6495 return true;
6496 }
6497
6498 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
6499 {
6500 return true;
6501 }
6502
6503 bool key(string_t& /*unused*/)
6504 {
6505 return true;
6506 }
6507
6509 {
6510 return true;
6511 }
6512
6513 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
6514 {
6515 return true;
6516 }
6517
6519 {
6520 return true;
6521 }
6522
6523 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6524 {
6525 return false;
6526 }
6527 };
6528 } // namespace detail
6529
6530} // namespace nlohmann
6531
6532// #include <nlohmann/detail/input/lexer.hpp>
6533
6534
6535#include <array> // array
6536#include <clocale> // localeconv
6537#include <cstddef> // size_t
6538#include <cstdio> // snprintf
6539#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6540#include <initializer_list> // initializer_list
6541#include <string> // char_traits, string
6542#include <utility> // move
6543#include <vector> // vector
6544
6545// #include <nlohmann/detail/input/input_adapters.hpp>
6546
6547// #include <nlohmann/detail/input/position_t.hpp>
6548
6549// #include <nlohmann/detail/macro_scope.hpp>
6550
6551
6552namespace nlohmann
6553{
6554 namespace detail
6555 {
6556 ///////////
6557 // lexer //
6558 ///////////
6559
6560 template<typename BasicJsonType>
6562 {
6563 public:
6564 /// token types for the parser
6565 enum class token_type
6566 {
6567 uninitialized, ///< indicating the scanner is uninitialized
6568 literal_true, ///< the `true` literal
6569 literal_false, ///< the `false` literal
6570 literal_null, ///< the `null` literal
6571 value_string, ///< a string -- use get_string() for actual value
6572 value_unsigned, ///< an unsigned integer -- use get_number_unsigned() for actual value
6573 value_integer, ///< a signed integer -- use get_number_integer() for actual value
6574 value_float, ///< an floating point number -- use get_number_float() for actual value
6575 begin_array, ///< the character for array begin `[`
6576 begin_object, ///< the character for object begin `{`
6577 end_array, ///< the character for array end `]`
6578 end_object, ///< the character for object end `}`
6579 name_separator, ///< the name separator `:`
6580 value_separator, ///< the value separator `,`
6581 parse_error, ///< indicating a parse error
6582 end_of_input, ///< indicating the end of the input buffer
6583 literal_or_value ///< a literal or the begin of a value (only for diagnostics)
6584 };
6585
6586 /// return name of values of type token_type (only used for errors)
6589 static const char* token_type_name(const token_type t) noexcept
6590 {
6591 switch (t)
6592 {
6594 return "<uninitialized>";
6596 return "true literal";
6598 return "false literal";
6600 return "null literal";
6602 return "string literal";
6605 case token_type::value_float:
6606 return "number literal";
6607 case token_type::begin_array:
6608 return "'['";
6610 return "'{'";
6611 case token_type::end_array:
6612 return "']'";
6613 case token_type::end_object:
6614 return "'}'";
6616 return "':'";
6618 return "','";
6619 case token_type::parse_error:
6620 return "<parse error>";
6622 return "end of input";
6624 return "'[', '{', or a literal";
6625 // LCOV_EXCL_START
6626 default: // catch non-enum values
6627 return "unknown token";
6628 // LCOV_EXCL_STOP
6629 }
6630 }
6631 };
6632 /*!
6633 @brief lexical analysis
6634
6635 This class organizes the lexical analysis during JSON deserialization.
6636 */
6637 template<typename BasicJsonType, typename InputAdapterType>
6638 class lexer : public lexer_base<BasicJsonType>
6639 {
6640 using number_integer_t = typename BasicJsonType::number_integer_t;
6641 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6642 using number_float_t = typename BasicJsonType::number_float_t;
6643 using string_t = typename BasicJsonType::string_t;
6644 using char_type = typename InputAdapterType::char_type;
6645 using char_int_type = typename std::char_traits<char_type>::int_type;
6646
6647 public:
6648 using token_type = typename lexer_base<BasicJsonType>::token_type;
6649
6650 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6651 : ia(std::move(adapter))
6654 {}
6655
6656 // delete because of pointer members
6657 lexer(const lexer&) = delete;
6658 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6659 lexer& operator=(lexer&) = delete;
6660 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6661 ~lexer() = default;
6662
6663 private:
6664 /////////////////////
6665 // locales
6666 /////////////////////
6667
6668 /// return the locale-dependent decimal point
6670 static char get_decimal_point() noexcept
6671 {
6672 const auto* loc = localeconv();
6673 JSON_ASSERT(loc != nullptr);
6674 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6675 }
6676
6677 /////////////////////
6678 // scan functions
6679 /////////////////////
6680
6681 /*!
6682 @brief get codepoint from 4 hex characters following `\u`
6683
6684 For input "\u c1 c2 c3 c4" the codepoint is:
6685 (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
6686 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
6687
6688 Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
6689 must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
6690 conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
6691 between the ASCII value of the character and the desired integer value.
6692
6693 @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
6694 non-hex character)
6695 */
6697 {
6698 // this function only makes sense after reading `\u`
6699 JSON_ASSERT(current == 'u');
6700 int codepoint = 0;
6701
6702 const auto factors = { 12u, 8u, 4u, 0u };
6703 for (const auto factor : factors)
6704 {
6705 get();
6706
6707 if (current >= '0' && current <= '9')
6708 {
6709 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6710 }
6711 else if (current >= 'A' && current <= 'F')
6712 {
6713 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6714 }
6715 else if (current >= 'a' && current <= 'f')
6716 {
6717 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6718 }
6719 else
6720 {
6721 return -1;
6722 }
6723 }
6724
6725 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6726 return codepoint;
6727 }
6728
6729 /*!
6730 @brief check if the next byte(s) are inside a given range
6731
6732 Adds the current byte and, for each passed range, reads a new byte and
6733 checks if it is inside the range. If a violation was detected, set up an
6734 error message and return false. Otherwise, return true.
6735
6736 @param[in] ranges list of integers; interpreted as list of pairs of
6737 inclusive lower and upper bound, respectively
6738
6739 @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
6740 1, 2, or 3 pairs. This precondition is enforced by an assertion.
6741
6742 @return true if and only if no range violation was detected
6743 */
6744 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6745 {
6746 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6747 add(current);
6748
6749 for (auto range = ranges.begin(); range != ranges.end(); ++range)
6750 {
6751 get();
6752 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6753 {
6754 add(current);
6755 }
6756 else
6757 {
6758 error_message = "invalid string: ill-formed UTF-8 byte";
6759 return false;
6760 }
6761 }
6762
6763 return true;
6764 }
6765
6766 /*!
6767 @brief scan a string literal
6768
6769 This function scans a string according to Sect. 7 of RFC 8259. While
6770 scanning, bytes are escaped and copied into buffer token_buffer. Then the
6771 function returns successfully, token_buffer is *not* null-terminated (as it
6772 may contain \0 bytes), and token_buffer.size() is the number of bytes in the
6773 string.
6774
6775 @return token_type::value_string if string could be successfully scanned,
6776 token_type::parse_error otherwise
6777
6778 @note In case of errors, variable error_message contains a textual
6779 description.
6780 */
6781 token_type scan_string()
6782 {
6783 // reset token_buffer (ignore opening quote)
6784 reset();
6785
6786 // we entered the function by reading an open quote
6787 JSON_ASSERT(current == '\"');
6788
6789 while (true)
6790 {
6791 // get next character
6792 switch (get())
6793 {
6794 // end of file while parsing string
6795 case std::char_traits<char_type>::eof():
6796 {
6797 error_message = "invalid string: missing closing quote";
6798 return token_type::parse_error;
6799 }
6800
6801 // closing quote
6802 case '\"':
6803 {
6804 return token_type::value_string;
6805 }
6806
6807 // escapes
6808 case '\\':
6809 {
6810 switch (get())
6811 {
6812 // quotation mark
6813 case '\"':
6814 add('\"');
6815 break;
6816 // reverse solidus
6817 case '\\':
6818 add('\\');
6819 break;
6820 // solidus
6821 case '/':
6822 add('/');
6823 break;
6824 // backspace
6825 case 'b':
6826 add('\b');
6827 break;
6828 // form feed
6829 case 'f':
6830 add('\f');
6831 break;
6832 // line feed
6833 case 'n':
6834 add('\n');
6835 break;
6836 // carriage return
6837 case 'r':
6838 add('\r');
6839 break;
6840 // tab
6841 case 't':
6842 add('\t');
6843 break;
6844
6845 // unicode escapes
6846 case 'u':
6847 {
6848 const int codepoint1 = get_codepoint();
6849 int codepoint = codepoint1; // start with codepoint1
6850
6852 {
6853 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6854 return token_type::parse_error;
6855 }
6856
6857 // check if code point is a high surrogate
6858 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6859 {
6860 // expect next \uxxxx entry
6861 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6862 {
6863 const int codepoint2 = get_codepoint();
6864
6866 {
6867 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6868 return token_type::parse_error;
6869 }
6870
6871 // check if codepoint2 is a low surrogate
6872 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6873 {
6874 // overwrite codepoint
6875 codepoint = static_cast<int>(
6876 // high surrogate occupies the most significant 22 bits
6877 (static_cast<unsigned int>(codepoint1) << 10u)
6878 // low surrogate occupies the least significant 15 bits
6879 + static_cast<unsigned int>(codepoint2)
6880 // there is still the 0xD800, 0xDC00 and 0x10000 noise
6881 // in the result so we have to subtract with:
6882 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6883 -0x35FDC00u);
6884 }
6885 else
6886 {
6887 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6888 return token_type::parse_error;
6889 }
6890 }
6891 else
6892 {
6893 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6894 return token_type::parse_error;
6895 }
6896 }
6897 else
6898 {
6899 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6900 {
6901 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6902 return token_type::parse_error;
6903 }
6904 }
6905
6906 // result of the above calculation yields a proper codepoint
6907 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6908
6909 // translate codepoint into bytes
6910 if (codepoint < 0x80)
6911 {
6912 // 1-byte characters: 0xxxxxxx (ASCII)
6913 add(static_cast<char_int_type>(codepoint));
6914 }
6915 else if (codepoint <= 0x7FF)
6916 {
6917 // 2-byte characters: 110xxxxx 10xxxxxx
6918 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6919 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6920 }
6921 else if (codepoint <= 0xFFFF)
6922 {
6923 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6924 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6925 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6926 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6927 }
6928 else
6929 {
6930 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6931 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6932 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
6933 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6934 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6935 }
6936
6937 break;
6938 }
6939
6940 // other characters after escape
6941 default:
6942 error_message = "invalid string: forbidden character after backslash";
6943 return token_type::parse_error;
6944 }
6945
6946 break;
6947 }
6948
6949 // invalid control characters
6950 case 0x00:
6951 {
6952 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6953 return token_type::parse_error;
6954 }
6955
6956 case 0x01:
6957 {
6958 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6959 return token_type::parse_error;
6960 }
6961
6962 case 0x02:
6963 {
6964 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6965 return token_type::parse_error;
6966 }
6967
6968 case 0x03:
6969 {
6970 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6971 return token_type::parse_error;
6972 }
6973
6974 case 0x04:
6975 {
6976 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6977 return token_type::parse_error;
6978 }
6979
6980 case 0x05:
6981 {
6982 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6983 return token_type::parse_error;
6984 }
6985
6986 case 0x06:
6987 {
6988 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6989 return token_type::parse_error;
6990 }
6991
6992 case 0x07:
6993 {
6994 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6995 return token_type::parse_error;
6996 }
6997
6998 case 0x08:
6999 {
7000 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7001 return token_type::parse_error;
7002 }
7003
7004 case 0x09:
7005 {
7006 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7007 return token_type::parse_error;
7008 }
7009
7010 case 0x0A:
7011 {
7012 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7013 return token_type::parse_error;
7014 }
7015
7016 case 0x0B:
7017 {
7018 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7019 return token_type::parse_error;
7020 }
7021
7022 case 0x0C:
7023 {
7024 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7025 return token_type::parse_error;
7026 }
7027
7028 case 0x0D:
7029 {
7030 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7031 return token_type::parse_error;
7032 }
7033
7034 case 0x0E:
7035 {
7036 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7037 return token_type::parse_error;
7038 }
7039
7040 case 0x0F:
7041 {
7042 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7043 return token_type::parse_error;
7044 }
7045
7046 case 0x10:
7047 {
7048 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7049 return token_type::parse_error;
7050 }
7051
7052 case 0x11:
7053 {
7054 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7055 return token_type::parse_error;
7056 }
7057
7058 case 0x12:
7059 {
7060 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7061 return token_type::parse_error;
7062 }
7063
7064 case 0x13:
7065 {
7066 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7067 return token_type::parse_error;
7068 }
7069
7070 case 0x14:
7071 {
7072 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7073 return token_type::parse_error;
7074 }
7075
7076 case 0x15:
7077 {
7078 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7079 return token_type::parse_error;
7080 }
7081
7082 case 0x16:
7083 {
7084 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7085 return token_type::parse_error;
7086 }
7087
7088 case 0x17:
7089 {
7090 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7091 return token_type::parse_error;
7092 }
7093
7094 case 0x18:
7095 {
7096 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7097 return token_type::parse_error;
7098 }
7099
7100 case 0x19:
7101 {
7102 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7103 return token_type::parse_error;
7104 }
7105
7106 case 0x1A:
7107 {
7108 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7109 return token_type::parse_error;
7110 }
7111
7112 case 0x1B:
7113 {
7114 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7115 return token_type::parse_error;
7116 }
7117
7118 case 0x1C:
7119 {
7120 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7121 return token_type::parse_error;
7122 }
7123
7124 case 0x1D:
7125 {
7126 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7127 return token_type::parse_error;
7128 }
7129
7130 case 0x1E:
7131 {
7132 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7133 return token_type::parse_error;
7134 }
7135
7136 case 0x1F:
7137 {
7138 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7139 return token_type::parse_error;
7140 }
7141
7142 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7143 case 0x20:
7144 case 0x21:
7145 case 0x23:
7146 case 0x24:
7147 case 0x25:
7148 case 0x26:
7149 case 0x27:
7150 case 0x28:
7151 case 0x29:
7152 case 0x2A:
7153 case 0x2B:
7154 case 0x2C:
7155 case 0x2D:
7156 case 0x2E:
7157 case 0x2F:
7158 case 0x30:
7159 case 0x31:
7160 case 0x32:
7161 case 0x33:
7162 case 0x34:
7163 case 0x35:
7164 case 0x36:
7165 case 0x37:
7166 case 0x38:
7167 case 0x39:
7168 case 0x3A:
7169 case 0x3B:
7170 case 0x3C:
7171 case 0x3D:
7172 case 0x3E:
7173 case 0x3F:
7174 case 0x40:
7175 case 0x41:
7176 case 0x42:
7177 case 0x43:
7178 case 0x44:
7179 case 0x45:
7180 case 0x46:
7181 case 0x47:
7182 case 0x48:
7183 case 0x49:
7184 case 0x4A:
7185 case 0x4B:
7186 case 0x4C:
7187 case 0x4D:
7188 case 0x4E:
7189 case 0x4F:
7190 case 0x50:
7191 case 0x51:
7192 case 0x52:
7193 case 0x53:
7194 case 0x54:
7195 case 0x55:
7196 case 0x56:
7197 case 0x57:
7198 case 0x58:
7199 case 0x59:
7200 case 0x5A:
7201 case 0x5B:
7202 case 0x5D:
7203 case 0x5E:
7204 case 0x5F:
7205 case 0x60:
7206 case 0x61:
7207 case 0x62:
7208 case 0x63:
7209 case 0x64:
7210 case 0x65:
7211 case 0x66:
7212 case 0x67:
7213 case 0x68:
7214 case 0x69:
7215 case 0x6A:
7216 case 0x6B:
7217 case 0x6C:
7218 case 0x6D:
7219 case 0x6E:
7220 case 0x6F:
7221 case 0x70:
7222 case 0x71:
7223 case 0x72:
7224 case 0x73:
7225 case 0x74:
7226 case 0x75:
7227 case 0x76:
7228 case 0x77:
7229 case 0x78:
7230 case 0x79:
7231 case 0x7A:
7232 case 0x7B:
7233 case 0x7C:
7234 case 0x7D:
7235 case 0x7E:
7236 case 0x7F:
7237 {
7238 add(current);
7239 break;
7240 }
7241
7242 // U+0080..U+07FF: bytes C2..DF 80..BF
7243 case 0xC2:
7244 case 0xC3:
7245 case 0xC4:
7246 case 0xC5:
7247 case 0xC6:
7248 case 0xC7:
7249 case 0xC8:
7250 case 0xC9:
7251 case 0xCA:
7252 case 0xCB:
7253 case 0xCC:
7254 case 0xCD:
7255 case 0xCE:
7256 case 0xCF:
7257 case 0xD0:
7258 case 0xD1:
7259 case 0xD2:
7260 case 0xD3:
7261 case 0xD4:
7262 case 0xD5:
7263 case 0xD6:
7264 case 0xD7:
7265 case 0xD8:
7266 case 0xD9:
7267 case 0xDA:
7268 case 0xDB:
7269 case 0xDC:
7270 case 0xDD:
7271 case 0xDE:
7272 case 0xDF:
7273 {
7274 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({ 0x80, 0xBF })))
7275 {
7276 return token_type::parse_error;
7277 }
7278 break;
7279 }
7280
7281 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7282 case 0xE0:
7283 {
7284 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0xA0, 0xBF, 0x80, 0xBF }))))
7285 {
7286 return token_type::parse_error;
7287 }
7288 break;
7289 }
7290
7291 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7292 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7293 case 0xE1:
7294 case 0xE2:
7295 case 0xE3:
7296 case 0xE4:
7297 case 0xE5:
7298 case 0xE6:
7299 case 0xE7:
7300 case 0xE8:
7301 case 0xE9:
7302 case 0xEA:
7303 case 0xEB:
7304 case 0xEC:
7305 case 0xEE:
7306 case 0xEF:
7307 {
7308 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0xBF, 0x80, 0xBF }))))
7309 {
7310 return token_type::parse_error;
7311 }
7312 break;
7313 }
7314
7315 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7316 case 0xED:
7317 {
7318 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0x9F, 0x80, 0xBF }))))
7319 {
7320 return token_type::parse_error;
7321 }
7322 break;
7323 }
7324
7325 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7326 case 0xF0:
7327 {
7328 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF }))))
7329 {
7330 return token_type::parse_error;
7331 }
7332 break;
7333 }
7334
7335 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7336 case 0xF1:
7337 case 0xF2:
7338 case 0xF3:
7339 {
7340 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF }))))
7341 {
7342 return token_type::parse_error;
7343 }
7344 break;
7345 }
7346
7347 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7348 case 0xF4:
7349 {
7350 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({ 0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF }))))
7351 {
7352 return token_type::parse_error;
7353 }
7354 break;
7355 }
7356
7357 // remaining bytes (80..C1 and F5..FF) are ill-formed
7358 default:
7359 {
7360 error_message = "invalid string: ill-formed UTF-8 byte";
7361 return token_type::parse_error;
7362 }
7363 }
7364 }
7365 }
7366
7367 /*!
7368 * @brief scan a comment
7369 * @return whether comment could be scanned successfully
7370 */
7372 {
7373 switch (get())
7374 {
7375 // single-line comments skip input until a newline or EOF is read
7376 case '/':
7377 {
7378 while (true)
7379 {
7380 switch (get())
7381 {
7382 case '\n':
7383 case '\r':
7384 case std::char_traits<char_type>::eof():
7385 case '\0':
7386 return true;
7387
7388 default:
7389 break;
7390 }
7391 }
7392 }
7393
7394 // multi-line comments skip input until */ is read
7395 case '*':
7396 {
7397 while (true)
7398 {
7399 switch (get())
7400 {
7401 case std::char_traits<char_type>::eof():
7402 case '\0':
7403 {
7404 error_message = "invalid comment; missing closing '*/'";
7405 return false;
7406 }
7407
7408 case '*':
7409 {
7410 switch (get())
7411 {
7412 case '/':
7413 return true;
7414
7415 default:
7416 {
7417 unget();
7418 continue;
7419 }
7420 }
7421 }
7422
7423 default:
7424 continue;
7425 }
7426 }
7427 }
7428
7429 // unexpected character after reading '/'
7430 default:
7431 {
7432 error_message = "invalid comment; expecting '/' or '*' after '/'";
7433 return false;
7434 }
7435 }
7436 }
7437
7439 static void strtof(float& f, const char* str, char** endptr) noexcept
7440 {
7441 f = std::strtof(str, endptr);
7442 }
7443
7445 static void strtof(double& f, const char* str, char** endptr) noexcept
7446 {
7447 f = std::strtod(str, endptr);
7448 }
7449
7451 static void strtof(long double& f, const char* str, char** endptr) noexcept
7452 {
7453 f = std::strtold(str, endptr);
7454 }
7455
7456 /*!
7457 @brief scan a number literal
7458
7459 This function scans a string according to Sect. 6 of RFC 8259.
7460
7461 The function is realized with a deterministic finite state machine derived
7462 from the grammar described in RFC 8259. Starting in state "init", the
7463 input is read and used to determined the next state. Only state "done"
7464 accepts the number. State "error" is a trap state to model errors. In the
7465 table below, "anything" means any character but the ones listed before.
7466
7467 state | 0 | 1-9 | e E | + | - | . | anything
7468 ---------|----------|----------|----------|---------|---------|----------|-----------
7469 init | zero | any1 | [error] | [error] | minus | [error] | [error]
7470 minus | zero | any1 | [error] | [error] | [error] | [error] | [error]
7471 zero | done | done | exponent | done | done | decimal1 | done
7472 any1 | any1 | any1 | exponent | done | done | decimal1 | done
7473 decimal1 | decimal2 | decimal2 | [error] | [error] | [error] | [error] | [error]
7474 decimal2 | decimal2 | decimal2 | exponent | done | done | done | done
7475 exponent | any2 | any2 | [error] | sign | sign | [error] | [error]
7476 sign | any2 | any2 | [error] | [error] | [error] | [error] | [error]
7477 any2 | any2 | any2 | done | done | done | done | done
7478
7479 The state machine is realized with one label per state (prefixed with
7480 "scan_number_") and `goto` statements between them. The state machine
7481 contains cycles, but any cycle can be left when EOF is read. Therefore,
7482 the function is guaranteed to terminate.
7483
7484 During scanning, the read bytes are stored in token_buffer. This string is
7485 then converted to a signed integer, an unsigned integer, or a
7486 floating-point number.
7487
7488 @return token_type::value_unsigned, token_type::value_integer, or
7489 token_type::value_float if number could be successfully scanned,
7490 token_type::parse_error otherwise
7491
7492 @note The scanner is independent of the current locale. Internally, the
7493 locale's decimal point is used instead of `.` to work with the
7494 locale-dependent converters.
7495 */
7496 token_type scan_number() // lgtm [cpp/use-of-goto]
7497 {
7498 // reset token_buffer to store the number's bytes
7499 reset();
7500
7501 // the type of the parsed number; initially set to unsigned; will be
7502 // changed if minus sign, decimal point or exponent is read
7504
7505 // state (init): we just found out we need to scan a number
7506 switch (current)
7507 {
7508 case '-':
7509 {
7510 add(current);
7511 goto scan_number_minus;
7512 }
7513
7514 case '0':
7515 {
7516 add(current);
7517 goto scan_number_zero;
7518 }
7519
7520 case '1':
7521 case '2':
7522 case '3':
7523 case '4':
7524 case '5':
7525 case '6':
7526 case '7':
7527 case '8':
7528 case '9':
7529 {
7530 add(current);
7531 goto scan_number_any1;
7532 }
7533
7534 // all other characters are rejected outside scan_number()
7535 default: // LCOV_EXCL_LINE
7536 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7537 }
7538
7540 // state: we just parsed a leading minus sign
7542 switch (get())
7543 {
7544 case '0':
7545 {
7546 add(current);
7547 goto scan_number_zero;
7548 }
7549
7550 case '1':
7551 case '2':
7552 case '3':
7553 case '4':
7554 case '5':
7555 case '6':
7556 case '7':
7557 case '8':
7558 case '9':
7559 {
7560 add(current);
7561 goto scan_number_any1;
7562 }
7563
7564 default:
7565 {
7566 error_message = "invalid number; expected digit after '-'";
7567 return token_type::parse_error;
7568 }
7569 }
7570
7572 // state: we just parse a zero (maybe with a leading minus sign)
7573 switch (get())
7574 {
7575 case '.':
7576 {
7579 }
7580
7581 case 'e':
7582 case 'E':
7583 {
7584 add(current);
7586 }
7587
7588 default:
7589 goto scan_number_done;
7590 }
7591
7593 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7594 switch (get())
7595 {
7596 case '0':
7597 case '1':
7598 case '2':
7599 case '3':
7600 case '4':
7601 case '5':
7602 case '6':
7603 case '7':
7604 case '8':
7605 case '9':
7606 {
7607 add(current);
7608 goto scan_number_any1;
7609 }
7610
7611 case '.':
7612 {
7615 }
7616
7617 case 'e':
7618 case 'E':
7619 {
7620 add(current);
7622 }
7623
7624 default:
7625 goto scan_number_done;
7626 }
7627
7629 // state: we just parsed a decimal point
7631 switch (get())
7632 {
7633 case '0':
7634 case '1':
7635 case '2':
7636 case '3':
7637 case '4':
7638 case '5':
7639 case '6':
7640 case '7':
7641 case '8':
7642 case '9':
7643 {
7644 add(current);
7646 }
7647
7648 default:
7649 {
7650 error_message = "invalid number; expected digit after '.'";
7651 return token_type::parse_error;
7652 }
7653 }
7654
7656 // we just parsed at least one number after a decimal point
7657 switch (get())
7658 {
7659 case '0':
7660 case '1':
7661 case '2':
7662 case '3':
7663 case '4':
7664 case '5':
7665 case '6':
7666 case '7':
7667 case '8':
7668 case '9':
7669 {
7670 add(current);
7672 }
7673
7674 case 'e':
7675 case 'E':
7676 {
7677 add(current);
7679 }
7680
7681 default:
7682 goto scan_number_done;
7683 }
7684
7686 // we just parsed an exponent
7688 switch (get())
7689 {
7690 case '+':
7691 case '-':
7692 {
7693 add(current);
7694 goto scan_number_sign;
7695 }
7696
7697 case '0':
7698 case '1':
7699 case '2':
7700 case '3':
7701 case '4':
7702 case '5':
7703 case '6':
7704 case '7':
7705 case '8':
7706 case '9':
7707 {
7708 add(current);
7709 goto scan_number_any2;
7710 }
7711
7712 default:
7713 {
7715 "invalid number; expected '+', '-', or digit after exponent";
7716 return token_type::parse_error;
7717 }
7718 }
7719
7721 // we just parsed an exponent sign
7722 switch (get())
7723 {
7724 case '0':
7725 case '1':
7726 case '2':
7727 case '3':
7728 case '4':
7729 case '5':
7730 case '6':
7731 case '7':
7732 case '8':
7733 case '9':
7734 {
7735 add(current);
7736 goto scan_number_any2;
7737 }
7738
7739 default:
7740 {
7741 error_message = "invalid number; expected digit after exponent sign";
7742 return token_type::parse_error;
7743 }
7744 }
7745
7747 // we just parsed a number after the exponent or exponent sign
7748 switch (get())
7749 {
7750 case '0':
7751 case '1':
7752 case '2':
7753 case '3':
7754 case '4':
7755 case '5':
7756 case '6':
7757 case '7':
7758 case '8':
7759 case '9':
7760 {
7761 add(current);
7762 goto scan_number_any2;
7763 }
7764
7765 default:
7766 goto scan_number_done;
7767 }
7768
7770 // unget the character after the number (we only read it to know that
7771 // we are done scanning a number)
7772 unget();
7773
7774 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7775 errno = 0;
7776
7777 // try to parse integers first and fall back to floats
7779 {
7780 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7781
7782 // we checked the number format before
7784
7785 if (errno == 0)
7786 {
7787 value_unsigned = static_cast<number_unsigned_t>(x);
7788 if (value_unsigned == x)
7789 {
7790 return token_type::value_unsigned;
7791 }
7792 }
7793 }
7795 {
7796 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7797
7798 // we checked the number format before
7800
7801 if (errno == 0)
7802 {
7803 value_integer = static_cast<number_integer_t>(x);
7804 if (value_integer == x)
7805 {
7806 return token_type::value_integer;
7807 }
7808 }
7809 }
7810
7811 // this code is reached if we parse a floating-point number or if an
7812 // integer conversion above failed
7814
7815 // we checked the number format before
7817
7818 return token_type::value_float;
7819 }
7820
7821 /*!
7822 @param[in] literal_text the literal text to expect
7823 @param[in] length the length of the passed literal text
7824 @param[in] return_type the token type to return on success
7825 */
7827 token_type scan_literal(const char_type* literal_text, const std::size_t length,
7828 token_type return_type)
7829 {
7831 for (std::size_t i = 1; i < length; ++i)
7832 {
7834 {
7835 error_message = "invalid literal";
7836 return token_type::parse_error;
7837 }
7838 }
7839 return return_type;
7840 }
7841
7842 /////////////////////
7843 // input management
7844 /////////////////////
7845
7846 /// reset token_buffer; current character is beginning of token
7847 void reset() noexcept
7848 {
7852 }
7853
7854 /*
7855 @brief get next character from the input
7856
7857 This function provides the interface to the used input adapter. It does
7858 not throw in case the input reached EOF, but returns a
7859 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7860 for use in error messages.
7861
7862 @return character read from the input
7863 */
7864 char_int_type get()
7865 {
7868
7869 if (next_unget)
7870 {
7871 // just reset the next_unget variable and work with current
7872 next_unget = false;
7873 }
7874 else
7875 {
7877 }
7878
7880 {
7882 }
7883
7884 if (current == '\n')
7885 {
7888 }
7889
7890 return current;
7891 }
7892
7893 /*!
7894 @brief unget current character (read it again on next get)
7895
7896 We implement unget by setting variable next_unget to true. The input is not
7897 changed - we just simulate ungetting by modifying chars_read_total,
7898 chars_read_current_line, and token_string. The next call to get() will
7899 behave as if the unget character is read again.
7900 */
7901 void unget()
7902 {
7903 next_unget = true;
7904
7906
7907 // in case we "unget" a newline, we have to also decrement the lines_read
7909 {
7910 if (position.lines_read > 0)
7911 {
7913 }
7914 }
7915 else
7916 {
7918 }
7919
7921 {
7924 }
7925 }
7926
7927 /// add a character to token_buffer
7928 void add(char_int_type c)
7929 {
7930 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7931 }
7932
7933 public:
7934 /////////////////////
7935 // value getters
7936 /////////////////////
7937
7938 /// return integer value
7939 constexpr number_integer_t get_number_integer() const noexcept
7940 {
7941 return value_integer;
7942 }
7943
7944 /// return unsigned integer value
7945 constexpr number_unsigned_t get_number_unsigned() const noexcept
7946 {
7947 return value_unsigned;
7948 }
7949
7950 /// return floating-point value
7951 constexpr number_float_t get_number_float() const noexcept
7952 {
7953 return value_float;
7954 }
7955
7956 /// return current string value (implicitly resets the token; useful only once)
7957 string_t& get_string()
7958 {
7959 return token_buffer;
7960 }
7961
7962 /////////////////////
7963 // diagnostics
7964 /////////////////////
7965
7966 /// return position of last read token
7967 constexpr position_t get_position() const noexcept
7968 {
7969 return position;
7970 }
7971
7972 /// return the last read token (for errors only). Will never contain EOF
7973 /// (an arbitrary value that is not a valid char value, often -1), because
7974 /// 255 may legitimately occur. May contain NUL, which should be escaped.
7975 std::string get_token_string() const
7976 {
7977 // escape control characters
7978 std::string result;
7979 for (const auto c : token_string)
7980 {
7981 if (static_cast<unsigned char>(c) <= '\x1F')
7982 {
7983 // escape control characters
7984 std::array<char, 9> cs{ {} };
7985 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7986 result += cs.data();
7987 }
7988 else
7989 {
7990 // add character as is
7991 result.push_back(static_cast<std::string::value_type>(c));
7992 }
7993 }
7994
7995 return result;
7996 }
7997
7998 /// return syntax error message
8000 constexpr const char* get_error_message() const noexcept
8001 {
8002 return error_message;
8003 }
8004
8005 /////////////////////
8006 // actual scanner
8007 /////////////////////
8008
8009 /*!
8010 @brief skip the UTF-8 byte order mark
8011 @return true iff there is no BOM or the correct BOM has been skipped
8012 */
8014 {
8015 if (get() == 0xEF)
8016 {
8017 // check if we completely parse the BOM
8018 return get() == 0xBB && get() == 0xBF;
8019 }
8020
8021 // the first character is not the beginning of the BOM; unget it to
8022 // process is later
8023 unget();
8024 return true;
8025 }
8026
8028 {
8029 do
8030 {
8031 get();
8032 } while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8033 }
8034
8035 token_type scan()
8036 {
8037 // initially, skip the BOM
8038 if (position.chars_read_total == 0 && !skip_bom())
8039 {
8040 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8041 return token_type::parse_error;
8042 }
8043
8044 // read next character and ignore whitespace
8046
8047 // ignore comments
8048 while (ignore_comments && current == '/')
8049 {
8050 if (!scan_comment())
8051 {
8052 return token_type::parse_error;
8053 }
8054
8055 // skip following whitespace
8057 }
8058
8059 switch (current)
8060 {
8061 // structural characters
8062 case '[':
8063 return token_type::begin_array;
8064 case ']':
8065 return token_type::end_array;
8066 case '{':
8067 return token_type::begin_object;
8068 case '}':
8069 return token_type::end_object;
8070 case ':':
8071 return token_type::name_separator;
8072 case ',':
8074
8075 // literals
8076 case 't':
8077 {
8078 std::array<char_type, 4> true_literal = { {char_type('t'), char_type('r'), char_type('u'), char_type('e')} };
8080 }
8081 case 'f':
8082 {
8083 std::array<char_type, 5> false_literal = { {char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')} };
8085 }
8086 case 'n':
8087 {
8088 std::array<char_type, 4> null_literal = { {char_type('n'), char_type('u'), char_type('l'), char_type('l')} };
8090 }
8091
8092 // string
8093 case '\"':
8094 return scan_string();
8095
8096 // number
8097 case '-':
8098 case '0':
8099 case '1':
8100 case '2':
8101 case '3':
8102 case '4':
8103 case '5':
8104 case '6':
8105 case '7':
8106 case '8':
8107 case '9':
8108 return scan_number();
8109
8110 // end of input (the null byte is needed when parsing from
8111 // string literals)
8112 case '\0':
8113 case std::char_traits<char_type>::eof():
8114 return token_type::end_of_input;
8115
8116 // error
8117 default:
8118 error_message = "invalid literal";
8119 return token_type::parse_error;
8120 }
8121 }
8122
8123 private:
8124 /// input adapter
8125 InputAdapterType ia;
8126
8127 /// whether comments should be ignored (true) or signaled as errors (false)
8128 const bool ignore_comments = false;
8129
8130 /// the current character
8131 char_int_type current = std::char_traits<char_type>::eof();
8132
8133 /// whether the next get() call should just return current
8134 bool next_unget = false;
8135
8136 /// the start position of the current token
8138
8139 /// raw input token string (for error messages)
8141
8142 /// buffer for variable-length tokens (numbers, strings)
8143 string_t token_buffer{};
8144
8145 /// a description of occurred lexer errors
8146 const char* error_message = "";
8147
8148 // number values
8149 number_integer_t value_integer = 0;
8150 number_unsigned_t value_unsigned = 0;
8151 number_float_t value_float = 0;
8152
8153 /// the decimal point
8154 const char_int_type decimal_point_char = '.';
8155 };
8156 } // namespace detail
8157} // namespace nlohmann
8158
8159// #include <nlohmann/detail/macro_scope.hpp>
8160
8161// #include <nlohmann/detail/meta/is_sax.hpp>
8162
8163
8164#include <cstdint> // size_t
8165#include <utility> // declval
8166#include <string> // string
8167
8168// #include <nlohmann/detail/meta/detected.hpp>
8169
8170// #include <nlohmann/detail/meta/type_traits.hpp>
8171
8172
8173namespace nlohmann
8174{
8175 namespace detail
8176 {
8177 template<typename T>
8178 using null_function_t = decltype(std::declval<T&>().null());
8179
8180 template<typename T>
8182 decltype(std::declval<T&>().boolean(std::declval<bool>()));
8183
8184 template<typename T, typename Integer>
8185 using number_integer_function_t =
8186 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8187
8188 template<typename T, typename Unsigned>
8189 using number_unsigned_function_t =
8190 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8191
8192 template<typename T, typename Float, typename String>
8193 using number_float_function_t = decltype(std::declval<T&>().number_float(
8194 std::declval<Float>(), std::declval<const String&>()));
8195
8196 template<typename T, typename String>
8197 using string_function_t =
8198 decltype(std::declval<T&>().string(std::declval<String&>()));
8199
8200 template<typename T, typename Binary>
8201 using binary_function_t =
8202 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8203
8204 template<typename T>
8206 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8207
8208 template<typename T, typename String>
8209 using key_function_t =
8210 decltype(std::declval<T&>().key(std::declval<String&>()));
8211
8212 template<typename T>
8213 using end_object_function_t = decltype(std::declval<T&>().end_object());
8214
8215 template<typename T>
8217 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8218
8219 template<typename T>
8220 using end_array_function_t = decltype(std::declval<T&>().end_array());
8221
8222 template<typename T, typename Exception>
8224 std::declval<std::size_t>(), std::declval<const std::string&>(),
8225 std::declval<const Exception&>()));
8226
8227 template<typename SAX, typename BasicJsonType>
8228 struct is_sax
8229 {
8230 private:
8231 static_assert(is_basic_json<BasicJsonType>::value,
8232 "BasicJsonType must be of type basic_json<...>");
8233
8234 using number_integer_t = typename BasicJsonType::number_integer_t;
8235 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8236 using number_float_t = typename BasicJsonType::number_float_t;
8237 using string_t = typename BasicJsonType::string_t;
8238 using binary_t = typename BasicJsonType::binary_t;
8239 using exception_t = typename BasicJsonType::exception;
8240
8241 public:
8242 static constexpr bool value =
8256 };
8257
8258 template<typename SAX, typename BasicJsonType>
8260 {
8261 private:
8262 static_assert(is_basic_json<BasicJsonType>::value,
8263 "BasicJsonType must be of type basic_json<...>");
8264
8265 using number_integer_t = typename BasicJsonType::number_integer_t;
8266 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8267 using number_float_t = typename BasicJsonType::number_float_t;
8268 using string_t = typename BasicJsonType::string_t;
8269 using binary_t = typename BasicJsonType::binary_t;
8270 using exception_t = typename BasicJsonType::exception;
8271
8272 public:
8273 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
8274 "Missing/invalid function: bool null()");
8275 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8276 "Missing/invalid function: bool boolean(bool)");
8277 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8278 "Missing/invalid function: bool boolean(bool)");
8279 static_assert(
8282 "Missing/invalid function: bool number_integer(number_integer_t)");
8283 static_assert(
8286 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8287 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8289 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8290 static_assert(
8292 "Missing/invalid function: bool string(string_t&)");
8293 static_assert(
8295 "Missing/invalid function: bool binary(binary_t&)");
8296 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
8297 "Missing/invalid function: bool start_object(std::size_t)");
8298 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
8299 "Missing/invalid function: bool key(string_t&)");
8300 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
8301 "Missing/invalid function: bool end_object()");
8302 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
8303 "Missing/invalid function: bool start_array(std::size_t)");
8304 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
8305 "Missing/invalid function: bool end_array()");
8306 static_assert(
8308 "Missing/invalid function: bool parse_error(std::size_t, const "
8309 "std::string&, const exception&)");
8310 };
8311 } // namespace detail
8312} // namespace nlohmann
8313
8314// #include <nlohmann/detail/meta/type_traits.hpp>
8315
8316// #include <nlohmann/detail/value_t.hpp>
8317
8318
8319namespace nlohmann
8320{
8321 namespace detail
8322 {
8323
8324 /// how to treat CBOR tags
8326 {
8327 error, ///< throw a parse_error exception in case of a tag
8328 ignore, ///< ignore tags
8329 store ///< store tags as binary type
8330 };
8331
8332 /*!
8333 @brief determine system byte order
8334
8335 @return true if and only if system's byte order is little endian
8336
8337 @note from https://stackoverflow.com/a/1001328/266378
8338 */
8339 static inline bool little_endianess(int num = 1) noexcept
8340 {
8341 return *reinterpret_cast<char*>(&num) == 1;
8342 }
8343
8344
8345 ///////////////////
8346 // binary reader //
8347 ///////////////////
8348
8349 /*!
8350 @brief deserialization of CBOR, MessagePack, and UBJSON values
8351 */
8352 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8354 {
8355 using number_integer_t = typename BasicJsonType::number_integer_t;
8356 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8357 using number_float_t = typename BasicJsonType::number_float_t;
8358 using string_t = typename BasicJsonType::string_t;
8359 using binary_t = typename BasicJsonType::binary_t;
8360 using json_sax_t = SAX;
8361 using char_type = typename InputAdapterType::char_type;
8362 using char_int_type = typename std::char_traits<char_type>::int_type;
8363
8364 public:
8365 /*!
8366 @brief create a binary reader
8367
8368 @param[in] adapter input adapter to read from
8369 */
8370 explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
8371 {
8373 }
8374
8375 // make class move-only
8377 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8379 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8380 ~binary_reader() = default;
8381
8382 /*!
8383 @param[in] format the binary format to parse
8384 @param[in] sax_ a SAX event processor
8385 @param[in] strict whether to expect the input to be consumed completed
8386 @param[in] tag_handler how to treat CBOR tags
8387
8388 @return whether parsing was successful
8389 */
8391 bool sax_parse(const input_format_t format,
8392 json_sax_t* sax_,
8393 const bool strict = true,
8395 {
8396 sax = sax_;
8397 bool result = false;
8398
8399 switch (format)
8400 {
8401 case input_format_t::bson:
8403 break;
8404
8405 case input_format_t::cbor:
8407 break;
8408
8409 case input_format_t::msgpack:
8411 break;
8412
8413 case input_format_t::ubjson:
8415 break;
8416
8417 case input_format_t::json: // LCOV_EXCL_LINE
8418 default: // LCOV_EXCL_LINE
8419 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8420 }
8421
8422 // strict mode: next byte must be EOF
8423 if (result && strict)
8424 {
8426 {
8428 }
8429 else
8430 {
8431 get();
8432 }
8433
8435 {
8437 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
8438 }
8439 }
8440
8441 return result;
8442 }
8443
8444 private:
8445 //////////
8446 // BSON //
8447 //////////
8448
8449 /*!
8450 @brief Reads in a BSON-object and passes it to the SAX-parser.
8451 @return whether a valid BSON-value was passed to the SAX parser
8452 */
8454 {
8457
8459 {
8460 return false;
8461 }
8462
8463 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8464 {
8465 return false;
8466 }
8467
8468 return sax->end_object();
8469 }
8470
8471 /*!
8472 @brief Parses a C-style string from the BSON input.
8473 @param[in,out] result A reference to the string variable where the read
8474 string is to be stored.
8475 @return `true` if the \x00-byte indicating the end of the string was
8476 encountered before the EOF; false` indicates an unexpected EOF.
8477 */
8478 bool get_bson_cstr(string_t& result)
8479 {
8480 auto out = std::back_inserter(result);
8481 while (true)
8482 {
8483 get();
8485 {
8486 return false;
8487 }
8488 if (current == 0x00)
8489 {
8490 return true;
8491 }
8492 *out++ = static_cast<typename string_t::value_type>(current);
8493 }
8494 }
8495
8496 /*!
8497 @brief Parses a zero-terminated string of length @a len from the BSON
8498 input.
8499 @param[in] len The length (including the zero-byte at the end) of the
8500 string to be read.
8501 @param[in,out] result A reference to the string variable where the read
8502 string is to be stored.
8503 @tparam NumberType The type of the length @a len
8504 @pre len >= 1
8505 @return `true` if the string was successfully parsed
8506 */
8507 template<typename NumberType>
8508 bool get_bson_string(const NumberType len, string_t& result)
8509 {
8510 if (JSON_HEDLEY_UNLIKELY(len < 1))
8511 {
8513 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()));
8514 }
8515
8516 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8517 }
8518
8519 /*!
8520 @brief Parses a byte array input of length @a len from the BSON input.
8521 @param[in] len The length of the byte array to be read.
8522 @param[in,out] result A reference to the binary variable where the read
8523 array is to be stored.
8524 @tparam NumberType The type of the length @a len
8525 @pre len >= 0
8526 @return `true` if the byte array was successfully parsed
8527 */
8528 template<typename NumberType>
8529 bool get_bson_binary(const NumberType len, binary_t& result)
8530 {
8531 if (JSON_HEDLEY_UNLIKELY(len < 0))
8532 {
8534 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()));
8535 }
8536
8537 // All BSON binary values have a subtype
8538 std::uint8_t subtype{};
8541
8543 }
8544
8545 /*!
8546 @brief Read a BSON document element of the given @a element_type.
8547 @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
8548 @param[in] element_type_parse_position The position in the input stream,
8549 where the `element_type` was read.
8550 @warning Not all BSON element types are supported yet. An unsupported
8551 @a element_type will give rise to a parse_error.114:
8552 Unsupported BSON record type 0x...
8553 @return whether a valid BSON-object/array was passed to the SAX parser
8554 */
8555 bool parse_bson_element_internal(const char_int_type element_type,
8556 const std::size_t element_type_parse_position)
8557 {
8558 switch (element_type)
8559 {
8560 case 0x01: // double
8561 {
8562 double number{};
8563 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8564 }
8565
8566 case 0x02: // string
8567 {
8568 std::int32_t len{};
8571 }
8572
8573 case 0x03: // object
8574 {
8575 return parse_bson_internal();
8576 }
8577
8578 case 0x04: // array
8579 {
8580 return parse_bson_array();
8581 }
8582
8583 case 0x05: // binary
8584 {
8585 std::int32_t len{};
8588 }
8589
8590 case 0x08: // boolean
8591 {
8592 return sax->boolean(get() != 0);
8593 }
8594
8595 case 0x0A: // null
8596 {
8597 return sax->null();
8598 }
8599
8600 case 0x10: // int32
8601 {
8602 std::int32_t value{};
8604 }
8605
8606 case 0x12: // int64
8607 {
8608 std::int64_t value{};
8610 }
8611
8612 default: // anything else not supported (yet)
8613 {
8614 std::array<char, 3> cr{ {} };
8615 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8616 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()));
8617 }
8618 }
8619 }
8620
8621 /*!
8622 @brief Read a BSON element list (as specified in the BSON-spec)
8623
8624 The same binary layout is used for objects and arrays, hence it must be
8625 indicated with the argument @a is_array which one is expected
8626 (true --> array, false --> object).
8627
8628 @param[in] is_array Determines if the element list being read is to be
8629 treated as an object (@a is_array == false), or as an
8630 array (@a is_array == true).
8631 @return whether a valid BSON-object/array was passed to the SAX parser
8632 */
8633 bool parse_bson_element_list(const bool is_array)
8634 {
8635 string_t key;
8636
8637 while (auto element_type = get())
8638 {
8639 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8640 {
8641 return false;
8642 }
8643
8646 {
8647 return false;
8648 }
8649
8650 if (!is_array && !sax->key(key))
8651 {
8652 return false;
8653 }
8654
8656 {
8657 return false;
8658 }
8659
8660 // get_bson_cstr only appends
8661 key.clear();
8662 }
8663
8664 return true;
8665 }
8666
8667 /*!
8668 @brief Reads an array from the BSON input and passes it to the SAX-parser.
8669 @return whether a valid BSON-array was passed to the SAX parser
8670 */
8672 {
8675
8677 {
8678 return false;
8679 }
8680
8681 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8682 {
8683 return false;
8684 }
8685
8686 return sax->end_array();
8687 }
8688
8689 //////////
8690 // CBOR //
8691 //////////
8692
8693 /*!
8694 @param[in] get_char whether a new character should be retrieved from the
8695 input (true) or whether the last read character should
8696 be considered instead (false)
8697 @param[in] tag_handler how CBOR tags should be treated
8698
8699 @return whether a valid CBOR value was passed to the SAX parser
8700 */
8701 bool parse_cbor_internal(const bool get_char,
8702 const cbor_tag_handler_t tag_handler)
8703 {
8704 switch (get_char ? get() : current)
8705 {
8706 // EOF
8707 case std::char_traits<char_type>::eof():
8708 return unexpect_eof(input_format_t::cbor, "value");
8709
8710 // Integer 0x00..0x17 (0..23)
8711 case 0x00:
8712 case 0x01:
8713 case 0x02:
8714 case 0x03:
8715 case 0x04:
8716 case 0x05:
8717 case 0x06:
8718 case 0x07:
8719 case 0x08:
8720 case 0x09:
8721 case 0x0A:
8722 case 0x0B:
8723 case 0x0C:
8724 case 0x0D:
8725 case 0x0E:
8726 case 0x0F:
8727 case 0x10:
8728 case 0x11:
8729 case 0x12:
8730 case 0x13:
8731 case 0x14:
8732 case 0x15:
8733 case 0x16:
8734 case 0x17:
8735 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8736
8737 case 0x18: // Unsigned integer (one-byte uint8_t follows)
8738 {
8739 std::uint8_t number{};
8741 }
8742
8743 case 0x19: // Unsigned integer (two-byte uint16_t follows)
8744 {
8745 std::uint16_t number{};
8747 }
8748
8749 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8750 {
8751 std::uint32_t number{};
8753 }
8754
8755 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8756 {
8757 std::uint64_t number{};
8759 }
8760
8761 // Negative integer -1-0x00..-1-0x17 (-1..-24)
8762 case 0x20:
8763 case 0x21:
8764 case 0x22:
8765 case 0x23:
8766 case 0x24:
8767 case 0x25:
8768 case 0x26:
8769 case 0x27:
8770 case 0x28:
8771 case 0x29:
8772 case 0x2A:
8773 case 0x2B:
8774 case 0x2C:
8775 case 0x2D:
8776 case 0x2E:
8777 case 0x2F:
8778 case 0x30:
8779 case 0x31:
8780 case 0x32:
8781 case 0x33:
8782 case 0x34:
8783 case 0x35:
8784 case 0x36:
8785 case 0x37:
8786 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8787
8788 case 0x38: // Negative integer (one-byte uint8_t follows)
8789 {
8790 std::uint8_t number{};
8792 }
8793
8794 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8795 {
8796 std::uint16_t number{};
8798 }
8799
8800 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8801 {
8802 std::uint32_t number{};
8804 }
8805
8806 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8807 {
8808 std::uint64_t number{};
8810 - static_cast<number_integer_t>(number));
8811 }
8812
8813 // Binary data (0x00..0x17 bytes follow)
8814 case 0x40:
8815 case 0x41:
8816 case 0x42:
8817 case 0x43:
8818 case 0x44:
8819 case 0x45:
8820 case 0x46:
8821 case 0x47:
8822 case 0x48:
8823 case 0x49:
8824 case 0x4A:
8825 case 0x4B:
8826 case 0x4C:
8827 case 0x4D:
8828 case 0x4E:
8829 case 0x4F:
8830 case 0x50:
8831 case 0x51:
8832 case 0x52:
8833 case 0x53:
8834 case 0x54:
8835 case 0x55:
8836 case 0x56:
8837 case 0x57:
8838 case 0x58: // Binary data (one-byte uint8_t for n follows)
8839 case 0x59: // Binary data (two-byte uint16_t for n follow)
8840 case 0x5A: // Binary data (four-byte uint32_t for n follow)
8841 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8842 case 0x5F: // Binary data (indefinite length)
8843 {
8844 binary_t b;
8845 return get_cbor_binary(b) && sax->binary(b);
8846 }
8847
8848 // UTF-8 string (0x00..0x17 bytes follow)
8849 case 0x60:
8850 case 0x61:
8851 case 0x62:
8852 case 0x63:
8853 case 0x64:
8854 case 0x65:
8855 case 0x66:
8856 case 0x67:
8857 case 0x68:
8858 case 0x69:
8859 case 0x6A:
8860 case 0x6B:
8861 case 0x6C:
8862 case 0x6D:
8863 case 0x6E:
8864 case 0x6F:
8865 case 0x70:
8866 case 0x71:
8867 case 0x72:
8868 case 0x73:
8869 case 0x74:
8870 case 0x75:
8871 case 0x76:
8872 case 0x77:
8873 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8874 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8875 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8876 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8877 case 0x7F: // UTF-8 string (indefinite length)
8878 {
8879 string_t s;
8880 return get_cbor_string(s) && sax->string(s);
8881 }
8882
8883 // array (0x00..0x17 data items follow)
8884 case 0x80:
8885 case 0x81:
8886 case 0x82:
8887 case 0x83:
8888 case 0x84:
8889 case 0x85:
8890 case 0x86:
8891 case 0x87:
8892 case 0x88:
8893 case 0x89:
8894 case 0x8A:
8895 case 0x8B:
8896 case 0x8C:
8897 case 0x8D:
8898 case 0x8E:
8899 case 0x8F:
8900 case 0x90:
8901 case 0x91:
8902 case 0x92:
8903 case 0x93:
8904 case 0x94:
8905 case 0x95:
8906 case 0x96:
8907 case 0x97:
8908 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8909
8910 case 0x98: // array (one-byte uint8_t for n follows)
8911 {
8912 std::uint8_t len{};
8914 }
8915
8916 case 0x99: // array (two-byte uint16_t for n follow)
8917 {
8918 std::uint16_t len{};
8920 }
8921
8922 case 0x9A: // array (four-byte uint32_t for n follow)
8923 {
8924 std::uint32_t len{};
8926 }
8927
8928 case 0x9B: // array (eight-byte uint64_t for n follow)
8929 {
8930 std::uint64_t len{};
8932 }
8933
8934 case 0x9F: // array (indefinite length)
8935 return get_cbor_array(std::size_t(-1), tag_handler);
8936
8937 // map (0x00..0x17 pairs of data items follow)
8938 case 0xA0:
8939 case 0xA1:
8940 case 0xA2:
8941 case 0xA3:
8942 case 0xA4:
8943 case 0xA5:
8944 case 0xA6:
8945 case 0xA7:
8946 case 0xA8:
8947 case 0xA9:
8948 case 0xAA:
8949 case 0xAB:
8950 case 0xAC:
8951 case 0xAD:
8952 case 0xAE:
8953 case 0xAF:
8954 case 0xB0:
8955 case 0xB1:
8956 case 0xB2:
8957 case 0xB3:
8958 case 0xB4:
8959 case 0xB5:
8960 case 0xB6:
8961 case 0xB7:
8962 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8963
8964 case 0xB8: // map (one-byte uint8_t for n follows)
8965 {
8966 std::uint8_t len{};
8968 }
8969
8970 case 0xB9: // map (two-byte uint16_t for n follow)
8971 {
8972 std::uint16_t len{};
8974 }
8975
8976 case 0xBA: // map (four-byte uint32_t for n follow)
8977 {
8978 std::uint32_t len{};
8980 }
8981
8982 case 0xBB: // map (eight-byte uint64_t for n follow)
8983 {
8984 std::uint64_t len{};
8986 }
8987
8988 case 0xBF: // map (indefinite length)
8989 return get_cbor_object(std::size_t(-1), tag_handler);
8990
8991 case 0xC6: // tagged item
8992 case 0xC7:
8993 case 0xC8:
8994 case 0xC9:
8995 case 0xCA:
8996 case 0xCB:
8997 case 0xCC:
8998 case 0xCD:
8999 case 0xCE:
9000 case 0xCF:
9001 case 0xD0:
9002 case 0xD1:
9003 case 0xD2:
9004 case 0xD3:
9005 case 0xD4:
9006 case 0xD8: // tagged item (1 bytes follow)
9007 case 0xD9: // tagged item (2 bytes follow)
9008 case 0xDA: // tagged item (4 bytes follow)
9009 case 0xDB: // tagged item (8 bytes follow)
9010 {
9011 switch (tag_handler)
9012 {
9014 {
9017 }
9018
9020 {
9021 // ignore binary subtype
9022 switch (current)
9023 {
9024 case 0xD8:
9025 {
9028 break;
9029 }
9030 case 0xD9:
9031 {
9034 break;
9035 }
9036 case 0xDA:
9037 {
9040 break;
9041 }
9042 case 0xDB:
9043 {
9046 break;
9047 }
9048 default:
9049 break;
9050 }
9051 return parse_cbor_internal(true, tag_handler);
9052 }
9053
9055 {
9056 binary_t b;
9057 // use binary subtype and store in binary container
9058 switch (current)
9059 {
9060 case 0xD8:
9061 {
9062 std::uint8_t subtype{};
9065 break;
9066 }
9067 case 0xD9:
9068 {
9069 std::uint16_t subtype{};
9072 break;
9073 }
9074 case 0xDA:
9075 {
9076 std::uint32_t subtype{};
9079 break;
9080 }
9081 case 0xDB:
9082 {
9083 std::uint64_t subtype{};
9086 break;
9087 }
9088 default:
9089 return parse_cbor_internal(true, tag_handler);
9090 }
9091 get();
9092 return get_cbor_binary(b) && sax->binary(b);
9093 }
9094
9095 default: // LCOV_EXCL_LINE
9096 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9097 return false; // LCOV_EXCL_LINE
9098 }
9099 }
9100
9101 case 0xF4: // false
9102 return sax->boolean(false);
9103
9104 case 0xF5: // true
9105 return sax->boolean(true);
9106
9107 case 0xF6: // null
9108 return sax->null();
9109
9110 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9111 {
9112 const auto byte1_raw = get();
9114 {
9115 return false;
9116 }
9117 const auto byte2_raw = get();
9119 {
9120 return false;
9121 }
9122
9123 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9124 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9125
9126 // code from RFC 7049, Appendix D, Figure 3:
9127 // As half-precision floating-point numbers were only added
9128 // to IEEE 754 in 2008, today's programming platforms often
9129 // still only have limited support for them. It is very
9130 // easy to include at least decoding support for them even
9131 // without such support. An example of a small decoder for
9132 // half-precision floating-point numbers in the C language
9133 // is shown in Fig. 3.
9134 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9135 const double val = [&half]
9136 {
9137 const int exp = (half >> 10u) & 0x1Fu;
9138 const unsigned int mant = half & 0x3FFu;
9139 JSON_ASSERT(0 <= exp && exp <= 32);
9140 JSON_ASSERT(mant <= 1024);
9141 switch (exp)
9142 {
9143 case 0:
9144 return std::ldexp(mant, -24);
9145 case 31:
9146 return (mant == 0)
9147 ? std::numeric_limits<double>::infinity()
9148 : std::numeric_limits<double>::quiet_NaN();
9149 default:
9150 return std::ldexp(mant + 1024, exp - 25);
9151 }
9152 }();
9153 return sax->number_float((half & 0x8000u) != 0
9154 ? static_cast<number_float_t>(-val)
9155 : static_cast<number_float_t>(val), "");
9156 }
9157
9158 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9159 {
9160 float number{};
9161 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9162 }
9163
9164 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9165 {
9166 double number{};
9167 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9168 }
9169
9170 default: // anything else (0xFF is handled inside the other types)
9171 {
9174 }
9175 }
9176 }
9177
9178 /*!
9179 @brief reads a CBOR string
9180
9181 This function first reads starting bytes to determine the expected
9182 string length and then copies this number of bytes into a string.
9183 Additionally, CBOR's strings with indefinite lengths are supported.
9184
9185 @param[out] result created string
9186
9187 @return whether string creation completed
9188 */
9189 bool get_cbor_string(string_t& result)
9190 {
9192 {
9193 return false;
9194 }
9195
9196 switch (current)
9197 {
9198 // UTF-8 string (0x00..0x17 bytes follow)
9199 case 0x60:
9200 case 0x61:
9201 case 0x62:
9202 case 0x63:
9203 case 0x64:
9204 case 0x65:
9205 case 0x66:
9206 case 0x67:
9207 case 0x68:
9208 case 0x69:
9209 case 0x6A:
9210 case 0x6B:
9211 case 0x6C:
9212 case 0x6D:
9213 case 0x6E:
9214 case 0x6F:
9215 case 0x70:
9216 case 0x71:
9217 case 0x72:
9218 case 0x73:
9219 case 0x74:
9220 case 0x75:
9221 case 0x76:
9222 case 0x77:
9223 {
9224 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9225 }
9226
9227 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9228 {
9229 std::uint8_t len{};
9231 }
9232
9233 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9234 {
9235 std::uint16_t len{};
9237 }
9238
9239 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9240 {
9241 std::uint32_t len{};
9243 }
9244
9245 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9246 {
9247 std::uint64_t len{};
9249 }
9250
9251 case 0x7F: // UTF-8 string (indefinite length)
9252 {
9253 while (get() != 0xFF)
9254 {
9256 if (!get_cbor_string(chunk))
9257 {
9258 return false;
9259 }
9261 }
9262 return true;
9263 }
9264
9265 default:
9266 {
9268 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()));
9269 }
9270 }
9271 }
9272
9273 /*!
9274 @brief reads a CBOR byte array
9275
9276 This function first reads starting bytes to determine the expected
9277 byte array length and then copies this number of bytes into the byte array.
9278 Additionally, CBOR's byte arrays with indefinite lengths are supported.
9279
9280 @param[out] result created byte array
9281
9282 @return whether byte array creation completed
9283 */
9284 bool get_cbor_binary(binary_t& result)
9285 {
9287 {
9288 return false;
9289 }
9290
9291 switch (current)
9292 {
9293 // Binary data (0x00..0x17 bytes follow)
9294 case 0x40:
9295 case 0x41:
9296 case 0x42:
9297 case 0x43:
9298 case 0x44:
9299 case 0x45:
9300 case 0x46:
9301 case 0x47:
9302 case 0x48:
9303 case 0x49:
9304 case 0x4A:
9305 case 0x4B:
9306 case 0x4C:
9307 case 0x4D:
9308 case 0x4E:
9309 case 0x4F:
9310 case 0x50:
9311 case 0x51:
9312 case 0x52:
9313 case 0x53:
9314 case 0x54:
9315 case 0x55:
9316 case 0x56:
9317 case 0x57:
9318 {
9319 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9320 }
9321
9322 case 0x58: // Binary data (one-byte uint8_t for n follows)
9323 {
9324 std::uint8_t len{};
9325 return get_number(input_format_t::cbor, len) &&
9327 }
9328
9329 case 0x59: // Binary data (two-byte uint16_t for n follow)
9330 {
9331 std::uint16_t len{};
9332 return get_number(input_format_t::cbor, len) &&
9334 }
9335
9336 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9337 {
9338 std::uint32_t len{};
9339 return get_number(input_format_t::cbor, len) &&
9341 }
9342
9343 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9344 {
9345 std::uint64_t len{};
9346 return get_number(input_format_t::cbor, len) &&
9348 }
9349
9350 case 0x5F: // Binary data (indefinite length)
9351 {
9352 while (get() != 0xFF)
9353 {
9355 if (!get_cbor_binary(chunk))
9356 {
9357 return false;
9358 }
9360 }
9361 return true;
9362 }
9363
9364 default:
9365 {
9367 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()));
9368 }
9369 }
9370 }
9371
9372 /*!
9373 @param[in] len the length of the array or std::size_t(-1) for an
9374 array of indefinite size
9375 @param[in] tag_handler how CBOR tags should be treated
9376 @return whether array creation completed
9377 */
9378 bool get_cbor_array(const std::size_t len,
9379 const cbor_tag_handler_t tag_handler)
9380 {
9382 {
9383 return false;
9384 }
9385
9386 if (len != std::size_t(-1))
9387 {
9388 for (std::size_t i = 0; i < len; ++i)
9389 {
9391 {
9392 return false;
9393 }
9394 }
9395 }
9396 else
9397 {
9398 while (get() != 0xFF)
9399 {
9401 {
9402 return false;
9403 }
9404 }
9405 }
9406
9407 return sax->end_array();
9408 }
9409
9410 /*!
9411 @param[in] len the length of the object or std::size_t(-1) for an
9412 object of indefinite size
9413 @param[in] tag_handler how CBOR tags should be treated
9414 @return whether object creation completed
9415 */
9416 bool get_cbor_object(const std::size_t len,
9417 const cbor_tag_handler_t tag_handler)
9418 {
9420 {
9421 return false;
9422 }
9423
9424 if (len != 0)
9425 {
9426 string_t key;
9427 if (len != std::size_t(-1))
9428 {
9429 for (std::size_t i = 0; i < len; ++i)
9430 {
9431 get();
9433 {
9434 return false;
9435 }
9436
9438 {
9439 return false;
9440 }
9441 key.clear();
9442 }
9443 }
9444 else
9445 {
9446 while (get() != 0xFF)
9447 {
9449 {
9450 return false;
9451 }
9452
9454 {
9455 return false;
9456 }
9457 key.clear();
9458 }
9459 }
9460 }
9461
9462 return sax->end_object();
9463 }
9464
9465 /////////////
9466 // MsgPack //
9467 /////////////
9468
9469 /*!
9470 @return whether a valid MessagePack value was passed to the SAX parser
9471 */
9473 {
9474 switch (get())
9475 {
9476 // EOF
9477 case std::char_traits<char_type>::eof():
9478 return unexpect_eof(input_format_t::msgpack, "value");
9479
9480 // positive fixint
9481 case 0x00:
9482 case 0x01:
9483 case 0x02:
9484 case 0x03:
9485 case 0x04:
9486 case 0x05:
9487 case 0x06:
9488 case 0x07:
9489 case 0x08:
9490 case 0x09:
9491 case 0x0A:
9492 case 0x0B:
9493 case 0x0C:
9494 case 0x0D:
9495 case 0x0E:
9496 case 0x0F:
9497 case 0x10:
9498 case 0x11:
9499 case 0x12:
9500 case 0x13:
9501 case 0x14:
9502 case 0x15:
9503 case 0x16:
9504 case 0x17:
9505 case 0x18:
9506 case 0x19:
9507 case 0x1A:
9508 case 0x1B:
9509 case 0x1C:
9510 case 0x1D:
9511 case 0x1E:
9512 case 0x1F:
9513 case 0x20:
9514 case 0x21:
9515 case 0x22:
9516 case 0x23:
9517 case 0x24:
9518 case 0x25:
9519 case 0x26:
9520 case 0x27:
9521 case 0x28:
9522 case 0x29:
9523 case 0x2A:
9524 case 0x2B:
9525 case 0x2C:
9526 case 0x2D:
9527 case 0x2E:
9528 case 0x2F:
9529 case 0x30:
9530 case 0x31:
9531 case 0x32:
9532 case 0x33:
9533 case 0x34:
9534 case 0x35:
9535 case 0x36:
9536 case 0x37:
9537 case 0x38:
9538 case 0x39:
9539 case 0x3A:
9540 case 0x3B:
9541 case 0x3C:
9542 case 0x3D:
9543 case 0x3E:
9544 case 0x3F:
9545 case 0x40:
9546 case 0x41:
9547 case 0x42:
9548 case 0x43:
9549 case 0x44:
9550 case 0x45:
9551 case 0x46:
9552 case 0x47:
9553 case 0x48:
9554 case 0x49:
9555 case 0x4A:
9556 case 0x4B:
9557 case 0x4C:
9558 case 0x4D:
9559 case 0x4E:
9560 case 0x4F:
9561 case 0x50:
9562 case 0x51:
9563 case 0x52:
9564 case 0x53:
9565 case 0x54:
9566 case 0x55:
9567 case 0x56:
9568 case 0x57:
9569 case 0x58:
9570 case 0x59:
9571 case 0x5A:
9572 case 0x5B:
9573 case 0x5C:
9574 case 0x5D:
9575 case 0x5E:
9576 case 0x5F:
9577 case 0x60:
9578 case 0x61:
9579 case 0x62:
9580 case 0x63:
9581 case 0x64:
9582 case 0x65:
9583 case 0x66:
9584 case 0x67:
9585 case 0x68:
9586 case 0x69:
9587 case 0x6A:
9588 case 0x6B:
9589 case 0x6C:
9590 case 0x6D:
9591 case 0x6E:
9592 case 0x6F:
9593 case 0x70:
9594 case 0x71:
9595 case 0x72:
9596 case 0x73:
9597 case 0x74:
9598 case 0x75:
9599 case 0x76:
9600 case 0x77:
9601 case 0x78:
9602 case 0x79:
9603 case 0x7A:
9604 case 0x7B:
9605 case 0x7C:
9606 case 0x7D:
9607 case 0x7E:
9608 case 0x7F:
9609 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9610
9611 // fixmap
9612 case 0x80:
9613 case 0x81:
9614 case 0x82:
9615 case 0x83:
9616 case 0x84:
9617 case 0x85:
9618 case 0x86:
9619 case 0x87:
9620 case 0x88:
9621 case 0x89:
9622 case 0x8A:
9623 case 0x8B:
9624 case 0x8C:
9625 case 0x8D:
9626 case 0x8E:
9627 case 0x8F:
9628 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9629
9630 // fixarray
9631 case 0x90:
9632 case 0x91:
9633 case 0x92:
9634 case 0x93:
9635 case 0x94:
9636 case 0x95:
9637 case 0x96:
9638 case 0x97:
9639 case 0x98:
9640 case 0x99:
9641 case 0x9A:
9642 case 0x9B:
9643 case 0x9C:
9644 case 0x9D:
9645 case 0x9E:
9646 case 0x9F:
9647 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9648
9649 // fixstr
9650 case 0xA0:
9651 case 0xA1:
9652 case 0xA2:
9653 case 0xA3:
9654 case 0xA4:
9655 case 0xA5:
9656 case 0xA6:
9657 case 0xA7:
9658 case 0xA8:
9659 case 0xA9:
9660 case 0xAA:
9661 case 0xAB:
9662 case 0xAC:
9663 case 0xAD:
9664 case 0xAE:
9665 case 0xAF:
9666 case 0xB0:
9667 case 0xB1:
9668 case 0xB2:
9669 case 0xB3:
9670 case 0xB4:
9671 case 0xB5:
9672 case 0xB6:
9673 case 0xB7:
9674 case 0xB8:
9675 case 0xB9:
9676 case 0xBA:
9677 case 0xBB:
9678 case 0xBC:
9679 case 0xBD:
9680 case 0xBE:
9681 case 0xBF:
9682 case 0xD9: // str 8
9683 case 0xDA: // str 16
9684 case 0xDB: // str 32
9685 {
9686 string_t s;
9687 return get_msgpack_string(s) && sax->string(s);
9688 }
9689
9690 case 0xC0: // nil
9691 return sax->null();
9692
9693 case 0xC2: // false
9694 return sax->boolean(false);
9695
9696 case 0xC3: // true
9697 return sax->boolean(true);
9698
9699 case 0xC4: // bin 8
9700 case 0xC5: // bin 16
9701 case 0xC6: // bin 32
9702 case 0xC7: // ext 8
9703 case 0xC8: // ext 16
9704 case 0xC9: // ext 32
9705 case 0xD4: // fixext 1
9706 case 0xD5: // fixext 2
9707 case 0xD6: // fixext 4
9708 case 0xD7: // fixext 8
9709 case 0xD8: // fixext 16
9710 {
9711 binary_t b;
9712 return get_msgpack_binary(b) && sax->binary(b);
9713 }
9714
9715 case 0xCA: // float 32
9716 {
9717 float number{};
9719 }
9720
9721 case 0xCB: // float 64
9722 {
9723 double number{};
9725 }
9726
9727 case 0xCC: // uint 8
9728 {
9729 std::uint8_t number{};
9731 }
9732
9733 case 0xCD: // uint 16
9734 {
9735 std::uint16_t number{};
9737 }
9738
9739 case 0xCE: // uint 32
9740 {
9741 std::uint32_t number{};
9743 }
9744
9745 case 0xCF: // uint 64
9746 {
9747 std::uint64_t number{};
9749 }
9750
9751 case 0xD0: // int 8
9752 {
9753 std::int8_t number{};
9755 }
9756
9757 case 0xD1: // int 16
9758 {
9759 std::int16_t number{};
9761 }
9762
9763 case 0xD2: // int 32
9764 {
9765 std::int32_t number{};
9767 }
9768
9769 case 0xD3: // int 64
9770 {
9771 std::int64_t number{};
9773 }
9774
9775 case 0xDC: // array 16
9776 {
9777 std::uint16_t len{};
9778 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9779 }
9780
9781 case 0xDD: // array 32
9782 {
9783 std::uint32_t len{};
9784 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9785 }
9786
9787 case 0xDE: // map 16
9788 {
9789 std::uint16_t len{};
9790 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9791 }
9792
9793 case 0xDF: // map 32
9794 {
9795 std::uint32_t len{};
9796 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9797 }
9798
9799 // negative fixint
9800 case 0xE0:
9801 case 0xE1:
9802 case 0xE2:
9803 case 0xE3:
9804 case 0xE4:
9805 case 0xE5:
9806 case 0xE6:
9807 case 0xE7:
9808 case 0xE8:
9809 case 0xE9:
9810 case 0xEA:
9811 case 0xEB:
9812 case 0xEC:
9813 case 0xED:
9814 case 0xEE:
9815 case 0xEF:
9816 case 0xF0:
9817 case 0xF1:
9818 case 0xF2:
9819 case 0xF3:
9820 case 0xF4:
9821 case 0xF5:
9822 case 0xF6:
9823 case 0xF7:
9824 case 0xF8:
9825 case 0xF9:
9826 case 0xFA:
9827 case 0xFB:
9828 case 0xFC:
9829 case 0xFD:
9830 case 0xFE:
9831 case 0xFF:
9832 return sax->number_integer(static_cast<std::int8_t>(current));
9833
9834 default: // anything else
9835 {
9838 }
9839 }
9840 }
9841
9842 /*!
9843 @brief reads a MessagePack string
9844
9845 This function first reads starting bytes to determine the expected
9846 string length and then copies this number of bytes into a string.
9847
9848 @param[out] result created string
9849
9850 @return whether string creation completed
9851 */
9852 bool get_msgpack_string(string_t& result)
9853 {
9855 {
9856 return false;
9857 }
9858
9859 switch (current)
9860 {
9861 // fixstr
9862 case 0xA0:
9863 case 0xA1:
9864 case 0xA2:
9865 case 0xA3:
9866 case 0xA4:
9867 case 0xA5:
9868 case 0xA6:
9869 case 0xA7:
9870 case 0xA8:
9871 case 0xA9:
9872 case 0xAA:
9873 case 0xAB:
9874 case 0xAC:
9875 case 0xAD:
9876 case 0xAE:
9877 case 0xAF:
9878 case 0xB0:
9879 case 0xB1:
9880 case 0xB2:
9881 case 0xB3:
9882 case 0xB4:
9883 case 0xB5:
9884 case 0xB6:
9885 case 0xB7:
9886 case 0xB8:
9887 case 0xB9:
9888 case 0xBA:
9889 case 0xBB:
9890 case 0xBC:
9891 case 0xBD:
9892 case 0xBE:
9893 case 0xBF:
9894 {
9895 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9896 }
9897
9898 case 0xD9: // str 8
9899 {
9900 std::uint8_t len{};
9902 }
9903
9904 case 0xDA: // str 16
9905 {
9906 std::uint16_t len{};
9908 }
9909
9910 case 0xDB: // str 32
9911 {
9912 std::uint32_t len{};
9914 }
9915
9916 default:
9917 {
9919 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()));
9920 }
9921 }
9922 }
9923
9924 /*!
9925 @brief reads a MessagePack byte array
9926
9927 This function first reads starting bytes to determine the expected
9928 byte array length and then copies this number of bytes into a byte array.
9929
9930 @param[out] result created byte array
9931
9932 @return whether byte array creation completed
9933 */
9934 bool get_msgpack_binary(binary_t& result)
9935 {
9936 // helper function to set the subtype
9938 {
9939 result.set_subtype(static_cast<std::uint8_t>(subtype));
9940 return true;
9941 };
9942
9943 switch (current)
9944 {
9945 case 0xC4: // bin 8
9946 {
9947 std::uint8_t len{};
9950 }
9951
9952 case 0xC5: // bin 16
9953 {
9954 std::uint16_t len{};
9957 }
9958
9959 case 0xC6: // bin 32
9960 {
9961 std::uint32_t len{};
9964 }
9965
9966 case 0xC7: // ext 8
9967 {
9968 std::uint8_t len{};
9969 std::int8_t subtype{};
9974 }
9975
9976 case 0xC8: // ext 16
9977 {
9978 std::uint16_t len{};
9979 std::int8_t subtype{};
9984 }
9985
9986 case 0xC9: // ext 32
9987 {
9988 std::uint32_t len{};
9989 std::int8_t subtype{};
9994 }
9995
9996 case 0xD4: // fixext 1
9997 {
9998 std::int8_t subtype{};
10002 }
10003
10004 case 0xD5: // fixext 2
10005 {
10006 std::int8_t subtype{};
10010 }
10011
10012 case 0xD6: // fixext 4
10013 {
10014 std::int8_t subtype{};
10018 }
10019
10020 case 0xD7: // fixext 8
10021 {
10022 std::int8_t subtype{};
10026 }
10027
10028 case 0xD8: // fixext 16
10029 {
10030 std::int8_t subtype{};
10034 }
10035
10036 default: // LCOV_EXCL_LINE
10037 return false; // LCOV_EXCL_LINE
10038 }
10039 }
10040
10041 /*!
10042 @param[in] len the length of the array
10043 @return whether array creation completed
10044 */
10045 bool get_msgpack_array(const std::size_t len)
10046 {
10048 {
10049 return false;
10050 }
10051
10052 for (std::size_t i = 0; i < len; ++i)
10053 {
10055 {
10056 return false;
10057 }
10058 }
10059
10060 return sax->end_array();
10061 }
10062
10063 /*!
10064 @param[in] len the length of the object
10065 @return whether object creation completed
10066 */
10067 bool get_msgpack_object(const std::size_t len)
10068 {
10070 {
10071 return false;
10072 }
10073
10074 string_t key;
10075 for (std::size_t i = 0; i < len; ++i)
10076 {
10077 get();
10079 {
10080 return false;
10081 }
10082
10084 {
10085 return false;
10086 }
10087 key.clear();
10088 }
10089
10090 return sax->end_object();
10091 }
10092
10093 ////////////
10094 // UBJSON //
10095 ////////////
10096
10097 /*!
10098 @param[in] get_char whether a new character should be retrieved from the
10099 input (true, default) or whether the last read
10100 character should be considered instead
10101
10102 @return whether a valid UBJSON value was passed to the SAX parser
10103 */
10104 bool parse_ubjson_internal(const bool get_char = true)
10105 {
10107 }
10108
10109 /*!
10110 @brief reads a UBJSON string
10111
10112 This function is either called after reading the 'S' byte explicitly
10113 indicating a string, or in case of an object key where the 'S' byte can be
10114 left out.
10115
10116 @param[out] result created string
10117 @param[in] get_char whether a new character should be retrieved from the
10118 input (true, default) or whether the last read
10119 character should be considered instead
10120
10121 @return whether string creation completed
10122 */
10123 bool get_ubjson_string(string_t& result, const bool get_char = true)
10124 {
10125 if (get_char)
10126 {
10127 get(); // TODO(niels): may we ignore N here?
10128 }
10129
10131 {
10132 return false;
10133 }
10134
10135 switch (current)
10136 {
10137 case 'U':
10138 {
10139 std::uint8_t len{};
10141 }
10142
10143 case 'i':
10144 {
10145 std::int8_t len{};
10147 }
10148
10149 case 'I':
10150 {
10151 std::int16_t len{};
10153 }
10154
10155 case 'l':
10156 {
10157 std::int32_t len{};
10159 }
10160
10161 case 'L':
10162 {
10163 std::int64_t len{};
10165 }
10166
10167 default:
10169 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()));
10170 }
10171 }
10172
10173 /*!
10174 @param[out] result determined size
10175 @return whether size determination completed
10176 */
10177 bool get_ubjson_size_value(std::size_t& result)
10178 {
10179 switch (get_ignore_noop())
10180 {
10181 case 'U':
10182 {
10183 std::uint8_t number{};
10185 {
10186 return false;
10187 }
10188 result = static_cast<std::size_t>(number);
10189 return true;
10190 }
10191
10192 case 'i':
10193 {
10194 std::int8_t number{};
10196 {
10197 return false;
10198 }
10199 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10200 return true;
10201 }
10202
10203 case 'I':
10204 {
10205 std::int16_t number{};
10207 {
10208 return false;
10209 }
10210 result = static_cast<std::size_t>(number);
10211 return true;
10212 }
10213
10214 case 'l':
10215 {
10216 std::int32_t number{};
10218 {
10219 return false;
10220 }
10221 result = static_cast<std::size_t>(number);
10222 return true;
10223 }
10224
10225 case 'L':
10226 {
10227 std::int64_t number{};
10229 {
10230 return false;
10231 }
10232 result = static_cast<std::size_t>(number);
10233 return true;
10234 }
10235
10236 default:
10237 {
10239 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()));
10240 }
10241 }
10242 }
10243
10244 /*!
10245 @brief determine the type and size for a container
10246
10247 In the optimized UBJSON format, a type and a size can be provided to allow
10248 for a more compact representation.
10249
10250 @param[out] result pair of the size and the type
10251
10252 @return whether pair creation completed
10253 */
10254 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
10255 {
10256 result.first = string_t::npos; // size
10257 result.second = 0; // type
10258
10260
10261 if (current == '$')
10262 {
10263 result.second = get(); // must not ignore 'N', because 'N' maybe the type
10265 {
10266 return false;
10267 }
10268
10270 if (JSON_HEDLEY_UNLIKELY(current != '#'))
10271 {
10273 {
10274 return false;
10275 }
10277 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()));
10278 }
10279
10281 }
10282
10283 if (current == '#')
10284 {
10286 }
10287
10288 return true;
10289 }
10290
10291 /*!
10292 @param prefix the previously read or set type prefix
10293 @return whether value creation completed
10294 */
10295 bool get_ubjson_value(const char_int_type prefix)
10296 {
10297 switch (prefix)
10298 {
10299 case std::char_traits<char_type>::eof(): // EOF
10300 return unexpect_eof(input_format_t::ubjson, "value");
10301
10302 case 'T': // true
10303 return sax->boolean(true);
10304 case 'F': // false
10305 return sax->boolean(false);
10306
10307 case 'Z': // null
10308 return sax->null();
10309
10310 case 'U':
10311 {
10312 std::uint8_t number{};
10314 }
10315
10316 case 'i':
10317 {
10318 std::int8_t number{};
10320 }
10321
10322 case 'I':
10323 {
10324 std::int16_t number{};
10326 }
10327
10328 case 'l':
10329 {
10330 std::int32_t number{};
10332 }
10333
10334 case 'L':
10335 {
10336 std::int64_t number{};
10338 }
10339
10340 case 'd':
10341 {
10342 float number{};
10344 }
10345
10346 case 'D':
10347 {
10348 double number{};
10350 }
10351
10352 case 'H':
10353 {
10355 }
10356
10357 case 'C': // char
10358 {
10359 get();
10361 {
10362 return false;
10363 }
10364 if (JSON_HEDLEY_UNLIKELY(current > 127))
10365 {
10367 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()));
10368 }
10369 string_t s(1, static_cast<typename string_t::value_type>(current));
10370 return sax->string(s);
10371 }
10372
10373 case 'S': // string
10374 {
10375 string_t s;
10376 return get_ubjson_string(s) && sax->string(s);
10377 }
10378
10379 case '[': // array
10380 return get_ubjson_array();
10381
10382 case '{': // object
10383 return get_ubjson_object();
10384
10385 default: // anything else
10386 {
10389 }
10390 }
10391 }
10392
10393 /*!
10394 @return whether array creation completed
10395 */
10397 {
10400 {
10401 return false;
10402 }
10403
10405 {
10407 {
10408 return false;
10409 }
10410
10411 if (size_and_type.second != 0)
10412 {
10413 if (size_and_type.second != 'N')
10414 {
10415 for (std::size_t i = 0; i < size_and_type.first; ++i)
10416 {
10418 {
10419 return false;
10420 }
10421 }
10422 }
10423 }
10424 else
10425 {
10426 for (std::size_t i = 0; i < size_and_type.first; ++i)
10427 {
10429 {
10430 return false;
10431 }
10432 }
10433 }
10434 }
10435 else
10436 {
10438 {
10439 return false;
10440 }
10441
10442 while (current != ']')
10443 {
10445 {
10446 return false;
10447 }
10449 }
10450 }
10451
10452 return sax->end_array();
10453 }
10454
10455 /*!
10456 @return whether object creation completed
10457 */
10459 {
10462 {
10463 return false;
10464 }
10465
10466 string_t key;
10468 {
10470 {
10471 return false;
10472 }
10473
10474 if (size_and_type.second != 0)
10475 {
10476 for (std::size_t i = 0; i < size_and_type.first; ++i)
10477 {
10479 {
10480 return false;
10481 }
10483 {
10484 return false;
10485 }
10486 key.clear();
10487 }
10488 }
10489 else
10490 {
10491 for (std::size_t i = 0; i < size_and_type.first; ++i)
10492 {
10494 {
10495 return false;
10496 }
10498 {
10499 return false;
10500 }
10501 key.clear();
10502 }
10503 }
10504 }
10505 else
10506 {
10508 {
10509 return false;
10510 }
10511
10512 while (current != '}')
10513 {
10515 {
10516 return false;
10517 }
10519 {
10520 return false;
10521 }
10523 key.clear();
10524 }
10525 }
10526
10527 return sax->end_object();
10528 }
10529
10530 // Note, no reader for UBJSON binary types is implemented because they do
10531 // not exist
10532
10534 {
10535 // get size of following number string
10536 std::size_t size{};
10539 {
10540 return res;
10541 }
10542
10543 // get number string
10544 std::vector<char> number_vector;
10545 for (std::size_t i = 0; i < size; ++i)
10546 {
10547 get();
10549 {
10550 return false;
10551 }
10552 number_vector.push_back(static_cast<char>(current));
10553 }
10554
10555 // parse number string
10556 using ia_type = decltype(detail::input_adapter(number_vector));
10558 const auto result_number = number_lexer.scan();
10560 const auto result_remainder = number_lexer.scan();
10561
10563
10565 {
10566 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()));
10567 }
10568
10569 switch (result_number)
10570 {
10575 case token_type::value_float:
10582 case token_type::begin_array:
10584 case token_type::end_array:
10585 case token_type::end_object:
10588 case token_type::parse_error:
10591 default:
10592 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()));
10593 }
10594 }
10595
10596 ///////////////////////
10597 // Utility functions //
10598 ///////////////////////
10599
10600 /*!
10601 @brief get next character from the input
10602
10603 This function provides the interface to the used input adapter. It does
10604 not throw in case the input reached EOF, but returns a -'ve valued
10605 `std::char_traits<char_type>::eof()` in that case.
10606
10607 @return character read from the input
10608 */
10609 char_int_type get()
10610 {
10611 ++chars_read;
10612 return current = ia.get_character();
10613 }
10614
10615 /*!
10616 @return character read from the input after ignoring all 'N' entries
10617 */
10618 char_int_type get_ignore_noop()
10619 {
10620 do
10621 {
10622 get();
10623 } while (current == 'N');
10624
10625 return current;
10626 }
10627
10628 /*
10629 @brief read a number from the input
10630
10631 @tparam NumberType the type of the number
10632 @param[in] format the current format (for diagnostics)
10633 @param[out] result number of type @a NumberType
10634
10635 @return whether conversion completed
10636
10637 @note This function needs to respect the system's endianess, because
10638 bytes in CBOR, MessagePack, and UBJSON are stored in network order
10639 (big endian) and therefore need reordering on little endian systems.
10640 */
10641 template<typename NumberType, bool InputIsLittleEndian = false>
10642 bool get_number(const input_format_t format, NumberType& result)
10643 {
10644 // step 1: read input into array with system's byte order
10645 std::array<std::uint8_t, sizeof(NumberType)> vec{};
10646 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
10647 {
10648 get();
10649 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10650 {
10651 return false;
10652 }
10653
10654 // reverse byte order prior to conversion if necessary
10656 {
10657 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10658 }
10659 else
10660 {
10661 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10662 }
10663 }
10664
10665 // step 2: convert array into number of type T and return
10666 std::memcpy(&result, vec.data(), sizeof(NumberType));
10667 return true;
10668 }
10669
10670 /*!
10671 @brief create a string by reading characters from the input
10672
10673 @tparam NumberType the type of the number
10674 @param[in] format the current format (for diagnostics)
10675 @param[in] len number of characters to read
10676 @param[out] result string created by reading @a len bytes
10677
10678 @return whether string creation completed
10679
10680 @note We can not reserve @a len bytes for the result, because @a len
10681 may be too large. Usually, @ref unexpect_eof() detects the end of
10682 the input before we run out of string memory.
10683 */
10684 template<typename NumberType>
10685 bool get_string(const input_format_t format,
10686 const NumberType len,
10687 string_t& result)
10688 {
10689 bool success = true;
10690 for (NumberType i = 0; i < len; i++)
10691 {
10692 get();
10693 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10694 {
10695 success = false;
10696 break;
10697 }
10698 result.push_back(static_cast<typename string_t::value_type>(current));
10699 }
10700 return success;
10701 }
10702
10703 /*!
10704 @brief create a byte array by reading bytes from the input
10705
10706 @tparam NumberType the type of the number
10707 @param[in] format the current format (for diagnostics)
10708 @param[in] len number of bytes to read
10709 @param[out] result byte array created by reading @a len bytes
10710
10711 @return whether byte array creation completed
10712
10713 @note We can not reserve @a len bytes for the result, because @a len
10714 may be too large. Usually, @ref unexpect_eof() detects the end of
10715 the input before we run out of memory.
10716 */
10717 template<typename NumberType>
10718 bool get_binary(const input_format_t format,
10719 const NumberType len,
10720 binary_t& result)
10721 {
10722 bool success = true;
10723 for (NumberType i = 0; i < len; i++)
10724 {
10725 get();
10726 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10727 {
10728 success = false;
10729 break;
10730 }
10731 result.push_back(static_cast<std::uint8_t>(current));
10732 }
10733 return success;
10734 }
10735
10736 /*!
10737 @param[in] format the current format (for diagnostics)
10738 @param[in] context further context information (for diagnostics)
10739 @return whether the last read character is not EOF
10740 */
10742 bool unexpect_eof(const input_format_t format, const char* context) const
10743 {
10745 {
10746 return sax->parse_error(chars_read, "<end of file>",
10747 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
10748 }
10749 return true;
10750 }
10751
10752 /*!
10753 @return a string representation of the last read byte
10754 */
10755 std::string get_token_string() const
10756 {
10757 std::array<char, 3> cr{ {} };
10758 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10759 return std::string{ cr.data() };
10760 }
10761
10762 /*!
10763 @param[in] format the current format
10764 @param[in] detail a detailed error message
10765 @param[in] context further context information
10766 @return a message string to use in the parse_error exceptions
10767 */
10768 std::string exception_message(const input_format_t format,
10769 const std::string& detail,
10770 const std::string& context) const
10771 {
10772 std::string error_msg = "syntax error while parsing ";
10773
10774 switch (format)
10775 {
10776 case input_format_t::cbor:
10777 error_msg += "CBOR";
10778 break;
10779
10780 case input_format_t::msgpack:
10781 error_msg += "MessagePack";
10782 break;
10783
10784 case input_format_t::ubjson:
10785 error_msg += "UBJSON";
10786 break;
10787
10788 case input_format_t::bson:
10789 error_msg += "BSON";
10790 break;
10791
10792 case input_format_t::json: // LCOV_EXCL_LINE
10793 default: // LCOV_EXCL_LINE
10794 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10795 }
10796
10797 return error_msg + " " + context + ": " + detail;
10798 }
10799
10800 private:
10801 /// input adapter
10802 InputAdapterType ia;
10803
10804 /// the current character
10805 char_int_type current = std::char_traits<char_type>::eof();
10806
10807 /// the number of characters read
10808 std::size_t chars_read = 0;
10809
10810 /// whether we can assume little endianess
10812
10813 /// the SAX parser
10814 json_sax_t* sax = nullptr;
10815 };
10816 } // namespace detail
10817} // namespace nlohmann
10818
10819// #include <nlohmann/detail/input/input_adapters.hpp>
10820
10821// #include <nlohmann/detail/input/lexer.hpp>
10822
10823// #include <nlohmann/detail/input/parser.hpp>
10824
10825
10826#include <cmath> // isfinite
10827#include <cstdint> // uint8_t
10828#include <functional> // function
10829#include <string> // string
10830#include <utility> // move
10831#include <vector> // vector
10832
10833// #include <nlohmann/detail/exceptions.hpp>
10834
10835// #include <nlohmann/detail/input/input_adapters.hpp>
10836
10837// #include <nlohmann/detail/input/json_sax.hpp>
10838
10839// #include <nlohmann/detail/input/lexer.hpp>
10840
10841// #include <nlohmann/detail/macro_scope.hpp>
10842
10843// #include <nlohmann/detail/meta/is_sax.hpp>
10844
10845// #include <nlohmann/detail/value_t.hpp>
10846
10847
10848namespace nlohmann
10849{
10850 namespace detail
10851 {
10852 ////////////
10853 // parser //
10854 ////////////
10855
10857 {
10858 /// the parser read `{` and started to process a JSON object
10860 /// the parser read `}` and finished processing a JSON object
10861 object_end,
10862 /// the parser read `[` and started to process a JSON array
10864 /// the parser read `]` and finished processing a JSON array
10865 array_end,
10866 /// the parser read a key of a value in an object
10867 key,
10868 /// the parser finished reading a JSON value
10869 value
10870 };
10871
10872 template<typename BasicJsonType>
10873 using parser_callback_t =
10874 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
10875
10876 /*!
10877 @brief syntax analysis
10878
10879 This class implements a recursive descent parser.
10880 */
10881 template<typename BasicJsonType, typename InputAdapterType>
10883 {
10884 using number_integer_t = typename BasicJsonType::number_integer_t;
10885 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10886 using number_float_t = typename BasicJsonType::number_float_t;
10887 using string_t = typename BasicJsonType::string_t;
10888 using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10889 using token_type = typename lexer_t::token_type;
10890
10891 public:
10892 /// a parser reading from an input adapter
10893 explicit parser(InputAdapterType&& adapter,
10894 const parser_callback_t<BasicJsonType> cb = nullptr,
10895 const bool allow_exceptions_ = true,
10896 const bool skip_comments = false)
10897 : callback(cb)
10900 {
10901 // read first token
10902 get_token();
10903 }
10904
10905 /*!
10906 @brief public parser interface
10907
10908 @param[in] strict whether to expect the last token to be EOF
10909 @param[in,out] result parsed JSON value
10910
10911 @throw parse_error.101 in case of an unexpected token
10912 @throw parse_error.102 if to_unicode fails or surrogate error
10913 @throw parse_error.103 if to_unicode fails
10914 */
10915 void parse(const bool strict, BasicJsonType& result)
10916 {
10917 if (callback)
10918 {
10921
10922 // in strict mode, input must be completely read
10923 if (strict && (get_token() != token_type::end_of_input))
10924 {
10929 }
10930
10931 // in case of an error, return discarded value
10932 if (sdp.is_errored())
10933 {
10935 return;
10936 }
10937
10938 // set top-level value to null if it was discarded by the callback
10939 // function
10940 if (result.is_discarded())
10941 {
10942 result = nullptr;
10943 }
10944 }
10945 else
10946 {
10949
10950 // in strict mode, input must be completely read
10951 if (strict && (get_token() != token_type::end_of_input))
10952 {
10956 }
10957
10958 // in case of an error, return discarded value
10959 if (sdp.is_errored())
10960 {
10962 return;
10963 }
10964 }
10965
10967 }
10968
10969 /*!
10970 @brief public accept interface
10971
10972 @param[in] strict whether to expect the last token to be EOF
10973 @return whether the input is a proper JSON text
10974 */
10975 bool accept(const bool strict = true)
10976 {
10978 return sax_parse(&sax_acceptor, strict);
10979 }
10980
10981 template<typename SAX>
10983 bool sax_parse(SAX* sax, const bool strict = true)
10984 {
10986 const bool result = sax_parse_internal(sax);
10987
10988 // strict mode: next byte must be EOF
10989 if (result && strict && (get_token() != token_type::end_of_input))
10990 {
10994 }
10995
10996 return result;
10997 }
10998
10999 private:
11000 template<typename SAX>
11002 bool sax_parse_internal(SAX* sax)
11003 {
11004 // stack to remember the hierarchy of structured values we are parsing
11005 // true = array; false = object
11006 std::vector<bool> states;
11007 // value to avoid a goto (see comment where set to true)
11008 bool skip_to_state_evaluation = false;
11009
11010 while (true)
11011 {
11013 {
11014 // invariant: get_token() was called before each iteration
11015 switch (last_token)
11016 {
11018 {
11020 {
11021 return false;
11022 }
11023
11024 // closing } -> we are done
11026 {
11028 {
11029 return false;
11030 }
11031 break;
11032 }
11033
11034 // parse key
11036 {
11040 }
11042 {
11043 return false;
11044 }
11045
11046 // parse separator (:)
11048 {
11052 }
11053
11054 // remember we are now inside an object
11055 states.push_back(false);
11056
11057 // parse values
11058 get_token();
11059 continue;
11060 }
11061
11062 case token_type::begin_array:
11063 {
11065 {
11066 return false;
11067 }
11068
11069 // closing ] -> we are done
11070 if (get_token() == token_type::end_array)
11071 {
11073 {
11074 return false;
11075 }
11076 break;
11077 }
11078
11079 // remember we are now inside an array
11080 states.push_back(true);
11081
11082 // parse values (no need to call get_token)
11083 continue;
11084 }
11085
11086 case token_type::value_float:
11087 {
11088 const auto res = m_lexer.get_number_float();
11089
11091 {
11094 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
11095 }
11096
11098 {
11099 return false;
11100 }
11101
11102 break;
11103 }
11104
11106 {
11107 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11108 {
11109 return false;
11110 }
11111 break;
11112 }
11113
11115 {
11116 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11117 {
11118 return false;
11119 }
11120 break;
11121 }
11122
11124 {
11125 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11126 {
11127 return false;
11128 }
11129 break;
11130 }
11131
11133 {
11135 {
11136 return false;
11137 }
11138 break;
11139 }
11140
11142 {
11144 {
11145 return false;
11146 }
11147 break;
11148 }
11149
11151 {
11153 {
11154 return false;
11155 }
11156 break;
11157 }
11158
11159 case token_type::parse_error:
11160 {
11161 // using "uninitialized" to avoid "expected" message
11165 }
11166
11168 case token_type::end_array:
11169 case token_type::end_object:
11174 default: // the last token was unexpected
11175 {
11179 }
11180 }
11181 }
11182 else
11183 {
11185 }
11186
11187 // we reached this line after we successfully parsed a value
11188 if (states.empty())
11189 {
11190 // empty stack: we reached the end of the hierarchy: done
11191 return true;
11192 }
11193
11194 if (states.back()) // array
11195 {
11196 // comma -> next value
11198 {
11199 // parse a new value
11200 get_token();
11201 continue;
11202 }
11203
11204 // closing ]
11206 {
11208 {
11209 return false;
11210 }
11211
11212 // We are done with this array. Before we can parse a
11213 // new value, we need to evaluate the new state first.
11214 // By setting skip_to_state_evaluation to false, we
11215 // are effectively jumping to the beginning of this if.
11217 states.pop_back();
11219 continue;
11220 }
11221
11225 }
11226
11227 // states.back() is false -> object
11228
11229 // comma -> next value
11231 {
11232 // parse key
11234 {
11238 }
11239
11241 {
11242 return false;
11243 }
11244
11245 // parse separator (:)
11247 {
11251 }
11252
11253 // parse values
11254 get_token();
11255 continue;
11256 }
11257
11258 // closing }
11260 {
11262 {
11263 return false;
11264 }
11265
11266 // We are done with this object. Before we can parse a
11267 // new value, we need to evaluate the new state first.
11268 // By setting skip_to_state_evaluation to false, we
11269 // are effectively jumping to the beginning of this if.
11271 states.pop_back();
11273 continue;
11274 }
11275
11279 }
11280 }
11281
11282 /// get next token from lexer
11283 token_type get_token()
11284 {
11285 return last_token = m_lexer.scan();
11286 }
11287
11288 std::string exception_message(const token_type expected, const std::string& context)
11289 {
11290 std::string error_msg = "syntax error ";
11291
11292 if (!context.empty())
11293 {
11294 error_msg += "while parsing " + context + " ";
11295 }
11296
11297 error_msg += "- ";
11298
11300 {
11301 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
11302 m_lexer.get_token_string() + "'";
11303 }
11304 else
11305 {
11306 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
11307 }
11308
11310 {
11311 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
11312 }
11313
11314 return error_msg;
11315 }
11316
11317 private:
11318 /// callback function
11320 /// the type of the last read token
11321 token_type last_token = token_type::uninitialized;
11322 /// the lexer
11323 lexer_t m_lexer;
11324 /// whether to throw exceptions in case of errors
11325 const bool allow_exceptions = true;
11326 };
11327
11328 } // namespace detail
11329} // namespace nlohmann
11330
11331// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11332
11333
11334// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11335
11336
11337#include <cstddef> // ptrdiff_t
11338#include <limits> // numeric_limits
11339
11340// #include <nlohmann/detail/macro_scope.hpp>
11341
11342
11343namespace nlohmann
11344{
11345 namespace detail
11346 {
11347 /*
11348 @brief an iterator for primitive JSON types
11349
11350 This class models an iterator for primitive JSON types (boolean, number,
11351 string). It's only purpose is to allow the iterator/const_iterator classes
11352 to "iterate" over primitive values. Internally, the iterator is modeled by
11353 a `difference_type` variable. Value begin_value (`0`) models the begin,
11354 end_value (`1`) models past the end.
11355 */
11357 {
11358 private:
11359 using difference_type = std::ptrdiff_t;
11360 static constexpr difference_type begin_value = 0;
11361 static constexpr difference_type end_value = begin_value + 1;
11362
11364 /// iterator as signed integer type
11365 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11366
11367 public:
11368 constexpr difference_type get_value() const noexcept
11369 {
11370 return m_it;
11371 }
11372
11373 /// set iterator to a defined beginning
11374 void set_begin() noexcept
11375 {
11376 m_it = begin_value;
11377 }
11378
11379 /// set iterator to a defined past the end
11380 void set_end() noexcept
11381 {
11382 m_it = end_value;
11383 }
11384
11385 /// return whether the iterator can be dereferenced
11386 constexpr bool is_begin() const noexcept
11387 {
11388 return m_it == begin_value;
11389 }
11390
11391 /// return whether the iterator is at end
11392 constexpr bool is_end() const noexcept
11393 {
11394 return m_it == end_value;
11395 }
11396
11397 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11398 {
11399 return lhs.m_it == rhs.m_it;
11400 }
11401
11402 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11403 {
11404 return lhs.m_it < rhs.m_it;
11405 }
11406
11407 primitive_iterator_t operator+(difference_type n) noexcept
11408 {
11409 auto result = *this;
11410 result += n;
11411 return result;
11412 }
11413
11414 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11415 {
11416 return lhs.m_it - rhs.m_it;
11417 }
11418
11420 {
11421 ++m_it;
11422 return *this;
11423 }
11424
11425 primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
11426 {
11427 auto result = *this;
11428 ++m_it;
11429 return result;
11430 }
11431
11433 {
11434 --m_it;
11435 return *this;
11436 }
11437
11438 primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
11439 {
11440 auto result = *this;
11441 --m_it;
11442 return result;
11443 }
11444
11445 primitive_iterator_t& operator+=(difference_type n) noexcept
11446 {
11447 m_it += n;
11448 return *this;
11449 }
11450
11451 primitive_iterator_t& operator-=(difference_type n) noexcept
11452 {
11453 m_it -= n;
11454 return *this;
11455 }
11456 };
11457 } // namespace detail
11458} // namespace nlohmann
11459
11460
11461namespace nlohmann
11462{
11463 namespace detail
11464 {
11465 /*!
11466 @brief an iterator value
11467
11468 @note This structure could easily be a union, but MSVC currently does not allow
11469 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
11470 */
11471 template<typename BasicJsonType> struct internal_iterator
11472 {
11473 /// iterator for JSON objects
11474 typename BasicJsonType::object_t::iterator object_iterator{};
11475 /// iterator for JSON arrays
11476 typename BasicJsonType::array_t::iterator array_iterator{};
11477 /// generic iterator for all other types
11479 };
11480 } // namespace detail
11481} // namespace nlohmann
11482
11483// #include <nlohmann/detail/iterators/iter_impl.hpp>
11484
11485
11486#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
11487#include <type_traits> // conditional, is_const, remove_const
11488
11489// #include <nlohmann/detail/exceptions.hpp>
11490
11491// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11492
11493// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11494
11495// #include <nlohmann/detail/macro_scope.hpp>
11496
11497// #include <nlohmann/detail/meta/cpp_future.hpp>
11498
11499// #include <nlohmann/detail/meta/type_traits.hpp>
11500
11501// #include <nlohmann/detail/value_t.hpp>
11502
11503
11504namespace nlohmann
11505{
11506 namespace detail
11507 {
11508 // forward declare, to be able to friend it later on
11509 template<typename IteratorType> class iteration_proxy;
11510 template<typename IteratorType> class iteration_proxy_value;
11511
11512 /*!
11513 @brief a template for a bidirectional iterator for the @ref basic_json class
11514 This class implements a both iterators (iterator and const_iterator) for the
11515 @ref basic_json class.
11516 @note An iterator is called *initialized* when a pointer to a JSON value has
11517 been set (e.g., by a constructor or a copy assignment). If the iterator is
11518 default-constructed, it is *uninitialized* and most methods are undefined.
11519 **The library uses assertions to detect calls on uninitialized iterators.**
11520 @requirement The class satisfies the following concept requirements:
11521 -
11522 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
11523 The iterator that can be moved can be moved in both directions (i.e.
11524 incremented and decremented).
11525 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
11526 iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
11527 */
11528 template<typename BasicJsonType>
11530 {
11531 /// the iterator with BasicJsonType of different const-ness
11532 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
11533 /// allow basic_json to access private members
11534 friend other_iter_impl;
11535 friend BasicJsonType;
11538
11539 using object_t = typename BasicJsonType::object_t;
11540 using array_t = typename BasicJsonType::array_t;
11541 // make sure BasicJsonType is basic_json or const basic_json
11542 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
11543 "iter_impl only accepts (const) basic_json");
11544
11545 public:
11546
11547 /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
11548 /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
11549 /// A user-defined iterator should provide publicly accessible typedefs named
11550 /// iterator_category, value_type, difference_type, pointer, and reference.
11551 /// Note that value_type is required to be non-const, even for constant iterators.
11552 using iterator_category = std::bidirectional_iterator_tag;
11553
11554 /// the type of the values when the iterator is dereferenced
11555 using value_type = typename BasicJsonType::value_type;
11556 /// a type to represent differences between iterators
11557 using difference_type = typename BasicJsonType::difference_type;
11558 /// defines a pointer to the type iterated over (value_type)
11559 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
11560 typename BasicJsonType::const_pointer,
11561 typename BasicJsonType::pointer>::type;
11562 /// defines a reference to the type iterated over (value_type)
11563 using reference =
11564 typename std::conditional<std::is_const<BasicJsonType>::value,
11565 typename BasicJsonType::const_reference,
11566 typename BasicJsonType::reference>::type;
11567
11568 iter_impl() = default;
11569 ~iter_impl() = default;
11570 iter_impl(iter_impl&&) noexcept = default;
11571 iter_impl& operator=(iter_impl&&) noexcept = default;
11572
11573 /*!
11574 @brief constructor for a given JSON instance
11575 @param[in] object pointer to a JSON object for this iterator
11576 @pre object != nullptr
11577 @post The iterator is initialized; i.e. `m_object != nullptr`.
11578 */
11579 explicit iter_impl(pointer object) noexcept : m_object(object)
11580 {
11581 JSON_ASSERT(m_object != nullptr);
11582
11583 switch (m_object->m_type)
11584 {
11585 case value_t::object:
11586 {
11587 m_it.object_iterator = typename object_t::iterator();
11588 break;
11589 }
11590
11591 case value_t::array:
11592 {
11593 m_it.array_iterator = typename array_t::iterator();
11594 break;
11595 }
11596
11597 case value_t::null:
11598 case value_t::string:
11599 case value_t::boolean:
11600 case value_t::number_integer:
11602 case value_t::number_float:
11603 case value_t::binary:
11604 case value_t::discarded:
11605 default:
11606 {
11608 break;
11609 }
11610 }
11611 }
11612
11613 /*!
11614 @note The conventional copy constructor and copy assignment are implicitly
11615 defined. Combined with the following converting constructor and
11616 assignment, they support: (1) copy from iterator to iterator, (2)
11617 copy from const iterator to const iterator, and (3) conversion from
11618 iterator to const iterator. However conversion from const iterator
11619 to iterator is not defined.
11620 */
11621
11622 /*!
11623 @brief const copy constructor
11624 @param[in] other const iterator to copy from
11625 @note This copy constructor had to be defined explicitly to circumvent a bug
11626 occurring on msvc v19.0 compiler (VS 2015) debug build. For more
11627 information refer to: https://github.com/nlohmann/json/issues/1608
11628 */
11629 iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
11631 {}
11632
11633 /*!
11634 @brief converting assignment
11635 @param[in] other const iterator to copy from
11636 @return const/non-const iterator
11637 @note It is not checked whether @a other is initialized.
11638 */
11639 iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
11640 {
11641 if (&other != this)
11642 {
11644 m_it = other.m_it;
11645 }
11646 return *this;
11647 }
11648
11649 /*!
11650 @brief converting constructor
11651 @param[in] other non-const iterator to copy from
11652 @note It is not checked whether @a other is initialized.
11653 */
11654 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
11656 {}
11657
11658 /*!
11659 @brief converting assignment
11660 @param[in] other non-const iterator to copy from
11661 @return const/non-const iterator
11662 @note It is not checked whether @a other is initialized.
11663 */
11664 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
11665 {
11667 m_it = other.m_it;
11668 return *this;
11669 }
11670
11672 /*!
11673 @brief set the iterator to the first value
11674 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11675 */
11676 void set_begin() noexcept
11677 {
11678 JSON_ASSERT(m_object != nullptr);
11679
11681 {
11682 case value_t::object:
11683 {
11685 break;
11686 }
11687
11688 case value_t::array:
11689 {
11691 break;
11692 }
11693
11694 case value_t::null:
11695 {
11696 // set to end so begin()==end() is true: null is empty
11698 break;
11699 }
11700
11701 case value_t::string:
11702 case value_t::boolean:
11703 case value_t::number_integer:
11705 case value_t::number_float:
11706 case value_t::binary:
11707 case value_t::discarded:
11708 default:
11709 {
11711 break;
11712 }
11713 }
11714 }
11715
11716 /*!
11717 @brief set the iterator past the last value
11718 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11719 */
11720 void set_end() noexcept
11721 {
11722 JSON_ASSERT(m_object != nullptr);
11723
11724 switch (m_object->m_type)
11725 {
11726 case value_t::object:
11727 {
11729 break;
11730 }
11731
11732 case value_t::array:
11733 {
11735 break;
11736 }
11737
11738 case value_t::null:
11739 case value_t::string:
11740 case value_t::boolean:
11741 case value_t::number_integer:
11743 case value_t::number_float:
11744 case value_t::binary:
11745 case value_t::discarded:
11746 default:
11747 {
11749 break;
11750 }
11751 }
11752 }
11753
11754 public:
11755 /*!
11756 @brief return a reference to the value pointed to by the iterator
11757 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11758 */
11759 reference operator*() const
11760 {
11761 JSON_ASSERT(m_object != nullptr);
11762
11763 switch (m_object->m_type)
11764 {
11765 case value_t::object:
11766 {
11768 return m_it.object_iterator->second;
11769 }
11770
11771 case value_t::array:
11772 {
11774 return *m_it.array_iterator;
11775 }
11776
11777 case value_t::null:
11778 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11779
11780 case value_t::string:
11781 case value_t::boolean:
11782 case value_t::number_integer:
11784 case value_t::number_float:
11785 case value_t::binary:
11786 case value_t::discarded:
11787 default:
11788 {
11790 {
11791 return *m_object;
11792 }
11793
11794 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11795 }
11796 }
11797 }
11798
11799 /*!
11800 @brief dereference the iterator
11801 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11802 */
11803 pointer operator->() const
11804 {
11805 JSON_ASSERT(m_object != nullptr);
11806
11807 switch (m_object->m_type)
11808 {
11809 case value_t::object:
11810 {
11812 return &(m_it.object_iterator->second);
11813 }
11814
11815 case value_t::array:
11816 {
11818 return &*m_it.array_iterator;
11819 }
11820
11821 case value_t::null:
11822 case value_t::string:
11823 case value_t::boolean:
11824 case value_t::number_integer:
11826 case value_t::number_float:
11827 case value_t::binary:
11828 case value_t::discarded:
11829 default:
11830 {
11832 {
11833 return m_object;
11834 }
11835
11836 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11837 }
11838 }
11839 }
11840
11841 /*!
11842 @brief post-increment (it++)
11843 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11844 */
11845 iter_impl const operator++(int) // NOLINT(readability-const-return-type)
11846 {
11847 auto result = *this;
11848 ++(*this);
11849 return result;
11850 }
11851
11852 /*!
11853 @brief pre-increment (++it)
11854 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11855 */
11857 {
11858 JSON_ASSERT(m_object != nullptr);
11859
11860 switch (m_object->m_type)
11861 {
11862 case value_t::object:
11863 {
11865 break;
11866 }
11867
11868 case value_t::array:
11869 {
11871 break;
11872 }
11873
11874 case value_t::null:
11875 case value_t::string:
11876 case value_t::boolean:
11877 case value_t::number_integer:
11879 case value_t::number_float:
11880 case value_t::binary:
11881 case value_t::discarded:
11882 default:
11883 {
11885 break;
11886 }
11887 }
11888
11889 return *this;
11890 }
11891
11892 /*!
11893 @brief post-decrement (it--)
11894 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11895 */
11896 iter_impl const operator--(int) // NOLINT(readability-const-return-type)
11897 {
11898 auto result = *this;
11899 --(*this);
11900 return result;
11901 }
11902
11903 /*!
11904 @brief pre-decrement (--it)
11905 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11906 */
11908 {
11909 JSON_ASSERT(m_object != nullptr);
11910
11911 switch (m_object->m_type)
11912 {
11913 case value_t::object:
11914 {
11916 break;
11917 }
11918
11919 case value_t::array:
11920 {
11922 break;
11923 }
11924
11925 case value_t::null:
11926 case value_t::string:
11927 case value_t::boolean:
11928 case value_t::number_integer:
11930 case value_t::number_float:
11931 case value_t::binary:
11932 case value_t::discarded:
11933 default:
11934 {
11936 break;
11937 }
11938 }
11939
11940 return *this;
11941 }
11942
11943 /*!
11944 @brief comparison: equal
11945 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11946 */
11947 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 >
11948 bool operator==(const IterImpl& other) const
11949 {
11950 // if objects are not the same, the comparison is undefined
11952 {
11953 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
11954 }
11955
11956 JSON_ASSERT(m_object != nullptr);
11957
11958 switch (m_object->m_type)
11959 {
11960 case value_t::object:
11962
11963 case value_t::array:
11965
11966 case value_t::null:
11967 case value_t::string:
11968 case value_t::boolean:
11969 case value_t::number_integer:
11971 case value_t::number_float:
11972 case value_t::binary:
11973 case value_t::discarded:
11974 default:
11976 }
11977 }
11978
11979 /*!
11980 @brief comparison: not equal
11981 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11982 */
11983 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 >
11984 bool operator!=(const IterImpl& other) const
11985 {
11986 return !operator==(other);
11987 }
11988
11989 /*!
11990 @brief comparison: smaller
11991 @pre The iterator is initialized; i.e. `m_object != nullptr`.
11992 */
11993 bool operator<(const iter_impl& other) const
11994 {
11995 // if objects are not the same, the comparison is undefined
11997 {
11998 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
11999 }
12000
12001 JSON_ASSERT(m_object != nullptr);
12002
12003 switch (m_object->m_type)
12004 {
12005 case value_t::object:
12006 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
12007
12008 case value_t::array:
12010
12011 case value_t::null:
12012 case value_t::string:
12013 case value_t::boolean:
12014 case value_t::number_integer:
12016 case value_t::number_float:
12017 case value_t::binary:
12018 case value_t::discarded:
12019 default:
12021 }
12022 }
12023
12024 /*!
12025 @brief comparison: less than or equal
12026 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12027 */
12028 bool operator<=(const iter_impl& other) const
12029 {
12030 return !other.operator < (*this);
12031 }
12032
12033 /*!
12034 @brief comparison: greater than
12035 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12036 */
12037 bool operator>(const iter_impl& other) const
12038 {
12039 return !operator<=(other);
12040 }
12041
12042 /*!
12043 @brief comparison: greater than or equal
12044 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12045 */
12046 bool operator>=(const iter_impl& other) const
12047 {
12048 return !operator<(other);
12049 }
12050
12051 /*!
12052 @brief add to iterator
12053 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12054 */
12055 iter_impl& operator+=(difference_type i)
12056 {
12057 JSON_ASSERT(m_object != nullptr);
12058
12059 switch (m_object->m_type)
12060 {
12061 case value_t::object:
12062 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12063
12064 case value_t::array:
12065 {
12067 break;
12068 }
12069
12070 case value_t::null:
12071 case value_t::string:
12072 case value_t::boolean:
12073 case value_t::number_integer:
12075 case value_t::number_float:
12076 case value_t::binary:
12077 case value_t::discarded:
12078 default:
12079 {
12081 break;
12082 }
12083 }
12084
12085 return *this;
12086 }
12087
12088 /*!
12089 @brief subtract from iterator
12090 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12091 */
12092 iter_impl& operator-=(difference_type i)
12093 {
12094 return operator+=(-i);
12095 }
12096
12097 /*!
12098 @brief add to iterator
12099 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12100 */
12101 iter_impl operator+(difference_type i) const
12102 {
12103 auto result = *this;
12104 result += i;
12105 return result;
12106 }
12107
12108 /*!
12109 @brief addition of distance and iterator
12110 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12111 */
12112 friend iter_impl operator+(difference_type i, const iter_impl& it)
12113 {
12114 auto result = it;
12115 result += i;
12116 return result;
12117 }
12118
12119 /*!
12120 @brief subtract from iterator
12121 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12122 */
12123 iter_impl operator-(difference_type i) const
12124 {
12125 auto result = *this;
12126 result -= i;
12127 return result;
12128 }
12129
12130 /*!
12131 @brief return difference
12132 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12133 */
12134 difference_type operator-(const iter_impl& other) const
12135 {
12136 JSON_ASSERT(m_object != nullptr);
12137
12138 switch (m_object->m_type)
12139 {
12140 case value_t::object:
12141 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12142
12143 case value_t::array:
12145
12146 case value_t::null:
12147 case value_t::string:
12148 case value_t::boolean:
12149 case value_t::number_integer:
12151 case value_t::number_float:
12152 case value_t::binary:
12153 case value_t::discarded:
12154 default:
12156 }
12157 }
12158
12159 /*!
12160 @brief access to successor
12161 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12162 */
12163 reference operator[](difference_type n) const
12164 {
12165 JSON_ASSERT(m_object != nullptr);
12166
12167 switch (m_object->m_type)
12168 {
12169 case value_t::object:
12170 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
12171
12172 case value_t::array:
12173 return *std::next(m_it.array_iterator, n);
12174
12175 case value_t::null:
12176 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12177
12178 case value_t::string:
12179 case value_t::boolean:
12180 case value_t::number_integer:
12182 case value_t::number_float:
12183 case value_t::binary:
12184 case value_t::discarded:
12185 default:
12186 {
12188 {
12189 return *m_object;
12190 }
12191
12192 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12193 }
12194 }
12195 }
12196
12197 /*!
12198 @brief return the key of an object iterator
12199 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12200 */
12201 const typename object_t::key_type& key() const
12202 {
12203 JSON_ASSERT(m_object != nullptr);
12204
12206 {
12207 return m_it.object_iterator->first;
12208 }
12209
12210 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
12211 }
12212
12213 /*!
12214 @brief return the value of an iterator
12215 @pre The iterator is initialized; i.e. `m_object != nullptr`.
12216 */
12217 reference value() const
12218 {
12219 return operator*();
12220 }
12221
12223 /// associated JSON instance
12224 pointer m_object = nullptr;
12225 /// the actual iterator of the associated instance
12226 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it{};
12227 };
12228 } // namespace detail
12229} // namespace nlohmann
12230
12231// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12232
12233// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12234
12235
12236#include <cstddef> // ptrdiff_t
12237#include <iterator> // reverse_iterator
12238#include <utility> // declval
12239
12240namespace nlohmann
12241{
12242 namespace detail
12243 {
12244 //////////////////////
12245 // reverse_iterator //
12246 //////////////////////
12247
12248 /*!
12249 @brief a template for a reverse iterator class
12250
12251 @tparam Base the base iterator type to reverse. Valid types are @ref
12252 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
12253 create @ref const_reverse_iterator).
12254
12255 @requirement The class satisfies the following concept requirements:
12256 -
12257 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
12258 The iterator that can be moved can be moved in both directions (i.e.
12259 incremented and decremented).
12260 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
12261 It is possible to write to the pointed-to element (only if @a Base is
12262 @ref iterator).
12263
12264 @since version 1.0.0
12265 */
12266 template<typename Base>
12267 class json_reverse_iterator : public std::reverse_iterator<Base>
12268 {
12269 public:
12270 using difference_type = std::ptrdiff_t;
12271 /// shortcut to the reverse iterator adapter
12272 using base_iterator = std::reverse_iterator<Base>;
12273 /// the reference type for the pointed-to element
12274 using reference = typename Base::reference;
12275
12276 /// create reverse iterator from iterator
12277 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
12278 : base_iterator(it) {}
12279
12280 /// create reverse iterator from base class
12281 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12282
12283 /// post-increment (it++)
12284 json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
12285 {
12286 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12287 }
12288
12289 /// pre-increment (++it)
12291 {
12292 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12293 }
12294
12295 /// post-decrement (it--)
12296 json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
12297 {
12298 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12299 }
12300
12301 /// pre-decrement (--it)
12303 {
12304 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12305 }
12306
12307 /// add to iterator
12308 json_reverse_iterator& operator+=(difference_type i)
12309 {
12310 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12311 }
12312
12313 /// add to iterator
12314 json_reverse_iterator operator+(difference_type i) const
12315 {
12316 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12317 }
12318
12319 /// subtract from iterator
12320 json_reverse_iterator operator-(difference_type i) const
12321 {
12322 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12323 }
12324
12325 /// return difference
12326 difference_type operator-(const json_reverse_iterator& other) const
12327 {
12328 return base_iterator(*this) - base_iterator(other);
12329 }
12330
12331 /// access to successor
12332 reference operator[](difference_type n) const
12333 {
12334 return *(this->operator+(n));
12335 }
12336
12337 /// return the key of an object iterator
12338 auto key() const -> decltype(std::declval<Base>().key())
12339 {
12340 auto it = --this->base();
12341 return it.key();
12342 }
12343
12344 /// return the value of an iterator
12345 reference value() const
12346 {
12347 auto it = --this->base();
12348 return it.operator * ();
12349 }
12350 };
12351 } // namespace detail
12352} // namespace nlohmann
12353
12354// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12355
12356// #include <nlohmann/detail/json_pointer.hpp>
12357
12358
12359#include <algorithm> // all_of
12360#include <cctype> // isdigit
12361#include <limits> // max
12362#include <numeric> // accumulate
12363#include <string> // string
12364#include <utility> // move
12365#include <vector> // vector
12366
12367// #include <nlohmann/detail/exceptions.hpp>
12368
12369// #include <nlohmann/detail/macro_scope.hpp>
12370
12371// #include <nlohmann/detail/string_escape.hpp>
12372
12373// #include <nlohmann/detail/value_t.hpp>
12374
12375
12376namespace nlohmann
12377{
12378 template<typename BasicJsonType>
12380 {
12381 // allow basic_json to access private members
12383 friend class basic_json;
12384
12385 public:
12386 /*!
12387 @brief create JSON pointer
12388
12389 Create a JSON pointer according to the syntax described in
12390 [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
12391
12392 @param[in] s string representing the JSON pointer; if omitted, the empty
12393 string is assumed which references the whole JSON value
12394
12395 @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
12396 not begin with a slash (`/`); see example below
12397
12398 @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
12399 not followed by `0` (representing `~`) or `1` (representing `/`); see
12400 example below
12401
12402 @liveexample{The example shows the construction several valid JSON pointers
12403 as well as the exceptional behavior.,json_pointer}
12404
12405 @since version 2.0.0
12406 */
12407 explicit json_pointer(const std::string& s = "")
12409 {}
12410
12411 /*!
12412 @brief return a string representation of the JSON pointer
12413
12414 @invariant For each JSON pointer `ptr`, it holds:
12415 @code {.cpp}
12416 ptr == json_pointer(ptr.to_string());
12417 @endcode
12418
12419 @return a string representation of the JSON pointer
12420
12421 @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
12422
12423 @since version 2.0.0
12424 */
12425 std::string to_string() const
12426 {
12428 std::string{},
12429 [](const std::string& a, const std::string& b)
12430 {
12431 return a + "/" + detail::escape(b);
12432 });
12433 }
12434
12435 /// @copydoc to_string()
12436 operator std::string() const
12437 {
12438 return to_string();
12439 }
12440
12441 /*!
12442 @brief append another JSON pointer at the end of this JSON pointer
12443
12444 @param[in] ptr JSON pointer to append
12445 @return JSON pointer with @a ptr appended
12446
12447 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12448
12449 @complexity Linear in the length of @a ptr.
12450
12451 @sa see @ref operator/=(std::string) to append a reference token
12452 @sa see @ref operator/=(std::size_t) to append an array index
12453 @sa see @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
12454
12455 @since version 3.6.0
12456 */
12457 json_pointer& operator/=(const json_pointer& ptr)
12458 {
12462 return *this;
12463 }
12464
12465 /*!
12466 @brief append an unescaped reference token at the end of this JSON pointer
12467
12468 @param[in] token reference token to append
12469 @return JSON pointer with @a token appended without escaping @a token
12470
12471 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12472
12473 @complexity Amortized constant.
12474
12475 @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12476 @sa see @ref operator/=(std::size_t) to append an array index
12477 @sa see @ref operator/(const json_pointer&, std::size_t) for a binary operator
12478
12479 @since version 3.6.0
12480 */
12481 json_pointer& operator/=(std::string token)
12482 {
12484 return *this;
12485 }
12486
12487 /*!
12488 @brief append an array index at the end of this JSON pointer
12489
12490 @param[in] array_idx array index to append
12491 @return JSON pointer with @a array_idx appended
12492
12493 @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12494
12495 @complexity Amortized constant.
12496
12497 @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12498 @sa see @ref operator/=(std::string) to append a reference token
12499 @sa see @ref operator/(const json_pointer&, std::string) for a binary operator
12500
12501 @since version 3.6.0
12502 */
12503 json_pointer& operator/=(std::size_t array_idx)
12504 {
12505 return *this /= std::to_string(array_idx);
12506 }
12507
12508 /*!
12509 @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
12510
12511 @param[in] lhs JSON pointer
12512 @param[in] rhs JSON pointer
12513 @return a new JSON pointer with @a rhs appended to @a lhs
12514
12515 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12516
12517 @complexity Linear in the length of @a lhs and @a rhs.
12518
12519 @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12520
12521 @since version 3.6.0
12522 */
12523 friend json_pointer operator/(const json_pointer& lhs,
12524 const json_pointer& rhs)
12525 {
12526 return json_pointer(lhs) /= rhs;
12527 }
12528
12529 /*!
12530 @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
12531
12532 @param[in] ptr JSON pointer
12533 @param[in] token reference token
12534 @return a new JSON pointer with unescaped @a token appended to @a ptr
12535
12536 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12537
12538 @complexity Linear in the length of @a ptr.
12539
12540 @sa see @ref operator/=(std::string) to append a reference token
12541
12542 @since version 3.6.0
12543 */
12544 friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param)
12545 {
12546 return json_pointer(ptr) /= std::move(token);
12547 }
12548
12549 /*!
12550 @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
12551
12552 @param[in] ptr JSON pointer
12553 @param[in] array_idx array index
12554 @return a new JSON pointer with @a array_idx appended to @a ptr
12555
12556 @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12557
12558 @complexity Linear in the length of @a ptr.
12559
12560 @sa see @ref operator/=(std::size_t) to append an array index
12561
12562 @since version 3.6.0
12563 */
12564 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
12565 {
12566 return json_pointer(ptr) /= array_idx;
12567 }
12568
12569 /*!
12570 @brief returns the parent of this JSON pointer
12571
12572 @return parent of this JSON pointer; in case this JSON pointer is the root,
12573 the root itself is returned
12574
12575 @complexity Linear in the length of the JSON pointer.
12576
12577 @liveexample{The example shows the result of `parent_pointer` for different
12578 JSON Pointers.,json_pointer__parent_pointer}
12579
12580 @since version 3.6.0
12581 */
12582 json_pointer parent_pointer() const
12583 {
12584 if (empty())
12585 {
12586 return *this;
12587 }
12588
12589 json_pointer res = *this;
12590 res.pop_back();
12591 return res;
12592 }
12593
12594 /*!
12595 @brief remove last reference token
12596
12597 @pre not `empty()`
12598
12599 @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
12600
12601 @complexity Constant.
12602
12603 @throw out_of_range.405 if JSON pointer has no parent
12604
12605 @since version 3.6.0
12606 */
12607 void pop_back()
12608 {
12610 {
12611 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12612 }
12613
12615 }
12616
12617 /*!
12618 @brief return last reference token
12619
12620 @pre not `empty()`
12621 @return last reference token
12622
12623 @liveexample{The example shows the usage of `back`.,json_pointer__back}
12624
12625 @complexity Constant.
12626
12627 @throw out_of_range.405 if JSON pointer has no parent
12628
12629 @since version 3.6.0
12630 */
12631 const std::string& back() const
12632 {
12634 {
12635 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12636 }
12637
12638 return reference_tokens.back();
12639 }
12640
12641 /*!
12642 @brief append an unescaped token at the end of the reference pointer
12643
12644 @param[in] token token to add
12645
12646 @complexity Amortized constant.
12647
12648 @liveexample{The example shows the result of `push_back` for different
12649 JSON Pointers.,json_pointer__push_back}
12650
12651 @since version 3.6.0
12652 */
12653 void push_back(const std::string& token)
12654 {
12656 }
12657
12658 /// @copydoc push_back(const std::string&)
12659 void push_back(std::string&& token)
12660 {
12662 }
12663
12664 /*!
12665 @brief return whether pointer points to the root document
12666
12667 @return true iff the JSON pointer points to the root document
12668
12669 @complexity Constant.
12670
12671 @exceptionsafety No-throw guarantee: this function never throws exceptions.
12672
12673 @liveexample{The example shows the result of `empty` for different JSON
12674 Pointers.,json_pointer__empty}
12675
12676 @since version 3.6.0
12677 */
12678 bool empty() const noexcept
12679 {
12680 return reference_tokens.empty();
12681 }
12682
12683 private:
12684 /*!
12685 @param[in] s reference token to be converted into an array index
12686
12687 @return integer representation of @a s
12688
12689 @throw parse_error.106 if an array index begins with '0'
12690 @throw parse_error.109 if an array index begins not with a digit
12691 @throw out_of_range.404 if string @a s could not be converted to an integer
12692 @throw out_of_range.410 if an array index exceeds size_type
12693 */
12694 static typename BasicJsonType::size_type array_index(const std::string& s)
12695 {
12696 using size_type = typename BasicJsonType::size_type;
12697
12698 // error condition (cf. RFC 6901, Sect. 4)
12699 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
12700 {
12701 JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
12702 }
12703
12704 // error condition (cf. RFC 6901, Sect. 4)
12705 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
12706 {
12707 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
12708 }
12709
12711 unsigned long long res = 0; // NOLINT(runtime/int)
12712 JSON_TRY
12713 {
12715 }
12717 {
12718 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12719 }
12720
12721 // check if the string was completely read
12723 {
12724 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12725 }
12726
12727 // only triggered on special platforms (like 32bit), see also
12728 // https://github.com/nlohmann/json/pull/2203
12729 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
12730 {
12731 JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
12732 }
12733
12734 return static_cast<size_type>(res);
12735 }
12736
12738 json_pointer top() const
12739 {
12741 {
12742 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12743 }
12744
12747 return result;
12748 }
12749
12750 private:
12751 /*!
12752 @brief create and return a reference to the pointed to value
12753
12754 @complexity Linear in the number of reference tokens.
12755
12756 @throw parse_error.109 if array index is not a number
12757 @throw type_error.313 if value cannot be unflattened
12758 */
12759 BasicJsonType& get_and_create(BasicJsonType& j) const
12760 {
12761 auto* result = &j;
12762
12763 // in case no reference tokens exist, return a reference to the JSON value
12764 // j which will be overwritten by a primitive value
12765 for (const auto& reference_token : reference_tokens)
12766 {
12767 switch (result->type())
12768 {
12769 case detail::value_t::null:
12770 {
12771 if (reference_token == "0")
12772 {
12773 // start a new array if reference token is 0
12774 result = &result->operator[](0);
12775 }
12776 else
12777 {
12778 // start a new object otherwise
12780 }
12781 break;
12782 }
12783
12784 case detail::value_t::object:
12785 {
12786 // create an entry in the object
12788 break;
12789 }
12790
12791 case detail::value_t::array:
12792 {
12793 // create an entry in the array
12795 break;
12796 }
12797
12798 /*
12799 The following code is only reached if there exists a reference
12800 token _and_ the current value is primitive. In this case, we have
12801 an error situation, because primitive values may only occur as
12802 single value; that is, with an empty list of reference tokens.
12803 */
12804 case detail::value_t::string:
12805 case detail::value_t::boolean:
12809 case detail::value_t::binary:
12810 case detail::value_t::discarded:
12811 default:
12812 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
12813 }
12814 }
12815
12816 return *result;
12817 }
12818
12819 /*!
12820 @brief return a reference to the pointed to value
12821
12822 @note This version does not throw if a value is not present, but tries to
12823 create nested values instead. For instance, calling this function
12824 with pointer `"/this/that"` on a null value is equivalent to calling
12825 `operator[]("this").operator[]("that")` on that value, effectively
12826 changing the null value to an object.
12827
12828 @param[in] ptr a JSON value
12829
12830 @return reference to the JSON value pointed to by the JSON pointer
12831
12832 @complexity Linear in the length of the JSON pointer.
12833
12834 @throw parse_error.106 if an array index begins with '0'
12835 @throw parse_error.109 if an array index was not a number
12836 @throw out_of_range.404 if the JSON pointer can not be resolved
12837 */
12838 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12839 {
12840 for (const auto& reference_token : reference_tokens)
12841 {
12842 // convert null values to arrays or objects before continuing
12843 if (ptr->is_null())
12844 {
12845 // check if reference token is a number
12846 const bool nums =
12848 [](const unsigned char x)
12849 {
12850 return std::isdigit(x);
12851 });
12852
12853 // change value to array for numbers or "-" or to object otherwise
12854 *ptr = (nums || reference_token == "-")
12855 ? detail::value_t::array
12856 : detail::value_t::object;
12857 }
12858
12859 switch (ptr->type())
12860 {
12861 case detail::value_t::object:
12862 {
12863 // use unchecked object access
12865 break;
12866 }
12867
12868 case detail::value_t::array:
12869 {
12870 if (reference_token == "-")
12871 {
12872 // explicitly treat "-" as index beyond the end
12873 ptr = &ptr->operator[](ptr->m_value.array->size());
12874 }
12875 else
12876 {
12877 // convert array index to number; unchecked access
12879 }
12880 break;
12881 }
12882
12883 case detail::value_t::null:
12884 case detail::value_t::string:
12885 case detail::value_t::boolean:
12889 case detail::value_t::binary:
12890 case detail::value_t::discarded:
12891 default:
12892 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12893 }
12894 }
12895
12896 return *ptr;
12897 }
12898
12899 /*!
12900 @throw parse_error.106 if an array index begins with '0'
12901 @throw parse_error.109 if an array index was not a number
12902 @throw out_of_range.402 if the array index '-' is used
12903 @throw out_of_range.404 if the JSON pointer can not be resolved
12904 */
12905 BasicJsonType& get_checked(BasicJsonType* ptr) const
12906 {
12907 for (const auto& reference_token : reference_tokens)
12908 {
12909 switch (ptr->type())
12910 {
12911 case detail::value_t::object:
12912 {
12913 // note: at performs range check
12915 break;
12916 }
12917
12918 case detail::value_t::array:
12919 {
12921 {
12922 // "-" always fails the range check
12924 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12925 ") is out of range", *ptr));
12926 }
12927
12928 // note: at performs range check
12930 break;
12931 }
12932
12933 case detail::value_t::null:
12934 case detail::value_t::string:
12935 case detail::value_t::boolean:
12939 case detail::value_t::binary:
12940 case detail::value_t::discarded:
12941 default:
12942 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12943 }
12944 }
12945
12946 return *ptr;
12947 }
12948
12949 /*!
12950 @brief return a const reference to the pointed to value
12951
12952 @param[in] ptr a JSON value
12953
12954 @return const reference to the JSON value pointed to by the JSON
12955 pointer
12956
12957 @throw parse_error.106 if an array index begins with '0'
12958 @throw parse_error.109 if an array index was not a number
12959 @throw out_of_range.402 if the array index '-' is used
12960 @throw out_of_range.404 if the JSON pointer can not be resolved
12961 */
12962 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
12963 {
12964 for (const auto& reference_token : reference_tokens)
12965 {
12966 switch (ptr->type())
12967 {
12968 case detail::value_t::object:
12969 {
12970 // use unchecked object access
12972 break;
12973 }
12974
12975 case detail::value_t::array:
12976 {
12978 {
12979 // "-" cannot be used for const access
12980 JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
12981 }
12982
12983 // use unchecked array access
12985 break;
12986 }
12987
12988 case detail::value_t::null:
12989 case detail::value_t::string:
12990 case detail::value_t::boolean:
12994 case detail::value_t::binary:
12995 case detail::value_t::discarded:
12996 default:
12997 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12998 }
12999 }
13000
13001 return *ptr;
13002 }
13003
13004 /*!
13005 @throw parse_error.106 if an array index begins with '0'
13006 @throw parse_error.109 if an array index was not a number
13007 @throw out_of_range.402 if the array index '-' is used
13008 @throw out_of_range.404 if the JSON pointer can not be resolved
13009 */
13010 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
13011 {
13012 for (const auto& reference_token : reference_tokens)
13013 {
13014 switch (ptr->type())
13015 {
13016 case detail::value_t::object:
13017 {
13018 // note: at performs range check
13020 break;
13021 }
13022
13023 case detail::value_t::array:
13024 {
13026 {
13027 // "-" always fails the range check
13029 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13030 ") is out of range", *ptr));
13031 }
13032
13033 // note: at performs range check
13035 break;
13036 }
13037
13038 case detail::value_t::null:
13039 case detail::value_t::string:
13040 case detail::value_t::boolean:
13044 case detail::value_t::binary:
13045 case detail::value_t::discarded:
13046 default:
13047 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13048 }
13049 }
13050
13051 return *ptr;
13052 }
13053
13054 /*!
13055 @throw parse_error.106 if an array index begins with '0'
13056 @throw parse_error.109 if an array index was not a number
13057 */
13058 bool contains(const BasicJsonType* ptr) const
13059 {
13060 for (const auto& reference_token : reference_tokens)
13061 {
13062 switch (ptr->type())
13063 {
13064 case detail::value_t::object:
13065 {
13067 {
13068 // we did not find the key in the object
13069 return false;
13070 }
13071
13073 break;
13074 }
13075
13076 case detail::value_t::array:
13077 {
13079 {
13080 // "-" always fails the range check
13081 return false;
13082 }
13083 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13084 {
13085 // invalid char
13086 return false;
13087 }
13089 {
13090 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13091 {
13092 // first char should be between '1' and '9'
13093 return false;
13094 }
13095 for (std::size_t i = 1; i < reference_token.size(); i++)
13096 {
13097 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13098 {
13099 // other char should be between '0' and '9'
13100 return false;
13101 }
13102 }
13103 }
13104
13105 const auto idx = array_index(reference_token);
13106 if (idx >= ptr->size())
13107 {
13108 // index out of range
13109 return false;
13110 }
13111
13112 ptr = &ptr->operator[](idx);
13113 break;
13114 }
13115
13116 case detail::value_t::null:
13117 case detail::value_t::string:
13118 case detail::value_t::boolean:
13122 case detail::value_t::binary:
13123 case detail::value_t::discarded:
13124 default:
13125 {
13126 // we do not expect primitive values if there is still a
13127 // reference token to process
13128 return false;
13129 }
13130 }
13131 }
13132
13133 // no reference token left means we found a primitive value
13134 return true;
13135 }
13136
13137 /*!
13138 @brief split the string input to reference tokens
13139
13140 @note This function is only called by the json_pointer constructor.
13141 All exceptions below are documented there.
13142
13143 @throw parse_error.107 if the pointer is not empty or begins with '/'
13144 @throw parse_error.108 if character '~' is not followed by '0' or '1'
13145 */
13146 static std::vector<std::string> split(const std::string& reference_string)
13147 {
13149
13150 // special case: empty reference string -> no reference tokens
13151 if (reference_string.empty())
13152 {
13153 return result;
13154 }
13155
13156 // check if nonempty reference string begins with slash
13158 {
13159 JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
13160 }
13161
13162 // extract the reference tokens:
13163 // - slash: position of the last read slash (or end of string)
13164 // - start: position after the previous slash
13165 for (
13166 // search for the first slash after the first character
13168 // set the beginning of the first reference token
13169 start = 1;
13170 // we can stop if start == 0 (if slash == std::string::npos)
13171 start != 0;
13172 // set the beginning of the next reference token
13173 // (will eventually be 0 if slash == std::string::npos)
13174 start = (slash == std::string::npos) ? 0 : slash + 1,
13175 // find next slash
13177 {
13178 // use the text between the beginning of the reference token
13179 // (start) and the last slash (slash).
13181
13182 // check reference tokens are properly escaped
13184 pos != std::string::npos;
13186 {
13188
13189 // ~ must be followed by 0 or 1
13191 (reference_token[pos + 1] != '0' &&
13192 reference_token[pos + 1] != '1')))
13193 {
13194 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
13195 }
13196 }
13197
13198 // finally, store the reference token
13201 }
13202
13203 return result;
13204 }
13205
13206 private:
13207 /*!
13208 @param[in] reference_string the reference string to the current value
13209 @param[in] value the value to consider
13210 @param[in,out] result the result object to insert values to
13211
13212 @note Empty objects or arrays are flattened to `null`.
13213 */
13214 static void flatten(const std::string& reference_string,
13215 const BasicJsonType& value,
13216 BasicJsonType& result)
13217 {
13218 switch (value.type())
13219 {
13220 case detail::value_t::array:
13221 {
13222 if (value.m_value.array->empty())
13223 {
13224 // flatten empty array as null
13225 result[reference_string] = nullptr;
13226 }
13227 else
13228 {
13229 // iterate array and use index as reference string
13230 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13231 {
13234 }
13235 }
13236 break;
13237 }
13238
13239 case detail::value_t::object:
13240 {
13241 if (value.m_value.object->empty())
13242 {
13243 // flatten empty object as null
13244 result[reference_string] = nullptr;
13245 }
13246 else
13247 {
13248 // iterate object and use keys as reference string
13249 for (const auto& element : *value.m_value.object)
13250 {
13252 }
13253 }
13254 break;
13255 }
13256
13257 case detail::value_t::null:
13258 case detail::value_t::string:
13259 case detail::value_t::boolean:
13263 case detail::value_t::binary:
13264 case detail::value_t::discarded:
13265 default:
13266 {
13267 // add primitive value with its reference string
13269 break;
13270 }
13271 }
13272 }
13273
13274 /*!
13275 @param[in] value flattened JSON
13276
13277 @return unflattened JSON
13278
13279 @throw parse_error.109 if array index is not a number
13280 @throw type_error.314 if value is not an object
13281 @throw type_error.315 if object values are not primitive
13282 @throw type_error.313 if value cannot be unflattened
13283 */
13284 static BasicJsonType
13285 unflatten(const BasicJsonType& value)
13286 {
13288 {
13289 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
13290 }
13291
13293
13294 // iterate the JSON object values
13295 for (const auto& element : *value.m_value.object)
13296 {
13298 {
13299 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
13300 }
13301
13302 // assign value to reference pointed to by JSON pointer; Note that if
13303 // the JSON pointer is "" (i.e., points to the whole value), function
13304 // get_and_create returns a reference to result itself. An assignment
13305 // will then create a primitive value.
13307 }
13308
13309 return result;
13310 }
13311
13312 /*!
13313 @brief compares two JSON pointers for equality
13314
13315 @param[in] lhs JSON pointer to compare
13316 @param[in] rhs JSON pointer to compare
13317 @return whether @a lhs is equal to @a rhs
13318
13319 @complexity Linear in the length of the JSON pointer
13320
13321 @exceptionsafety No-throw guarantee: this function never throws exceptions.
13322 */
13323 friend bool operator==(json_pointer const& lhs,
13324 json_pointer const& rhs) noexcept
13325 {
13327 }
13328
13329 /*!
13330 @brief compares two JSON pointers for inequality
13331
13332 @param[in] lhs JSON pointer to compare
13333 @param[in] rhs JSON pointer to compare
13334 @return whether @a lhs is not equal @a rhs
13335
13336 @complexity Linear in the length of the JSON pointer
13337
13338 @exceptionsafety No-throw guarantee: this function never throws exceptions.
13339 */
13340 friend bool operator!=(json_pointer const& lhs,
13341 json_pointer const& rhs) noexcept
13342 {
13343 return !(lhs == rhs);
13344 }
13345
13346 /// the reference tokens
13347 std::vector<std::string> reference_tokens;
13348 };
13349} // namespace nlohmann
13350
13351// #include <nlohmann/detail/json_ref.hpp>
13352
13353
13354#include <initializer_list>
13355#include <utility>
13356
13357// #include <nlohmann/detail/meta/type_traits.hpp>
13358
13359
13360namespace nlohmann
13361{
13362 namespace detail
13363 {
13364 template<typename BasicJsonType>
13366 {
13367 public:
13368 using value_type = BasicJsonType;
13369
13370 json_ref(value_type&& value)
13372 {}
13373
13374 json_ref(const value_type& value)
13375 : value_ref(&value)
13376 {}
13377
13378 json_ref(std::initializer_list<json_ref> init)
13379 : owned_value(init)
13380 {}
13381
13382 template <
13383 class... Args,
13384 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13385 json_ref(Args && ... args)
13387 {}
13388
13389 // class should be movable only
13390 json_ref(json_ref&&) noexcept = default;
13391 json_ref(const json_ref&) = delete;
13392 json_ref& operator=(const json_ref&) = delete;
13394 ~json_ref() = default;
13395
13396 value_type moved_or_copied() const
13397 {
13398 if (value_ref == nullptr)
13399 {
13400 return std::move(owned_value);
13401 }
13402 return *value_ref;
13403 }
13404
13405 value_type const& operator*() const
13406 {
13407 return value_ref ? *value_ref : owned_value;
13408 }
13409
13410 value_type const* operator->() const
13411 {
13412 return &**this;
13413 }
13414
13415 private:
13416 mutable value_type owned_value = nullptr;
13417 value_type const* value_ref = nullptr;
13418 };
13419 } // namespace detail
13420} // namespace nlohmann
13421
13422// #include <nlohmann/detail/macro_scope.hpp>
13423
13424// #include <nlohmann/detail/string_escape.hpp>
13425
13426// #include <nlohmann/detail/meta/cpp_future.hpp>
13427
13428// #include <nlohmann/detail/meta/type_traits.hpp>
13429
13430// #include <nlohmann/detail/output/binary_writer.hpp>
13431
13432
13433#include <algorithm> // reverse
13434#include <array> // array
13435#include <cmath> // isnan, isinf
13436#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13437#include <cstring> // memcpy
13438#include <limits> // numeric_limits
13439#include <string> // string
13440#include <utility> // move
13441
13442// #include <nlohmann/detail/input/binary_reader.hpp>
13443
13444// #include <nlohmann/detail/macro_scope.hpp>
13445
13446// #include <nlohmann/detail/output/output_adapters.hpp>
13447
13448
13449#include <algorithm> // copy
13450#include <cstddef> // size_t
13451#include <iterator> // back_inserter
13452#include <memory> // shared_ptr, make_shared
13453#include <string> // basic_string
13454#include <vector> // vector
13455
13456#ifndef JSON_NO_IO
13457#include <ios> // streamsize
13458#include <ostream> // basic_ostream
13459#endif // JSON_NO_IO
13460
13461// #include <nlohmann/detail/macro_scope.hpp>
13462
13463
13464namespace nlohmann
13465{
13466 namespace detail
13467 {
13468 /// abstract output adapter interface
13469 template<typename CharType> struct output_adapter_protocol
13470 {
13471 virtual void write_character(CharType c) = 0;
13472 virtual void write_characters(const CharType* s, std::size_t length) = 0;
13473 virtual ~output_adapter_protocol() = default;
13474
13480 };
13481
13482 /// a type to simplify interfaces
13483 template<typename CharType>
13484 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13485
13486 /// output adapter for byte vectors
13487 template<typename CharType>
13489 {
13490 public:
13491 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
13492 : v(vec)
13493 {}
13494
13495 void write_character(CharType c) override
13496 {
13497 v.push_back(c);
13498 }
13499
13501 void write_characters(const CharType* s, std::size_t length) override
13502 {
13503 std::copy(s, s + length, std::back_inserter(v));
13504 }
13505
13506 private:
13508 };
13509
13510#ifndef JSON_NO_IO
13511 /// output adapter for output streams
13512 template<typename CharType>
13514 {
13515 public:
13516 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13517 : stream(s)
13518 {}
13519
13520 void write_character(CharType c) override
13521 {
13522 stream.put(c);
13523 }
13524
13526 void write_characters(const CharType* s, std::size_t length) override
13527 {
13528 stream.write(s, static_cast<std::streamsize>(length));
13529 }
13530
13531 private:
13533 };
13534#endif // JSON_NO_IO
13535
13536 /// output adapter for basic_string
13537 template<typename CharType, typename StringType = std::basic_string<CharType>>
13539 {
13540 public:
13541 explicit output_string_adapter(StringType& s) noexcept
13542 : str(s)
13543 {}
13544
13545 void write_character(CharType c) override
13546 {
13547 str.push_back(c);
13548 }
13549
13551 void write_characters(const CharType* s, std::size_t length) override
13552 {
13553 str.append(s, length);
13554 }
13555
13556 private:
13557 StringType& str;
13558 };
13559
13560 template<typename CharType, typename StringType = std::basic_string<CharType>>
13562 {
13563 public:
13564 output_adapter(std::vector<CharType>& vec)
13566
13567#ifndef JSON_NO_IO
13568 output_adapter(std::basic_ostream<CharType>& s)
13570#endif // JSON_NO_IO
13571
13572 output_adapter(StringType& s)
13574
13576 {
13577 return oa;
13578 }
13579
13580 private:
13582 };
13583 } // namespace detail
13584} // namespace nlohmann
13585
13586
13587namespace nlohmann
13588{
13589 namespace detail
13590 {
13591 ///////////////////
13592 // binary writer //
13593 ///////////////////
13594
13595 /*!
13596 @brief serialization to CBOR and MessagePack values
13597 */
13598 template<typename BasicJsonType, typename CharType>
13600 {
13601 using string_t = typename BasicJsonType::string_t;
13602 using binary_t = typename BasicJsonType::binary_t;
13603 using number_float_t = typename BasicJsonType::number_float_t;
13604
13605 public:
13606 /*!
13607 @brief create a binary writer
13608
13609 @param[in] adapter output adapter to write to
13610 */
13611 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
13612 {
13613 JSON_ASSERT(oa);
13614 }
13615
13616 /*!
13617 @param[in] j JSON value to serialize
13618 @pre j.type() == value_t::object
13619 */
13620 void write_bson(const BasicJsonType& j)
13621 {
13622 switch (j.type())
13623 {
13624 case value_t::object:
13625 {
13627 break;
13628 }
13629
13630 case value_t::null:
13631 case value_t::array:
13632 case value_t::string:
13633 case value_t::boolean:
13634 case value_t::number_integer:
13636 case value_t::number_float:
13637 case value_t::binary:
13638 case value_t::discarded:
13639 default:
13640 {
13641 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));
13642 }
13643 }
13644 }
13645
13646 /*!
13647 @param[in] j JSON value to serialize
13648 */
13649 void write_cbor(const BasicJsonType& j)
13650 {
13651 switch (j.type())
13652 {
13653 case value_t::null:
13654 {
13656 break;
13657 }
13658
13659 case value_t::boolean:
13660 {
13662 ? to_char_type(0xF5)
13663 : to_char_type(0xF4));
13664 break;
13665 }
13666
13667 case value_t::number_integer:
13668 {
13669 if (j.m_value.number_integer >= 0)
13670 {
13671 // CBOR does not differentiate between positive signed
13672 // integers and unsigned integers. Therefore, we used the
13673 // code from the value_t::number_unsigned case here.
13674 if (j.m_value.number_integer <= 0x17)
13675 {
13677 }
13679 {
13682 }
13684 {
13687 }
13689 {
13692 }
13693 else
13694 {
13697 }
13698 }
13699 else
13700 {
13701 // The conversions below encode the sign in the first
13702 // byte, and the value is converted to a positive number.
13703 const auto positive_number = -1 - j.m_value.number_integer;
13704 if (j.m_value.number_integer >= -24)
13705 {
13706 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
13707 }
13708 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
13709 {
13711 write_number(static_cast<std::uint8_t>(positive_number));
13712 }
13713 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
13714 {
13716 write_number(static_cast<std::uint16_t>(positive_number));
13717 }
13718 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
13719 {
13721 write_number(static_cast<std::uint32_t>(positive_number));
13722 }
13723 else
13724 {
13726 write_number(static_cast<std::uint64_t>(positive_number));
13727 }
13728 }
13729 break;
13730 }
13731
13733 {
13734 if (j.m_value.number_unsigned <= 0x17)
13735 {
13737 }
13739 {
13742 }
13744 {
13747 }
13749 {
13752 }
13753 else
13754 {
13757 }
13758 break;
13759 }
13760
13761 case value_t::number_float:
13762 {
13764 {
13765 // NaN is 0xf97e00 in CBOR
13769 }
13770 else if (std::isinf(j.m_value.number_float))
13771 {
13772 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
13776 }
13777 else
13778 {
13780 }
13781 break;
13782 }
13783
13784 case value_t::string:
13785 {
13786 // step 1: write control byte and the string length
13787 const auto N = j.m_value.string->size();
13788 if (N <= 0x17)
13789 {
13790 write_number(static_cast<std::uint8_t>(0x60 + N));
13791 }
13792 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13793 {
13795 write_number(static_cast<std::uint8_t>(N));
13796 }
13797 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13798 {
13800 write_number(static_cast<std::uint16_t>(N));
13801 }
13802 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13803 {
13805 write_number(static_cast<std::uint32_t>(N));
13806 }
13807 // LCOV_EXCL_START
13808 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13809 {
13811 write_number(static_cast<std::uint64_t>(N));
13812 }
13813 // LCOV_EXCL_STOP
13814
13815 // step 2: write the string
13817 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13818 j.m_value.string->size());
13819 break;
13820 }
13821
13822 case value_t::array:
13823 {
13824 // step 1: write control byte and the array size
13825 const auto N = j.m_value.array->size();
13826 if (N <= 0x17)
13827 {
13828 write_number(static_cast<std::uint8_t>(0x80 + N));
13829 }
13830 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13831 {
13833 write_number(static_cast<std::uint8_t>(N));
13834 }
13835 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13836 {
13838 write_number(static_cast<std::uint16_t>(N));
13839 }
13840 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13841 {
13843 write_number(static_cast<std::uint32_t>(N));
13844 }
13845 // LCOV_EXCL_START
13846 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13847 {
13849 write_number(static_cast<std::uint64_t>(N));
13850 }
13851 // LCOV_EXCL_STOP
13852
13853 // step 2: write each element
13854 for (const auto& el : *j.m_value.array)
13855 {
13856 write_cbor(el);
13857 }
13858 break;
13859 }
13860
13861 case value_t::binary:
13862 {
13863 if (j.m_value.binary->has_subtype())
13864 {
13866 {
13867 write_number(static_cast<std::uint8_t>(0xd8));
13868 write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
13869 }
13870 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
13871 {
13872 write_number(static_cast<std::uint8_t>(0xd9));
13873 write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
13874 }
13875 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
13876 {
13877 write_number(static_cast<std::uint8_t>(0xda));
13878 write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
13879 }
13880 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
13881 {
13882 write_number(static_cast<std::uint8_t>(0xdb));
13883 write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
13884 }
13885 }
13886
13887 // step 1: write control byte and the binary array size
13888 const auto N = j.m_value.binary->size();
13889 if (N <= 0x17)
13890 {
13891 write_number(static_cast<std::uint8_t>(0x40 + N));
13892 }
13893 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13894 {
13896 write_number(static_cast<std::uint8_t>(N));
13897 }
13898 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13899 {
13901 write_number(static_cast<std::uint16_t>(N));
13902 }
13903 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13904 {
13906 write_number(static_cast<std::uint32_t>(N));
13907 }
13908 // LCOV_EXCL_START
13909 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13910 {
13912 write_number(static_cast<std::uint64_t>(N));
13913 }
13914 // LCOV_EXCL_STOP
13915
13916 // step 2: write each element
13918 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13919 N);
13920
13921 break;
13922 }
13923
13924 case value_t::object:
13925 {
13926 // step 1: write control byte and the object size
13927 const auto N = j.m_value.object->size();
13928 if (N <= 0x17)
13929 {
13930 write_number(static_cast<std::uint8_t>(0xA0 + N));
13931 }
13932 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13933 {
13935 write_number(static_cast<std::uint8_t>(N));
13936 }
13937 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13938 {
13940 write_number(static_cast<std::uint16_t>(N));
13941 }
13942 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13943 {
13945 write_number(static_cast<std::uint32_t>(N));
13946 }
13947 // LCOV_EXCL_START
13948 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13949 {
13951 write_number(static_cast<std::uint64_t>(N));
13952 }
13953 // LCOV_EXCL_STOP
13954
13955 // step 2: write each element
13956 for (const auto& el : *j.m_value.object)
13957 {
13960 }
13961 break;
13962 }
13963
13964 case value_t::discarded:
13965 default:
13966 break;
13967 }
13968 }
13969
13970 /*!
13971 @param[in] j JSON value to serialize
13972 */
13973 void write_msgpack(const BasicJsonType& j)
13974 {
13975 switch (j.type())
13976 {
13977 case value_t::null: // nil
13978 {
13980 break;
13981 }
13982
13983 case value_t::boolean: // true and false
13984 {
13986 ? to_char_type(0xC3)
13987 : to_char_type(0xC2));
13988 break;
13989 }
13990
13991 case value_t::number_integer:
13992 {
13993 if (j.m_value.number_integer >= 0)
13994 {
13995 // MessagePack does not differentiate between positive
13996 // signed integers and unsigned integers. Therefore, we used
13997 // the code from the value_t::number_unsigned case here.
13998 if (j.m_value.number_unsigned < 128)
13999 {
14000 // positive fixnum
14002 }
14004 {
14005 // uint 8
14008 }
14010 {
14011 // uint 16
14014 }
14016 {
14017 // uint 32
14020 }
14022 {
14023 // uint 64
14026 }
14027 }
14028 else
14029 {
14030 if (j.m_value.number_integer >= -32)
14031 {
14032 // negative fixnum
14034 }
14035 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14037 {
14038 // int 8
14041 }
14042 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14044 {
14045 // int 16
14048 }
14049 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14051 {
14052 // int 32
14055 }
14056 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14058 {
14059 // int 64
14062 }
14063 }
14064 break;
14065 }
14066
14068 {
14069 if (j.m_value.number_unsigned < 128)
14070 {
14071 // positive fixnum
14073 }
14075 {
14076 // uint 8
14079 }
14081 {
14082 // uint 16
14085 }
14087 {
14088 // uint 32
14091 }
14093 {
14094 // uint 64
14097 }
14098 break;
14099 }
14100
14101 case value_t::number_float:
14102 {
14104 break;
14105 }
14106
14107 case value_t::string:
14108 {
14109 // step 1: write control byte and the string length
14110 const auto N = j.m_value.string->size();
14111 if (N <= 31)
14112 {
14113 // fixstr
14114 write_number(static_cast<std::uint8_t>(0xA0 | N));
14115 }
14116 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14117 {
14118 // str 8
14120 write_number(static_cast<std::uint8_t>(N));
14121 }
14122 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14123 {
14124 // str 16
14126 write_number(static_cast<std::uint16_t>(N));
14127 }
14128 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14129 {
14130 // str 32
14132 write_number(static_cast<std::uint32_t>(N));
14133 }
14134
14135 // step 2: write the string
14137 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14138 j.m_value.string->size());
14139 break;
14140 }
14141
14142 case value_t::array:
14143 {
14144 // step 1: write control byte and the array size
14145 const auto N = j.m_value.array->size();
14146 if (N <= 15)
14147 {
14148 // fixarray
14149 write_number(static_cast<std::uint8_t>(0x90 | N));
14150 }
14151 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14152 {
14153 // array 16
14155 write_number(static_cast<std::uint16_t>(N));
14156 }
14157 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14158 {
14159 // array 32
14161 write_number(static_cast<std::uint32_t>(N));
14162 }
14163
14164 // step 2: write each element
14165 for (const auto& el : *j.m_value.array)
14166 {
14168 }
14169 break;
14170 }
14171
14172 case value_t::binary:
14173 {
14174 // step 0: determine if the binary type has a set subtype to
14175 // determine whether or not to use the ext or fixext types
14176 const bool use_ext = j.m_value.binary->has_subtype();
14177
14178 // step 1: write control byte and the byte string length
14179 const auto N = j.m_value.binary->size();
14180 if (N <= (std::numeric_limits<std::uint8_t>::max)())
14181 {
14183 bool fixed = true;
14184 if (use_ext)
14185 {
14186 switch (N)
14187 {
14188 case 1:
14189 output_type = 0xD4; // fixext 1
14190 break;
14191 case 2:
14192 output_type = 0xD5; // fixext 2
14193 break;
14194 case 4:
14195 output_type = 0xD6; // fixext 4
14196 break;
14197 case 8:
14198 output_type = 0xD7; // fixext 8
14199 break;
14200 case 16:
14201 output_type = 0xD8; // fixext 16
14202 break;
14203 default:
14204 output_type = 0xC7; // ext 8
14205 fixed = false;
14206 break;
14207 }
14208
14209 }
14210 else
14211 {
14212 output_type = 0xC4; // bin 8
14213 fixed = false;
14214 }
14215
14217 if (!fixed)
14218 {
14219 write_number(static_cast<std::uint8_t>(N));
14220 }
14221 }
14222 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14223 {
14225 ? 0xC8 // ext 16
14226 : 0xC5; // bin 16
14227
14229 write_number(static_cast<std::uint16_t>(N));
14230 }
14231 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14232 {
14234 ? 0xC9 // ext 32
14235 : 0xC6; // bin 32
14236
14238 write_number(static_cast<std::uint32_t>(N));
14239 }
14240
14241 // step 1.5: if this is an ext type, write the subtype
14242 if (use_ext)
14243 {
14244 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14245 }
14246
14247 // step 2: write the byte string
14249 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14250 N);
14251
14252 break;
14253 }
14254
14255 case value_t::object:
14256 {
14257 // step 1: write control byte and the object size
14258 const auto N = j.m_value.object->size();
14259 if (N <= 15)
14260 {
14261 // fixmap
14262 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
14263 }
14264 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14265 {
14266 // map 16
14268 write_number(static_cast<std::uint16_t>(N));
14269 }
14270 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14271 {
14272 // map 32
14274 write_number(static_cast<std::uint32_t>(N));
14275 }
14276
14277 // step 2: write each element
14278 for (const auto& el : *j.m_value.object)
14279 {
14282 }
14283 break;
14284 }
14285
14286 case value_t::discarded:
14287 default:
14288 break;
14289 }
14290 }
14291
14292 /*!
14293 @param[in] j JSON value to serialize
14294 @param[in] use_count whether to use '#' prefixes (optimized format)
14295 @param[in] use_type whether to use '$' prefixes (optimized format)
14296 @param[in] add_prefix whether prefixes need to be used for this value
14297 */
14298 void write_ubjson(const BasicJsonType& j, const bool use_count,
14299 const bool use_type, const bool add_prefix = true)
14300 {
14301 switch (j.type())
14302 {
14303 case value_t::null:
14304 {
14305 if (add_prefix)
14306 {
14308 }
14309 break;
14310 }
14311
14312 case value_t::boolean:
14313 {
14314 if (add_prefix)
14315 {
14317 ? to_char_type('T')
14318 : to_char_type('F'));
14319 }
14320 break;
14321 }
14322
14323 case value_t::number_integer:
14324 {
14326 break;
14327 }
14328
14330 {
14332 break;
14333 }
14334
14335 case value_t::number_float:
14336 {
14338 break;
14339 }
14340
14341 case value_t::string:
14342 {
14343 if (add_prefix)
14344 {
14346 }
14349 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14350 j.m_value.string->size());
14351 break;
14352 }
14353
14354 case value_t::array:
14355 {
14356 if (add_prefix)
14357 {
14359 }
14360
14361 bool prefix_required = true;
14362 if (use_type && !j.m_value.array->empty())
14363 {
14366 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14367 [this, first_prefix](const BasicJsonType& v)
14368 {
14369 return ubjson_prefix(v) == first_prefix;
14370 });
14371
14372 if (same_prefix)
14373 {
14374 prefix_required = false;
14377 }
14378 }
14379
14380 if (use_count)
14381 {
14384 }
14385
14386 for (const auto& el : *j.m_value.array)
14387 {
14389 }
14390
14391 if (!use_count)
14392 {
14394 }
14395
14396 break;
14397 }
14398
14399 case value_t::binary:
14400 {
14401 if (add_prefix)
14402 {
14404 }
14405
14406 if (use_type && !j.m_value.binary->empty())
14407 {
14410 oa->write_character('U');
14411 }
14412
14413 if (use_count)
14414 {
14417 }
14418
14419 if (use_type)
14420 {
14422 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14423 j.m_value.binary->size());
14424 }
14425 else
14426 {
14427 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14428 {
14431 }
14432 }
14433
14434 if (!use_count)
14435 {
14437 }
14438
14439 break;
14440 }
14441
14442 case value_t::object:
14443 {
14444 if (add_prefix)
14445 {
14447 }
14448
14449 bool prefix_required = true;
14450 if (use_type && !j.m_value.object->empty())
14451 {
14454 const bool same_prefix = std::all_of(j.begin(), j.end(),
14455 [this, first_prefix](const BasicJsonType& v)
14456 {
14457 return ubjson_prefix(v) == first_prefix;
14458 });
14459
14460 if (same_prefix)
14461 {
14462 prefix_required = false;
14465 }
14466 }
14467
14468 if (use_count)
14469 {
14472 }
14473
14474 for (const auto& el : *j.m_value.object)
14475 {
14478 reinterpret_cast<const CharType*>(el.first.c_str()),
14479 el.first.size());
14481 }
14482
14483 if (!use_count)
14484 {
14486 }
14487
14488 break;
14489 }
14490
14491 case value_t::discarded:
14492 default:
14493 break;
14494 }
14495 }
14496
14497 private:
14498 //////////
14499 // BSON //
14500 //////////
14501
14502 /*!
14503 @return The size of a BSON document entry header, including the id marker
14504 and the entry name size (and its null-terminator).
14505 */
14506 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14507 {
14508 const auto it = name.find(static_cast<typename string_t::value_type>(0));
14510 {
14511 JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
14512 static_cast<void>(j);
14513 }
14514
14515 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14516 }
14517
14518 /*!
14519 @brief Writes the given @a element_type and @a name to the output adapter
14520 */
14521 void write_bson_entry_header(const string_t& name,
14522 const std::uint8_t element_type)
14523 {
14526 reinterpret_cast<const CharType*>(name.c_str()),
14527 name.size() + 1u);
14528 }
14529
14530 /*!
14531 @brief Writes a BSON element with key @a name and boolean value @a value
14532 */
14533 void write_bson_boolean(const string_t& name,
14534 const bool value)
14535 {
14538 }
14539
14540 /*!
14541 @brief Writes a BSON element with key @a name and double value @a value
14542 */
14543 void write_bson_double(const string_t& name,
14544 const double value)
14545 {
14547 write_number<double, true>(value);
14548 }
14549
14550 /*!
14551 @return The size of the BSON-encoded string in @a value
14552 */
14553 static std::size_t calc_bson_string_size(const string_t& value)
14554 {
14555 return sizeof(std::int32_t) + value.size() + 1ul;
14556 }
14557
14558 /*!
14559 @brief Writes a BSON element with key @a name and string value @a value
14560 */
14561 void write_bson_string(const string_t& name,
14562 const string_t& value)
14563 {
14565
14566 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
14568 reinterpret_cast<const CharType*>(value.c_str()),
14569 value.size() + 1);
14570 }
14571
14572 /*!
14573 @brief Writes a BSON element with key @a name and null value
14574 */
14575 void write_bson_null(const string_t& name)
14576 {
14578 }
14579
14580 /*!
14581 @return The size of the BSON-encoded integer @a value
14582 */
14583 static std::size_t calc_bson_integer_size(const std::int64_t value)
14584 {
14585 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
14586 ? sizeof(std::int32_t)
14587 : sizeof(std::int64_t);
14588 }
14589
14590 /*!
14591 @brief Writes a BSON element with key @a name and integer @a value
14592 */
14593 void write_bson_integer(const string_t& name,
14594 const std::int64_t value)
14595 {
14596 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
14597 {
14598 write_bson_entry_header(name, 0x10); // int32
14599 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
14600 }
14601 else
14602 {
14603 write_bson_entry_header(name, 0x12); // int64
14604 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
14605 }
14606 }
14607
14608 /*!
14609 @return The size of the BSON-encoded unsigned integer in @a j
14610 */
14611 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
14612 {
14613 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14614 ? sizeof(std::int32_t)
14615 : sizeof(std::int64_t);
14616 }
14617
14618 /*!
14619 @brief Writes a BSON element with key @a name and unsigned @a value
14620 */
14621 void write_bson_unsigned(const string_t& name,
14622 const BasicJsonType& j)
14623 {
14624 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14625 {
14626 write_bson_entry_header(name, 0x10 /* int32 */);
14627 write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
14628 }
14629 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14630 {
14631 write_bson_entry_header(name, 0x12 /* int64 */);
14632 write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
14633 }
14634 else
14635 {
14636 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));
14637 }
14638 }
14639
14640 /*!
14641 @brief Writes a BSON element with key @a name and object @a value
14642 */
14643 void write_bson_object_entry(const string_t& name,
14644 const typename BasicJsonType::object_t& value)
14645 {
14646 write_bson_entry_header(name, 0x03); // object
14648 }
14649
14650 /*!
14651 @return The size of the BSON-encoded array @a value
14652 */
14653 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
14654 {
14655 std::size_t array_index = 0ul;
14656
14658 {
14660 });
14661
14662 return sizeof(std::int32_t) + embedded_document_size + 1ul;
14663 }
14664
14665 /*!
14666 @return The size of the BSON-encoded binary array @a value
14667 */
14668 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
14669 {
14670 return sizeof(std::int32_t) + value.size() + 1ul;
14671 }
14672
14673 /*!
14674 @brief Writes a BSON element with key @a name and array @a value
14675 */
14676 void write_bson_array(const string_t& name,
14677 const typename BasicJsonType::array_t& value)
14678 {
14679 write_bson_entry_header(name, 0x04); // array
14680 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
14681
14682 std::size_t array_index = 0ul;
14683
14684 for (const auto& el : value)
14685 {
14687 }
14688
14690 }
14691
14692 /*!
14693 @brief Writes a BSON element with key @a name and binary value @a value
14694 */
14695 void write_bson_binary(const string_t& name,
14696 const binary_t& value)
14697 {
14699
14700 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
14701 write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : std::uint8_t(0x00));
14702
14703 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
14704 }
14705
14706 /*!
14707 @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
14708 @return The calculated size for the BSON document entry for @a j with the given @a name.
14709 */
14710 static std::size_t calc_bson_element_size(const string_t& name,
14711 const BasicJsonType& j)
14712 {
14714 switch (j.type())
14715 {
14716 case value_t::object:
14718
14719 case value_t::array:
14721
14722 case value_t::binary:
14724
14725 case value_t::boolean:
14726 return header_size + 1ul;
14727
14728 case value_t::number_float:
14729 return header_size + 8ul;
14730
14731 case value_t::number_integer:
14733
14736
14737 case value_t::string:
14739
14740 case value_t::null:
14741 return header_size + 0ul;
14742
14743 // LCOV_EXCL_START
14744 case value_t::discarded:
14745 default:
14746 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14747 return 0ul;
14748 // LCOV_EXCL_STOP
14749 }
14750 }
14751
14752 /*!
14753 @brief Serializes the JSON value @a j to BSON and associates it with the
14754 key @a name.
14755 @param name The name to associate with the JSON entity @a j within the
14756 current BSON document
14757 */
14758 void write_bson_element(const string_t& name,
14759 const BasicJsonType& j)
14760 {
14761 switch (j.type())
14762 {
14763 case value_t::object:
14765
14766 case value_t::array:
14768
14769 case value_t::binary:
14771
14772 case value_t::boolean:
14774
14775 case value_t::number_float:
14777
14778 case value_t::number_integer:
14780
14782 return write_bson_unsigned(name, j);
14783
14784 case value_t::string:
14786
14787 case value_t::null:
14788 return write_bson_null(name);
14789
14790 // LCOV_EXCL_START
14791 case value_t::discarded:
14792 default:
14793 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14794 return;
14795 // LCOV_EXCL_STOP
14796 }
14797 }
14798
14799 /*!
14800 @brief Calculates the size of the BSON serialization of the given
14801 JSON-object @a j.
14802 @param[in] value JSON value to serialize
14803 @pre value.type() == value_t::object
14804 */
14805 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14806 {
14808 [](size_t result, const typename BasicJsonType::object_t::value_type& el)
14809 {
14811 });
14812
14813 return sizeof(std::int32_t) + document_size + 1ul;
14814 }
14815
14816 /*!
14817 @param[in] value JSON value to serialize
14818 @pre value.type() == value_t::object
14819 */
14820 void write_bson_object(const typename BasicJsonType::object_t& value)
14821 {
14823
14824 for (const auto& el : value)
14825 {
14827 }
14828
14830 }
14831
14832 //////////
14833 // CBOR //
14834 //////////
14835
14836 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14837 {
14838 return to_char_type(0xFA); // Single-Precision Float
14839 }
14840
14841 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14842 {
14843 return to_char_type(0xFB); // Double-Precision Float
14844 }
14845
14846 /////////////
14847 // MsgPack //
14848 /////////////
14849
14850 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14851 {
14852 return to_char_type(0xCA); // float 32
14853 }
14854
14855 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14856 {
14857 return to_char_type(0xCB); // float 64
14858 }
14859
14860 ////////////
14861 // UBJSON //
14862 ////////////
14863
14864 // UBJSON: write number (floating point)
14865 template<typename NumberType, typename std::enable_if<
14866 std::is_floating_point<NumberType>::value, int>::type = 0>
14867 void write_number_with_ubjson_prefix(const NumberType n,
14868 const bool add_prefix)
14869 {
14870 if (add_prefix)
14871 {
14873 }
14874 write_number(n);
14875 }
14876
14877 // UBJSON: write number (unsigned integer)
14878 template<typename NumberType, typename std::enable_if<
14879 std::is_unsigned<NumberType>::value, int>::type = 0>
14880 void write_number_with_ubjson_prefix(const NumberType n,
14881 const bool add_prefix)
14882 {
14883 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14884 {
14885 if (add_prefix)
14886 {
14887 oa->write_character(to_char_type('i')); // int8
14888 }
14889 write_number(static_cast<std::uint8_t>(n));
14890 }
14891 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14892 {
14893 if (add_prefix)
14894 {
14895 oa->write_character(to_char_type('U')); // uint8
14896 }
14897 write_number(static_cast<std::uint8_t>(n));
14898 }
14899 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14900 {
14901 if (add_prefix)
14902 {
14903 oa->write_character(to_char_type('I')); // int16
14904 }
14905 write_number(static_cast<std::int16_t>(n));
14906 }
14907 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14908 {
14909 if (add_prefix)
14910 {
14911 oa->write_character(to_char_type('l')); // int32
14912 }
14913 write_number(static_cast<std::int32_t>(n));
14914 }
14915 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14916 {
14917 if (add_prefix)
14918 {
14919 oa->write_character(to_char_type('L')); // int64
14920 }
14921 write_number(static_cast<std::int64_t>(n));
14922 }
14923 else
14924 {
14925 if (add_prefix)
14926 {
14927 oa->write_character(to_char_type('H')); // high-precision number
14928 }
14929
14930 const auto number = BasicJsonType(n).dump();
14932 for (std::size_t i = 0; i < number.size(); ++i)
14933 {
14934 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14935 }
14936 }
14937 }
14938
14939 // UBJSON: write number (signed integer)
14940 template < typename NumberType, typename std::enable_if <
14941 std::is_signed<NumberType>::value &&
14942 !std::is_floating_point<NumberType>::value, int >::type = 0 >
14943 void write_number_with_ubjson_prefix(const NumberType n,
14944 const bool add_prefix)
14945 {
14946 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
14947 {
14948 if (add_prefix)
14949 {
14950 oa->write_character(to_char_type('i')); // int8
14951 }
14952 write_number(static_cast<std::int8_t>(n));
14953 }
14954 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)()))
14955 {
14956 if (add_prefix)
14957 {
14958 oa->write_character(to_char_type('U')); // uint8
14959 }
14960 write_number(static_cast<std::uint8_t>(n));
14961 }
14962 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
14963 {
14964 if (add_prefix)
14965 {
14966 oa->write_character(to_char_type('I')); // int16
14967 }
14968 write_number(static_cast<std::int16_t>(n));
14969 }
14970 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
14971 {
14972 if (add_prefix)
14973 {
14974 oa->write_character(to_char_type('l')); // int32
14975 }
14976 write_number(static_cast<std::int32_t>(n));
14977 }
14978 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
14979 {
14980 if (add_prefix)
14981 {
14982 oa->write_character(to_char_type('L')); // int64
14983 }
14984 write_number(static_cast<std::int64_t>(n));
14985 }
14986 // LCOV_EXCL_START
14987 else
14988 {
14989 if (add_prefix)
14990 {
14991 oa->write_character(to_char_type('H')); // high-precision number
14992 }
14993
14994 const auto number = BasicJsonType(n).dump();
14996 for (std::size_t i = 0; i < number.size(); ++i)
14997 {
14998 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14999 }
15000 }
15001 // LCOV_EXCL_STOP
15002 }
15003
15004 /*!
15005 @brief determine the type prefix of container values
15006 */
15007 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
15008 {
15009 switch (j.type())
15010 {
15011 case value_t::null:
15012 return 'Z';
15013
15014 case value_t::boolean:
15015 return j.m_value.boolean ? 'T' : 'F';
15016
15017 case value_t::number_integer:
15018 {
15020 {
15021 return 'i';
15022 }
15024 {
15025 return 'U';
15026 }
15028 {
15029 return 'I';
15030 }
15032 {
15033 return 'l';
15034 }
15036 {
15037 return 'L';
15038 }
15039 // anything else is treated as high-precision number
15040 return 'H'; // LCOV_EXCL_LINE
15041 }
15042
15044 {
15045 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15046 {
15047 return 'i';
15048 }
15049 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15050 {
15051 return 'U';
15052 }
15053 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15054 {
15055 return 'I';
15056 }
15057 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15058 {
15059 return 'l';
15060 }
15061 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15062 {
15063 return 'L';
15064 }
15065 // anything else is treated as high-precision number
15066 return 'H'; // LCOV_EXCL_LINE
15067 }
15068
15069 case value_t::number_float:
15071
15072 case value_t::string:
15073 return 'S';
15074
15075 case value_t::array: // fallthrough
15076 case value_t::binary:
15077 return '[';
15078
15079 case value_t::object:
15080 return '{';
15081
15082 case value_t::discarded:
15083 default: // discarded values
15084 return 'N';
15085 }
15086 }
15087
15088 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15089 {
15090 return 'd'; // float 32
15091 }
15092
15093 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15094 {
15095 return 'D'; // float 64
15096 }
15097
15098 ///////////////////////
15099 // Utility functions //
15100 ///////////////////////
15101
15102 /*
15103 @brief write a number to output input
15104 @param[in] n number of type @a NumberType
15105 @tparam NumberType the type of the number
15106 @tparam OutputIsLittleEndian Set to true if output data is
15107 required to be little endian
15108
15109 @note This function needs to respect the system's endianess, because bytes
15110 in CBOR, MessagePack, and UBJSON are stored in network order (big
15111 endian) and therefore need reordering on little endian systems.
15112 */
15113 template<typename NumberType, bool OutputIsLittleEndian = false>
15114 void write_number(const NumberType n)
15115 {
15116 // step 1: write number to array of length NumberType
15117 std::array<CharType, sizeof(NumberType)> vec{};
15118 std::memcpy(vec.data(), &n, sizeof(NumberType));
15119
15120 // step 2: write array to output (with possible reordering)
15122 {
15123 // reverse byte order prior to conversion if necessary
15124 std::reverse(vec.begin(), vec.end());
15125 }
15126
15127 oa->write_characters(vec.data(), sizeof(NumberType));
15128 }
15129
15130 void write_compact_float(const number_float_t n, detail::input_format_t format)
15131 {
15132#ifdef __GNUC__
15133#pragma GCC diagnostic push
15134#pragma GCC diagnostic ignored "-Wfloat-equal"
15135#endif
15136 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
15137 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
15138 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
15139 {
15141 ? get_cbor_float_prefix(static_cast<float>(n))
15142 : get_msgpack_float_prefix(static_cast<float>(n)));
15143 write_number(static_cast<float>(n));
15144 }
15145 else
15146 {
15150 write_number(n);
15151 }
15152#ifdef __GNUC__
15153#pragma GCC diagnostic pop
15154#endif
15155 }
15156
15157 public:
15158 // The following to_char_type functions are implement the conversion
15159 // between uint8_t and CharType. In case CharType is not unsigned,
15160 // such a conversion is required to allow values greater than 128.
15161 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
15162 template < typename C = CharType,
15163 enable_if_t < std::is_signed<C>::value&& std::is_signed<char>::value >* = nullptr >
15164 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15165 {
15166 return *reinterpret_cast<char*>(&x);
15167 }
15168
15169 template < typename C = CharType,
15170 enable_if_t < std::is_signed<C>::value&& std::is_unsigned<char>::value >* = nullptr >
15171 static CharType to_char_type(std::uint8_t x) noexcept
15172 {
15173 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
15174 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
15176 std::memcpy(&result, &x, sizeof(x));
15177 return result;
15178 }
15179
15180 template<typename C = CharType,
15181 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
15182 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15183 {
15184 return x;
15185 }
15186
15187 template < typename InputCharType, typename C = CharType,
15188 enable_if_t <
15189 std::is_signed<C>::value&&
15190 std::is_signed<char>::value&&
15191 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
15192 >* = nullptr >
15193 static constexpr CharType to_char_type(InputCharType x) noexcept
15194 {
15195 return x;
15196 }
15197
15198 private:
15199 /// whether we can assume little endianess
15200 const bool is_little_endian = little_endianess();
15201
15202 /// the output
15204 };
15205 } // namespace detail
15206} // namespace nlohmann
15207
15208// #include <nlohmann/detail/output/output_adapters.hpp>
15209
15210// #include <nlohmann/detail/output/serializer.hpp>
15211
15212
15213#include <algorithm> // reverse, remove, fill, find, none_of
15214#include <array> // array
15215#include <clocale> // localeconv, lconv
15216#include <cmath> // labs, isfinite, isnan, signbit
15217#include <cstddef> // size_t, ptrdiff_t
15218#include <cstdint> // uint8_t
15219#include <cstdio> // snprintf
15220#include <limits> // numeric_limits
15221#include <string> // string, char_traits
15222#include <type_traits> // is_same
15223#include <utility> // move
15224
15225// #include <nlohmann/detail/conversions/to_chars.hpp>
15226
15227
15228#include <array> // array
15229#include <cmath> // signbit, isfinite
15230#include <cstdint> // intN_t, uintN_t
15231#include <cstring> // memcpy, memmove
15232#include <limits> // numeric_limits
15233#include <type_traits> // conditional
15234
15235// #include <nlohmann/detail/macro_scope.hpp>
15236
15237
15238namespace nlohmann
15239{
15240 namespace detail
15241 {
15242
15243 /*!
15244 @brief implements the Grisu2 algorithm for binary to decimal floating-point
15245 conversion.
15246
15247 This implementation is a slightly modified version of the reference
15248 implementation which may be obtained from
15249 http://florian.loitsch.com/publications (bench.tar.gz).
15250
15251 The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
15252
15253 For a detailed description of the algorithm see:
15254
15255 [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
15256 Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
15257 Language Design and Implementation, PLDI 2010
15258 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
15259 Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
15260 Design and Implementation, PLDI 1996
15261 */
15262 namespace dtoa_impl
15263 {
15264
15265 template<typename Target, typename Source>
15266 Target reinterpret_bits(const Source source)
15267 {
15268 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
15269
15270 Target target;
15271 std::memcpy(&target, &source, sizeof(Source));
15272 return target;
15273 }
15274
15275 struct diyfp // f * 2^e
15276 {
15277 static constexpr int kPrecision = 64; // = q
15278
15279 std::uint64_t f = 0;
15280 int e = 0;
15281
15282 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
15283
15284 /*!
15285 @brief returns x - y
15286 @pre x.e == y.e and x.f >= y.f
15287 */
15288 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
15289 {
15290 JSON_ASSERT(x.e == y.e);
15291 JSON_ASSERT(x.f >= y.f);
15292
15293 return { x.f - y.f, x.e };
15294 }
15295
15296 /*!
15297 @brief returns x * y
15298 @note The result is rounded. (Only the upper q bits are returned.)
15299 */
15300 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
15301 {
15302 static_assert(kPrecision == 64, "internal error");
15303
15304 // Computes:
15305 // f = round((x.f * y.f) / 2^q)
15306 // e = x.e + y.e + q
15307
15308 // Emulate the 64-bit * 64-bit multiplication:
15309 //
15310 // p = u * v
15311 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15312 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
15313 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
15314 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
15315 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
15316 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
15317 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
15318 //
15319 // (Since Q might be larger than 2^32 - 1)
15320 //
15321 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15322 //
15323 // (Q_hi + H does not overflow a 64-bit int)
15324 //
15325 // = p_lo + 2^64 p_hi
15326
15327 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15328 const std::uint64_t u_hi = x.f >> 32u;
15329 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15330 const std::uint64_t v_hi = y.f >> 32u;
15331
15332 const std::uint64_t p0 = u_lo * v_lo;
15333 const std::uint64_t p1 = u_lo * v_hi;
15334 const std::uint64_t p2 = u_hi * v_lo;
15335 const std::uint64_t p3 = u_hi * v_hi;
15336
15337 const std::uint64_t p0_hi = p0 >> 32u;
15338 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15339 const std::uint64_t p1_hi = p1 >> 32u;
15340 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15341 const std::uint64_t p2_hi = p2 >> 32u;
15342
15343 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15344
15345 // The full product might now be computed as
15346 //
15347 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
15348 // p_lo = p0_lo + (Q << 32)
15349 //
15350 // But in this particular case here, the full p_lo is not required.
15351 // Effectively we only need to add the highest bit in p_lo to p_hi (and
15352 // Q_hi + 1 does not overflow).
15353
15354 Q += std::uint64_t{ 1 } << (64u - 32u - 1u); // round, ties up
15355
15356 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15357
15358 return { h, x.e + y.e + 64 };
15359 }
15360
15361 /*!
15362 @brief normalize x such that the significand is >= 2^(q-1)
15363 @pre x.f != 0
15364 */
15365 static diyfp normalize(diyfp x) noexcept
15366 {
15367 JSON_ASSERT(x.f != 0);
15368
15369 while ((x.f >> 63u) == 0)
15370 {
15371 x.f <<= 1u;
15372 x.e--;
15373 }
15374
15375 return x;
15376 }
15377
15378 /*!
15379 @brief normalize x such that the result has the exponent E
15380 @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
15381 */
15382 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
15383 {
15384 const int delta = x.e - target_exponent;
15385
15386 JSON_ASSERT(delta >= 0);
15387 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
15388
15389 return { x.f << delta, target_exponent };
15390 }
15391 };
15392
15394 {
15398 };
15399
15400 /*!
15401 Compute the (normalized) diyfp representing the input number 'value' and its
15402 boundaries.
15403
15404 @pre value must be finite and positive
15405 */
15406 template<typename FloatType>
15408 {
15410 JSON_ASSERT(value > 0);
15411
15412 // Convert the IEEE representation into a diyfp.
15413 //
15414 // If v is denormal:
15415 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
15416 // If v is normalized:
15417 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
15418
15419 static_assert(std::numeric_limits<FloatType>::is_iec559,
15420 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
15421
15422 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
15423 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
15424 constexpr int kMinExp = 1 - kBias;
15425 constexpr std::uint64_t kHiddenBit = std::uint64_t{ 1 } << (kPrecision - 1); // = 2^(p-1)
15426
15427 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
15428
15429 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
15430 const std::uint64_t E = bits >> (kPrecision - 1);
15431 const std::uint64_t F = bits & (kHiddenBit - 1);
15432
15433 const bool is_denormal = E == 0;
15434 const diyfp v = is_denormal
15435 ? diyfp(F, kMinExp)
15436 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
15437
15438 // Compute the boundaries m- and m+ of the floating-point value
15439 // v = f * 2^e.
15440 //
15441 // Determine v- and v+, the floating-point predecessor and successor if v,
15442 // respectively.
15443 //
15444 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
15445 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
15446 //
15447 // v+ = v + 2^e
15448 //
15449 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
15450 // between m- and m+ round to v, regardless of how the input rounding
15451 // algorithm breaks ties.
15452 //
15453 // ---+-------------+-------------+-------------+-------------+--- (A)
15454 // v- m- v m+ v+
15455 //
15456 // -----------------+------+------+-------------+-------------+--- (B)
15457 // v- m- v m+ v+
15458
15459 const bool lower_boundary_is_closer = F == 0 && E > 1;
15460 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
15462 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
15463 : diyfp(2 * v.f - 1, v.e - 1); // (A)
15464
15465// Determine the normalized w+ = m+.
15466 const diyfp w_plus = diyfp::normalize(m_plus);
15467
15468 // Determine w- = m- such that e_(w-) = e_(w+).
15470
15471 return { diyfp::normalize(v), w_minus, w_plus };
15472 }
15473
15474 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
15475 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
15476 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
15477 //
15478 // alpha <= e = e_c + e_w + q <= gamma
15479 //
15480 // or
15481 //
15482 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
15483 // <= f_c * f_w * 2^gamma
15484 //
15485 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
15486 //
15487 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
15488 //
15489 // or
15490 //
15491 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
15492 //
15493 // The choice of (alpha,gamma) determines the size of the table and the form of
15494 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
15495 // in practice:
15496 //
15497 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
15498 // processed independently: An integral part p1, and a fractional part p2:
15499 //
15500 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
15501 // = (f div 2^-e) + (f mod 2^-e) * 2^e
15502 // = p1 + p2 * 2^e
15503 //
15504 // The conversion of p1 into decimal form requires a series of divisions and
15505 // modulos by (a power of) 10. These operations are faster for 32-bit than for
15506 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
15507 // achieved by choosing
15508 //
15509 // -e >= 32 or e <= -32 := gamma
15510 //
15511 // In order to convert the fractional part
15512 //
15513 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
15514 //
15515 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
15516 // d[-i] are extracted in order:
15517 //
15518 // (10 * p2) div 2^-e = d[-1]
15519 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
15520 //
15521 // The multiplication by 10 must not overflow. It is sufficient to choose
15522 //
15523 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
15524 //
15525 // Since p2 = f mod 2^-e < 2^-e,
15526 //
15527 // -e <= 60 or e >= -60 := alpha
15528
15529 constexpr int kAlpha = -60;
15530 constexpr int kGamma = -32;
15531
15532 struct cached_power // c = f * 2^e ~= 10^k
15533 {
15534 std::uint64_t f;
15535 int e;
15536 int k;
15537 };
15538
15539 /*!
15540 For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
15541 power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
15542 satisfies (Definition 3.2 from [1])
15543
15544 alpha <= e_c + e + q <= gamma.
15545 */
15547 {
15548 // Now
15549 //
15550 // alpha <= e_c + e + q <= gamma (1)
15551 // ==> f_c * 2^alpha <= c * 2^e * 2^q
15552 //
15553 // and since the c's are normalized, 2^(q-1) <= f_c,
15554 //
15555 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
15556 // ==> 2^(alpha - e - 1) <= c
15557 //
15558 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
15559 //
15560 // k = ceil( log_10( 2^(alpha - e - 1) ) )
15561 // = ceil( (alpha - e - 1) * log_10(2) )
15562 //
15563 // From the paper:
15564 // "In theory the result of the procedure could be wrong since c is rounded,
15565 // and the computation itself is approximated [...]. In practice, however,
15566 // this simple function is sufficient."
15567 //
15568 // For IEEE double precision floating-point numbers converted into
15569 // normalized diyfp's w = f * 2^e, with q = 64,
15570 //
15571 // e >= -1022 (min IEEE exponent)
15572 // -52 (p - 1)
15573 // -52 (p - 1, possibly normalize denormal IEEE numbers)
15574 // -11 (normalize the diyfp)
15575 // = -1137
15576 //
15577 // and
15578 //
15579 // e <= +1023 (max IEEE exponent)
15580 // -52 (p - 1)
15581 // -11 (normalize the diyfp)
15582 // = 960
15583 //
15584 // This binary exponent range [-1137,960] results in a decimal exponent
15585 // range [-307,324]. One does not need to store a cached power for each
15586 // k in this range. For each such k it suffices to find a cached power
15587 // such that the exponent of the product lies in [alpha,gamma].
15588 // This implies that the difference of the decimal exponents of adjacent
15589 // table entries must be less than or equal to
15590 //
15591 // floor( (gamma - alpha) * log_10(2) ) = 8.
15592 //
15593 // (A smaller distance gamma-alpha would require a larger table.)
15594
15595 // NB:
15596 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
15597
15598 constexpr int kCachedPowersMinDecExp = -300;
15599 constexpr int kCachedPowersDecStep = 8;
15600
15601 static constexpr std::array<cached_power, 79> kCachedPowers =
15602 {
15603 {
15604 { 0xAB70FE17C79AC6CA, -1060, -300 },
15605 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
15606 { 0xBE5691EF416BD60C, -1007, -284 },
15607 { 0x8DD01FAD907FFC3C, -980, -276 },
15608 { 0xD3515C2831559A83, -954, -268 },
15609 { 0x9D71AC8FADA6C9B5, -927, -260 },
15610 { 0xEA9C227723EE8BCB, -901, -252 },
15611 { 0xAECC49914078536D, -874, -244 },
15612 { 0x823C12795DB6CE57, -847, -236 },
15613 { 0xC21094364DFB5637, -821, -228 },
15614 { 0x9096EA6F3848984F, -794, -220 },
15615 { 0xD77485CB25823AC7, -768, -212 },
15616 { 0xA086CFCD97BF97F4, -741, -204 },
15617 { 0xEF340A98172AACE5, -715, -196 },
15618 { 0xB23867FB2A35B28E, -688, -188 },
15619 { 0x84C8D4DFD2C63F3B, -661, -180 },
15620 { 0xC5DD44271AD3CDBA, -635, -172 },
15621 { 0x936B9FCEBB25C996, -608, -164 },
15622 { 0xDBAC6C247D62A584, -582, -156 },
15623 { 0xA3AB66580D5FDAF6, -555, -148 },
15624 { 0xF3E2F893DEC3F126, -529, -140 },
15625 { 0xB5B5ADA8AAFF80B8, -502, -132 },
15626 { 0x87625F056C7C4A8B, -475, -124 },
15627 { 0xC9BCFF6034C13053, -449, -116 },
15628 { 0x964E858C91BA2655, -422, -108 },
15629 { 0xDFF9772470297EBD, -396, -100 },
15630 { 0xA6DFBD9FB8E5B88F, -369, -92 },
15631 { 0xF8A95FCF88747D94, -343, -84 },
15632 { 0xB94470938FA89BCF, -316, -76 },
15633 { 0x8A08F0F8BF0F156B, -289, -68 },
15634 { 0xCDB02555653131B6, -263, -60 },
15635 { 0x993FE2C6D07B7FAC, -236, -52 },
15636 { 0xE45C10C42A2B3B06, -210, -44 },
15637 { 0xAA242499697392D3, -183, -36 },
15638 { 0xFD87B5F28300CA0E, -157, -28 },
15639 { 0xBCE5086492111AEB, -130, -20 },
15640 { 0x8CBCCC096F5088CC, -103, -12 },
15641 { 0xD1B71758E219652C, -77, -4 },
15642 { 0x9C40000000000000, -50, 4 },
15643 { 0xE8D4A51000000000, -24, 12 },
15644 { 0xAD78EBC5AC620000, 3, 20 },
15645 { 0x813F3978F8940984, 30, 28 },
15646 { 0xC097CE7BC90715B3, 56, 36 },
15647 { 0x8F7E32CE7BEA5C70, 83, 44 },
15648 { 0xD5D238A4ABE98068, 109, 52 },
15649 { 0x9F4F2726179A2245, 136, 60 },
15650 { 0xED63A231D4C4FB27, 162, 68 },
15651 { 0xB0DE65388CC8ADA8, 189, 76 },
15652 { 0x83C7088E1AAB65DB, 216, 84 },
15653 { 0xC45D1DF942711D9A, 242, 92 },
15654 { 0x924D692CA61BE758, 269, 100 },
15655 { 0xDA01EE641A708DEA, 295, 108 },
15656 { 0xA26DA3999AEF774A, 322, 116 },
15657 { 0xF209787BB47D6B85, 348, 124 },
15658 { 0xB454E4A179DD1877, 375, 132 },
15659 { 0x865B86925B9BC5C2, 402, 140 },
15660 { 0xC83553C5C8965D3D, 428, 148 },
15661 { 0x952AB45CFA97A0B3, 455, 156 },
15662 { 0xDE469FBD99A05FE3, 481, 164 },
15663 { 0xA59BC234DB398C25, 508, 172 },
15664 { 0xF6C69A72A3989F5C, 534, 180 },
15665 { 0xB7DCBF5354E9BECE, 561, 188 },
15666 { 0x88FCF317F22241E2, 588, 196 },
15667 { 0xCC20CE9BD35C78A5, 614, 204 },
15668 { 0x98165AF37B2153DF, 641, 212 },
15669 { 0xE2A0B5DC971F303A, 667, 220 },
15670 { 0xA8D9D1535CE3B396, 694, 228 },
15671 { 0xFB9B7CD9A4A7443C, 720, 236 },
15672 { 0xBB764C4CA7A44410, 747, 244 },
15673 { 0x8BAB8EEFB6409C1A, 774, 252 },
15674 { 0xD01FEF10A657842C, 800, 260 },
15675 { 0x9B10A4E5E9913129, 827, 268 },
15676 { 0xE7109BFBA19C0C9D, 853, 276 },
15677 { 0xAC2820D9623BF429, 880, 284 },
15678 { 0x80444B5E7AA7CF85, 907, 292 },
15679 { 0xBF21E44003ACDD2D, 933, 300 },
15680 { 0x8E679C2F5E44FF8F, 960, 308 },
15681 { 0xD433179D9C8CB841, 986, 316 },
15682 { 0x9E19DB92B4E31BA9, 1013, 324 },
15683 }
15684 };
15685
15686 // This computation gives exactly the same results for k as
15687 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
15688 // for |e| <= 1500, but doesn't require floating-point operations.
15689 // NB: log_10(2) ~= 78913 / 2^18
15690 JSON_ASSERT(e >= -1500);
15691 JSON_ASSERT(e <= 1500);
15692 const int f = kAlpha - e - 1;
15693 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
15694
15695 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
15696 JSON_ASSERT(index >= 0);
15697 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
15698
15699 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
15700 JSON_ASSERT(kAlpha <= cached.e + e + 64);
15701 JSON_ASSERT(kGamma >= cached.e + e + 64);
15702
15703 return cached;
15704 }
15705
15706 /*!
15707 For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
15708 For n == 0, returns 1 and sets pow10 := 1.
15709 */
15710 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
15711 {
15712 // LCOV_EXCL_START
15713 if (n >= 1000000000)
15714 {
15715 pow10 = 1000000000;
15716 return 10;
15717 }
15718 // LCOV_EXCL_STOP
15719 if (n >= 100000000)
15720 {
15721 pow10 = 100000000;
15722 return 9;
15723 }
15724 if (n >= 10000000)
15725 {
15726 pow10 = 10000000;
15727 return 8;
15728 }
15729 if (n >= 1000000)
15730 {
15731 pow10 = 1000000;
15732 return 7;
15733 }
15734 if (n >= 100000)
15735 {
15736 pow10 = 100000;
15737 return 6;
15738 }
15739 if (n >= 10000)
15740 {
15741 pow10 = 10000;
15742 return 5;
15743 }
15744 if (n >= 1000)
15745 {
15746 pow10 = 1000;
15747 return 4;
15748 }
15749 if (n >= 100)
15750 {
15751 pow10 = 100;
15752 return 3;
15753 }
15754 if (n >= 10)
15755 {
15756 pow10 = 10;
15757 return 2;
15758 }
15759
15760 pow10 = 1;
15761 return 1;
15762 }
15763
15764 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
15765 std::uint64_t rest, std::uint64_t ten_k)
15766 {
15767 JSON_ASSERT(len >= 1);
15768 JSON_ASSERT(dist <= delta);
15769 JSON_ASSERT(rest <= delta);
15770 JSON_ASSERT(ten_k > 0);
15771
15772 // <--------------------------- delta ---->
15773 // <---- dist --------->
15774 // --------------[------------------+-------------------]--------------
15775 // M- w M+
15776 //
15777 // ten_k
15778 // <------>
15779 // <---- rest ---->
15780 // --------------[------------------+----+--------------]--------------
15781 // w V
15782 // = buf * 10^k
15783 //
15784 // ten_k represents a unit-in-the-last-place in the decimal representation
15785 // stored in buf.
15786 // Decrement buf by ten_k while this takes buf closer to w.
15787
15788 // The tests are written in this order to avoid overflow in unsigned
15789 // integer arithmetic.
15790
15791 while (rest < dist
15792 && delta - rest >= ten_k
15793 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
15794 {
15795 JSON_ASSERT(buf[len - 1] != '0');
15796 buf[len - 1]--;
15797 rest += ten_k;
15798 }
15799 }
15800
15801 /*!
15802 Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
15803 M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
15804 */
15805 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
15806 diyfp M_minus, diyfp w, diyfp M_plus)
15807 {
15808 static_assert(kAlpha >= -60, "internal error");
15809 static_assert(kGamma <= -32, "internal error");
15810
15811 // Generates the digits (and the exponent) of a decimal floating-point
15812 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15813 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15814 //
15815 // <--------------------------- delta ---->
15816 // <---- dist --------->
15817 // --------------[------------------+-------------------]--------------
15818 // M- w M+
15819 //
15820 // Grisu2 generates the digits of M+ from left to right and stops as soon as
15821 // V is in [M-,M+].
15822
15823 JSON_ASSERT(M_plus.e >= kAlpha);
15824 JSON_ASSERT(M_plus.e <= kGamma);
15825
15826 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15827 std::uint64_t dist = diyfp::sub(M_plus, w).f; // (significand of (M+ - w ), implicit exponent is e)
15828
15829 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15830 //
15831 // M+ = f * 2^e
15832 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15833 // = ((p1 ) * 2^-e + (p2 )) * 2^e
15834 // = p1 + p2 * 2^e
15835
15836 const diyfp one(std::uint64_t{ 1 } << -M_plus.e, M_plus.e);
15837
15838 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.)
15839 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
15840
15841 // 1)
15842 //
15843 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15844
15845 JSON_ASSERT(p1 > 0);
15846
15847 std::uint32_t pow10{};
15848 const int k = find_largest_pow10(p1, pow10);
15849
15850 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15851 //
15852 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15853 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
15854 //
15855 // M+ = p1 + p2 * 2^e
15856 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
15857 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15858 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
15859 //
15860 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15861 //
15862 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15863 //
15864 // but stop as soon as
15865 //
15866 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15867
15868 int n = k;
15869 while (n > 0)
15870 {
15871 // Invariants:
15872 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
15873 // pow10 = 10^(n-1) <= p1 < 10^n
15874 //
15875 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
15876 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
15877 //
15878 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15879 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15880 //
15881 JSON_ASSERT(d <= 9);
15882 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15883 //
15884 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15885 //
15886 p1 = r;
15887 n--;
15888 //
15889 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
15890 // pow10 = 10^n
15891 //
15892
15893 // Now check if enough digits have been generated.
15894 // Compute
15895 //
15896 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15897 //
15898 // Note:
15899 // Since rest and delta share the same exponent e, it suffices to
15900 // compare the significands.
15901 const std::uint64_t rest = (std::uint64_t{ p1 } << -one.e) + p2;
15902 if (rest <= delta)
15903 {
15904 // V = buffer * 10^n, with M- <= V <= M+.
15905
15906 decimal_exponent += n;
15907
15908 // We may now just stop. But instead look if the buffer could be
15909 // decremented to bring V closer to w.
15910 //
15911 // pow10 = 10^n is now 1 ulp in the decimal representation V.
15912 // The rounding procedure works with diyfp's with an implicit
15913 // exponent of e.
15914 //
15915 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15916 //
15917 const std::uint64_t ten_n = std::uint64_t{ pow10 } << -one.e;
15918 grisu2_round(buffer, length, dist, delta, rest, ten_n);
15919
15920 return;
15921 }
15922
15923 pow10 /= 10;
15924 //
15925 // pow10 = 10^(n-1) <= p1 < 10^n
15926 // Invariants restored.
15927 }
15928
15929 // 2)
15930 //
15931 // The digits of the integral part have been generated:
15932 //
15933 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15934 // = buffer + p2 * 2^e
15935 //
15936 // Now generate the digits of the fractional part p2 * 2^e.
15937 //
15938 // Note:
15939 // No decimal point is generated: the exponent is adjusted instead.
15940 //
15941 // p2 actually represents the fraction
15942 //
15943 // p2 * 2^e
15944 // = p2 / 2^-e
15945 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
15946 //
15947 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15948 //
15949 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15950 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15951 //
15952 // using
15953 //
15954 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15955 // = ( d) * 2^-e + ( r)
15956 //
15957 // or
15958 // 10^m * p2 * 2^e = d + r * 2^e
15959 //
15960 // i.e.
15961 //
15962 // M+ = buffer + p2 * 2^e
15963 // = buffer + 10^-m * (d + r * 2^e)
15964 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15965 //
15966 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15967
15968 JSON_ASSERT(p2 > delta);
15969
15970 int m = 0;
15971 for (;;)
15972 {
15973 // Invariant:
15974 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15975 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
15976 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
15977 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15978 //
15979 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
15980 p2 *= 10;
15981 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
15982 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15983 //
15984 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15985 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15986 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15987 //
15988 JSON_ASSERT(d <= 9);
15989 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15990 //
15991 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15992 //
15993 p2 = r;
15994 m++;
15995 //
15996 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15997 // Invariant restored.
15998
15999 // Check if enough digits have been generated.
16000 //
16001 // 10^-m * p2 * 2^e <= delta * 2^e
16002 // p2 * 2^e <= 10^m * delta * 2^e
16003 // p2 <= 10^m * delta
16004 delta *= 10;
16005 dist *= 10;
16006 if (p2 <= delta)
16007 {
16008 break;
16009 }
16010 }
16011
16012 // V = buffer * 10^-m, with M- <= V <= M+.
16013
16014 decimal_exponent -= m;
16015
16016 // 1 ulp in the decimal representation is now 10^-m.
16017 // Since delta and dist are now scaled by 10^m, we need to do the
16018 // same with ulp in order to keep the units in sync.
16019 //
16020 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16021 //
16022 const std::uint64_t ten_m = one.f;
16023 grisu2_round(buffer, length, dist, delta, p2, ten_m);
16024
16025 // By construction this algorithm generates the shortest possible decimal
16026 // number (Loitsch, Theorem 6.2) which rounds back to w.
16027 // For an input number of precision p, at least
16028 //
16029 // N = 1 + ceil(p * log_10(2))
16030 //
16031 // decimal digits are sufficient to identify all binary floating-point
16032 // numbers (Matula, "In-and-Out conversions").
16033 // This implies that the algorithm does not produce more than N decimal
16034 // digits.
16035 //
16036 // N = 17 for p = 53 (IEEE double precision)
16037 // N = 9 for p = 24 (IEEE single precision)
16038 }
16039
16040 /*!
16041 v = buf * 10^decimal_exponent
16042 len is the length of the buffer (number of decimal digits)
16043 The buffer must be large enough, i.e. >= max_digits10.
16044 */
16046 inline void grisu2(char* buf, int& len, int& decimal_exponent,
16047 diyfp m_minus, diyfp v, diyfp m_plus)
16048 {
16049 JSON_ASSERT(m_plus.e == m_minus.e);
16050 JSON_ASSERT(m_plus.e == v.e);
16051
16052 // --------(-----------------------+-----------------------)-------- (A)
16053 // m- v m+
16054 //
16055 // --------------------(-----------+-----------------------)-------- (B)
16056 // m- v m+
16057 //
16058 // First scale v (and m- and m+) such that the exponent is in the range
16059 // [alpha, gamma].
16060
16062
16063 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
16064
16065 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
16066 const diyfp w = diyfp::mul(v, c_minus_k);
16067 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
16068 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
16069
16070 // ----(---+---)---------------(---+---)---------------(---+---)----
16071 // w- w w+
16072 // = c*m- = c*v = c*m+
16073 //
16074 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
16075 // w+ are now off by a small amount.
16076 // In fact:
16077 //
16078 // w - v * 10^k < 1 ulp
16079 //
16080 // To account for this inaccuracy, add resp. subtract 1 ulp.
16081 //
16082 // --------+---[---------------(---+---)---------------]---+--------
16083 // w- M- w M+ w+
16084 //
16085 // Now any number in [M-, M+] (bounds included) will round to w when input,
16086 // regardless of how the input rounding algorithm breaks ties.
16087 //
16088 // And digit_gen generates the shortest possible such number in [M-, M+].
16089 // Note that this does not mean that Grisu2 always generates the shortest
16090 // possible number in the interval (m-, m+).
16091 const diyfp M_minus(w_minus.f + 1, w_minus.e);
16092 const diyfp M_plus(w_plus.f - 1, w_plus.e);
16093
16094 decimal_exponent = -cached.k; // = -(-k) = k
16095
16096 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
16097 }
16098
16099 /*!
16100 v = buf * 10^decimal_exponent
16101 len is the length of the buffer (number of decimal digits)
16102 The buffer must be large enough, i.e. >= max_digits10.
16103 */
16104 template<typename FloatType>
16106 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
16107 {
16108 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
16109 "internal error: not enough precision");
16110
16112 JSON_ASSERT(value > 0);
16113
16114 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
16115 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
16116 // decimal representations are not exactly "short".
16117 //
16118 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
16119 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
16120 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
16121 // does.
16122 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
16123 // representation using the corresponding std::from_chars function recovers value exactly". That
16124 // indicates that single precision floating-point numbers should be recovered using
16125 // 'std::strtof'.
16126 //
16127 // NB: If the neighbors are computed for single-precision numbers, there is a single float
16128 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
16129 // value is off by 1 ulp.
16130#if 0
16131 const boundaries w = compute_boundaries(static_cast<double>(value));
16132#else
16134#endif
16135
16137 }
16138
16139 /*!
16140 @brief appends a decimal representation of e to buf
16141 @return a pointer to the element following the exponent.
16142 @pre -1000 < e < 1000
16143 */
16146 inline char* append_exponent(char* buf, int e)
16147 {
16148 JSON_ASSERT(e > -1000);
16149 JSON_ASSERT(e < 1000);
16150
16151 if (e < 0)
16152 {
16153 e = -e;
16154 *buf++ = '-';
16155 }
16156 else
16157 {
16158 *buf++ = '+';
16159 }
16160
16161 auto k = static_cast<std::uint32_t>(e);
16162 if (k < 10)
16163 {
16164 // Always print at least two digits in the exponent.
16165 // This is for compatibility with printf("%g").
16166 *buf++ = '0';
16167 *buf++ = static_cast<char>('0' + k);
16168 }
16169 else if (k < 100)
16170 {
16171 *buf++ = static_cast<char>('0' + k / 10);
16172 k %= 10;
16173 *buf++ = static_cast<char>('0' + k);
16174 }
16175 else
16176 {
16177 *buf++ = static_cast<char>('0' + k / 100);
16178 k %= 100;
16179 *buf++ = static_cast<char>('0' + k / 10);
16180 k %= 10;
16181 *buf++ = static_cast<char>('0' + k);
16182 }
16183
16184 return buf;
16185 }
16186
16187 /*!
16188 @brief prettify v = buf * 10^decimal_exponent
16189
16190 If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
16191 notation. Otherwise it will be printed in exponential notation.
16192
16193 @pre min_exp < 0
16194 @pre max_exp > 0
16195 */
16198 inline char* format_buffer(char* buf, int len, int decimal_exponent,
16199 int min_exp, int max_exp)
16200 {
16201 JSON_ASSERT(min_exp < 0);
16202 JSON_ASSERT(max_exp > 0);
16203
16204 const int k = len;
16205 const int n = len + decimal_exponent;
16206
16207 // v = buf * 10^(n-k)
16208 // k is the length of the buffer (number of decimal digits)
16209 // n is the position of the decimal point relative to the start of the buffer.
16210
16211 if (k <= n && n <= max_exp)
16212 {
16213 // digits[000]
16214 // len <= max_exp + 2
16215
16216 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
16217 // Make it look like a floating-point number (#362, #378)
16218 buf[n + 0] = '.';
16219 buf[n + 1] = '0';
16220 return buf + (static_cast<size_t>(n) + 2);
16221 }
16222
16223 if (0 < n && n <= max_exp)
16224 {
16225 // dig.its
16226 // len <= max_digits10 + 1
16227
16228 JSON_ASSERT(k > n);
16229
16230 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
16231 buf[n] = '.';
16232 return buf + (static_cast<size_t>(k) + 1U);
16233 }
16234
16235 if (min_exp < n && n <= 0)
16236 {
16237 // 0.[000]digits
16238 // len <= 2 + (-min_exp - 1) + max_digits10
16239
16240 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
16241 buf[0] = '0';
16242 buf[1] = '.';
16243 std::memset(buf + 2, '0', static_cast<size_t>(-n));
16244 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
16245 }
16246
16247 if (k == 1)
16248 {
16249 // dE+123
16250 // len <= 1 + 5
16251
16252 buf += 1;
16253 }
16254 else
16255 {
16256 // d.igitsE+123
16257 // len <= max_digits10 + 1 + 5
16258
16259 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
16260 buf[1] = '.';
16261 buf += 1 + static_cast<size_t>(k);
16262 }
16263
16264 *buf++ = 'e';
16265 return append_exponent(buf, n - 1);
16266 }
16267
16268 } // namespace dtoa_impl
16269
16270 /*!
16271 @brief generates a decimal representation of the floating-point number value in [first, last).
16272
16273 The format of the resulting decimal representation is similar to printf's %g
16274 format. Returns an iterator pointing past-the-end of the decimal representation.
16275
16276 @note The input number must be finite, i.e. NaN's and Inf's are not supported.
16277 @note The buffer must be large enough.
16278 @note The result is NOT null-terminated.
16279 */
16280 template<typename FloatType>
16283 char* to_chars(char* first, const char* last, FloatType value)
16284 {
16285 static_cast<void>(last); // maybe unused - fix warning
16287
16288 // Use signbit(value) instead of (value < 0) since signbit works for -0.
16289 if (std::signbit(value))
16290 {
16291 value = -value;
16292 *first++ = '-';
16293 }
16294
16295#ifdef __GNUC__
16296#pragma GCC diagnostic push
16297#pragma GCC diagnostic ignored "-Wfloat-equal"
16298#endif
16299 if (value == 0) // +-0
16300 {
16301 *first++ = '0';
16302 // Make it look like a floating-point number (#362, #378)
16303 *first++ = '.';
16304 *first++ = '0';
16305 return first;
16306 }
16307#ifdef __GNUC__
16308#pragma GCC diagnostic pop
16309#endif
16310
16312
16313 // Compute v = buffer * 10^decimal_exponent.
16314 // The decimal digits are stored in the buffer, which needs to be interpreted
16315 // as an unsigned decimal integer.
16316 // len is the length of the buffer, i.e. the number of decimal digits.
16317 int len = 0;
16318 int decimal_exponent = 0;
16320
16322
16323 // Format the buffer like printf("%.*g", prec, value)
16324 constexpr int kMinExp = -4;
16325 // Use digits10 here to increase compatibility with version 2.
16326 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
16327
16328 JSON_ASSERT(last - first >= kMaxExp + 2);
16331
16333 }
16334
16335 } // namespace detail
16336} // namespace nlohmann
16337
16338// #include <nlohmann/detail/exceptions.hpp>
16339
16340// #include <nlohmann/detail/macro_scope.hpp>
16341
16342// #include <nlohmann/detail/meta/cpp_future.hpp>
16343
16344// #include <nlohmann/detail/output/binary_writer.hpp>
16345
16346// #include <nlohmann/detail/output/output_adapters.hpp>
16347
16348// #include <nlohmann/detail/value_t.hpp>
16349
16350
16351namespace nlohmann
16352{
16353 namespace detail
16354 {
16355 ///////////////////
16356 // serialization //
16357 ///////////////////
16358
16359 /// how to treat decoding errors
16361 {
16362 strict, ///< throw a type_error exception in case of invalid UTF-8
16363 replace, ///< replace invalid UTF-8 sequences with U+FFFD
16364 ignore ///< ignore invalid UTF-8 sequences
16365 };
16366
16367 template<typename BasicJsonType>
16369 {
16370 using string_t = typename BasicJsonType::string_t;
16371 using number_float_t = typename BasicJsonType::number_float_t;
16372 using number_integer_t = typename BasicJsonType::number_integer_t;
16373 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
16374 using binary_char_t = typename BasicJsonType::binary_t::value_type;
16375 static constexpr std::uint8_t UTF8_ACCEPT = 0;
16376 static constexpr std::uint8_t UTF8_REJECT = 1;
16377
16378 public:
16379 /*!
16380 @param[in] s output stream to serialize to
16381 @param[in] ichar indentation character to use
16382 @param[in] error_handler_ how to react on decoding errors
16383 */
16384 serializer(output_adapter_t<char> s, const char ichar,
16386 : o(std::move(s))
16387 , loc(std::localeconv())
16388 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(*(loc->thousands_sep)))
16389 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(*(loc->decimal_point)))
16393 {}
16394
16395 // delete because of pointer members
16396 serializer(const serializer&) = delete;
16397 serializer& operator=(const serializer&) = delete;
16400 ~serializer() = default;
16401
16402 /*!
16403 @brief internal implementation of the serialization function
16404
16405 This function is called by the public member function dump and organizes
16406 the serialization internally. The indentation level is propagated as
16407 additional parameter. In case of arrays and objects, the function is
16408 called recursively.
16409
16410 - strings and object keys are escaped using `escape_string()`
16411 - integer numbers are converted implicitly via `operator<<`
16412 - floating-point numbers are converted to a string using `"%g"` format
16413 - binary values are serialized as objects containing the subtype and the
16414 byte array
16415
16416 @param[in] val value to serialize
16417 @param[in] pretty_print whether the output shall be pretty-printed
16418 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
16419 in the output are escaped with `\uXXXX` sequences, and the result consists
16420 of ASCII characters only.
16421 @param[in] indent_step the indent level
16422 @param[in] current_indent the current indent level (only used internally)
16423 */
16424 void dump(const BasicJsonType& val,
16425 const bool pretty_print,
16426 const bool ensure_ascii,
16427 const unsigned int indent_step,
16428 const unsigned int current_indent = 0)
16429 {
16430 switch (val.m_type)
16431 {
16432 case value_t::object:
16433 {
16434 if (val.m_value.object->empty())
16435 {
16436 o->write_characters("{}", 2);
16437 return;
16438 }
16439
16440 if (pretty_print)
16441 {
16442 o->write_characters("{\n", 2);
16443
16444 // variable to hold indentation for recursive calls
16445 const auto new_indent = current_indent + indent_step;
16447 {
16449 }
16450
16451 // first n-1 elements
16452 auto i = val.m_value.object->cbegin();
16453 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16454 {
16456 o->write_character('\"');
16458 o->write_characters("\": ", 3);
16460 o->write_characters(",\n", 2);
16461 }
16462
16463 // last element
16467 o->write_character('\"');
16469 o->write_characters("\": ", 3);
16471
16472 o->write_character('\n');
16474 o->write_character('}');
16475 }
16476 else
16477 {
16478 o->write_character('{');
16479
16480 // first n-1 elements
16481 auto i = val.m_value.object->cbegin();
16482 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16483 {
16484 o->write_character('\"');
16486 o->write_characters("\":", 2);
16488 o->write_character(',');
16489 }
16490
16491 // last element
16494 o->write_character('\"');
16496 o->write_characters("\":", 2);
16498
16499 o->write_character('}');
16500 }
16501
16502 return;
16503 }
16504
16505 case value_t::array:
16506 {
16507 if (val.m_value.array->empty())
16508 {
16509 o->write_characters("[]", 2);
16510 return;
16511 }
16512
16513 if (pretty_print)
16514 {
16515 o->write_characters("[\n", 2);
16516
16517 // variable to hold indentation for recursive calls
16518 const auto new_indent = current_indent + indent_step;
16520 {
16522 }
16523
16524 // first n-1 elements
16525 for (auto i = val.m_value.array->cbegin();
16526 i != val.m_value.array->cend() - 1; ++i)
16527 {
16530 o->write_characters(",\n", 2);
16531 }
16532
16533 // last element
16537
16538 o->write_character('\n');
16540 o->write_character(']');
16541 }
16542 else
16543 {
16544 o->write_character('[');
16545
16546 // first n-1 elements
16547 for (auto i = val.m_value.array->cbegin();
16548 i != val.m_value.array->cend() - 1; ++i)
16549 {
16551 o->write_character(',');
16552 }
16553
16554 // last element
16557
16558 o->write_character(']');
16559 }
16560
16561 return;
16562 }
16563
16564 case value_t::string:
16565 {
16566 o->write_character('\"');
16568 o->write_character('\"');
16569 return;
16570 }
16571
16572 case value_t::binary:
16573 {
16574 if (pretty_print)
16575 {
16576 o->write_characters("{\n", 2);
16577
16578 // variable to hold indentation for recursive calls
16579 const auto new_indent = current_indent + indent_step;
16581 {
16583 }
16584
16586
16587 o->write_characters("\"bytes\": [", 10);
16588
16589 if (!val.m_value.binary->empty())
16590 {
16591 for (auto i = val.m_value.binary->cbegin();
16592 i != val.m_value.binary->cend() - 1; ++i)
16593 {
16594 dump_integer(*i);
16595 o->write_characters(", ", 2);
16596 }
16598 }
16599
16600 o->write_characters("],\n", 3);
16602
16603 o->write_characters("\"subtype\": ", 11);
16605 {
16607 }
16608 else
16609 {
16610 o->write_characters("null", 4);
16611 }
16612 o->write_character('\n');
16614 o->write_character('}');
16615 }
16616 else
16617 {
16618 o->write_characters("{\"bytes\":[", 10);
16619
16620 if (!val.m_value.binary->empty())
16621 {
16622 for (auto i = val.m_value.binary->cbegin();
16623 i != val.m_value.binary->cend() - 1; ++i)
16624 {
16625 dump_integer(*i);
16626 o->write_character(',');
16627 }
16629 }
16630
16631 o->write_characters("],\"subtype\":", 12);
16633 {
16635 o->write_character('}');
16636 }
16637 else
16638 {
16639 o->write_characters("null}", 5);
16640 }
16641 }
16642 return;
16643 }
16644
16645 case value_t::boolean:
16646 {
16647 if (val.m_value.boolean)
16648 {
16649 o->write_characters("true", 4);
16650 }
16651 else
16652 {
16653 o->write_characters("false", 5);
16654 }
16655 return;
16656 }
16657
16658 case value_t::number_integer:
16659 {
16661 return;
16662 }
16663
16665 {
16667 return;
16668 }
16669
16670 case value_t::number_float:
16671 {
16673 return;
16674 }
16675
16676 case value_t::discarded:
16677 {
16678 o->write_characters("<discarded>", 11);
16679 return;
16680 }
16681
16682 case value_t::null:
16683 {
16684 o->write_characters("null", 4);
16685 return;
16686 }
16687
16688 default: // LCOV_EXCL_LINE
16689 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16690 }
16691 }
16692
16694 /*!
16695 @brief dump escaped string
16696
16697 Escape a string by replacing certain special characters by a sequence of an
16698 escape character (backslash) and another character and other control
16699 characters by a sequence of "\u" followed by a four-digit hex
16700 representation. The escaped string is written to output stream @a o.
16701
16702 @param[in] s the string to escape
16703 @param[in] ensure_ascii whether to escape non-ASCII characters with
16704 \uXXXX sequences
16705
16706 @complexity Linear in the length of string @a s.
16707 */
16708 void dump_escaped(const string_t& s, const bool ensure_ascii)
16709 {
16712 std::size_t bytes = 0; // number of bytes written to string_buffer
16713
16714 // number of bytes written at the point of the last valid byte
16717
16718 for (std::size_t i = 0; i < s.size(); ++i)
16719 {
16720 const auto byte = static_cast<std::uint8_t>(s[i]);
16721
16722 switch (decode(state, codepoint, byte))
16723 {
16724 case UTF8_ACCEPT: // decode found a new code point
16725 {
16726 switch (codepoint)
16727 {
16728 case 0x08: // backspace
16729 {
16730 string_buffer[bytes++] = '\\';
16731 string_buffer[bytes++] = 'b';
16732 break;
16733 }
16734
16735 case 0x09: // horizontal tab
16736 {
16737 string_buffer[bytes++] = '\\';
16738 string_buffer[bytes++] = 't';
16739 break;
16740 }
16741
16742 case 0x0A: // newline
16743 {
16744 string_buffer[bytes++] = '\\';
16745 string_buffer[bytes++] = 'n';
16746 break;
16747 }
16748
16749 case 0x0C: // formfeed
16750 {
16751 string_buffer[bytes++] = '\\';
16752 string_buffer[bytes++] = 'f';
16753 break;
16754 }
16755
16756 case 0x0D: // carriage return
16757 {
16758 string_buffer[bytes++] = '\\';
16759 string_buffer[bytes++] = 'r';
16760 break;
16761 }
16762
16763 case 0x22: // quotation mark
16764 {
16765 string_buffer[bytes++] = '\\';
16766 string_buffer[bytes++] = '\"';
16767 break;
16768 }
16769
16770 case 0x5C: // reverse solidus
16771 {
16772 string_buffer[bytes++] = '\\';
16773 string_buffer[bytes++] = '\\';
16774 break;
16775 }
16776
16777 default:
16778 {
16779 // escape control characters (0x00..0x1F) or, if
16780 // ensure_ascii parameter is used, non-ASCII characters
16781 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
16782 {
16783 if (codepoint <= 0xFFFF)
16784 {
16785 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16786 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
16787 static_cast<std::uint16_t>(codepoint));
16788 bytes += 6;
16789 }
16790 else
16791 {
16792 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16793 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
16794 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
16795 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
16796 bytes += 12;
16797 }
16798 }
16799 else
16800 {
16801 // copy byte to buffer (all previous bytes
16802 // been copied have in default case above)
16803 string_buffer[bytes++] = s[i];
16804 }
16805 break;
16806 }
16807 }
16808
16809 // write buffer and reset index; there must be 13 bytes
16810 // left, as this is the maximal number of bytes to be
16811 // written ("\uxxxx\uxxxx\0") for one code point
16812 if (string_buffer.size() - bytes < 13)
16813 {
16815 bytes = 0;
16816 }
16817
16818 // remember the byte position of this accept
16820 undumped_chars = 0;
16821 break;
16822 }
16823
16824 case UTF8_REJECT: // decode found invalid UTF-8 byte
16825 {
16826 switch (error_handler)
16827 {
16828 case error_handler_t::strict:
16829 {
16830 std::string sn(9, '\0');
16831 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16832 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
16833 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType()));
16834 }
16835
16836 case error_handler_t::ignore:
16838 {
16839 // in case we saw this character the first time, we
16840 // would like to read it again, because the byte
16841 // may be OK for itself, but just not OK for the
16842 // previous sequence
16843 if (undumped_chars > 0)
16844 {
16845 --i;
16846 }
16847
16848 // reset length buffer to the last accepted index;
16849 // thus removing/ignoring the invalid characters
16851
16853 {
16854 // add a replacement character
16855 if (ensure_ascii)
16856 {
16857 string_buffer[bytes++] = '\\';
16858 string_buffer[bytes++] = 'u';
16859 string_buffer[bytes++] = 'f';
16860 string_buffer[bytes++] = 'f';
16861 string_buffer[bytes++] = 'f';
16862 string_buffer[bytes++] = 'd';
16863 }
16864 else
16865 {
16869 }
16870
16871 // write buffer and reset index; there must be 13 bytes
16872 // left, as this is the maximal number of bytes to be
16873 // written ("\uxxxx\uxxxx\0") for one code point
16874 if (string_buffer.size() - bytes < 13)
16875 {
16877 bytes = 0;
16878 }
16879
16881 }
16882
16883 undumped_chars = 0;
16884
16885 // continue processing the string
16887 break;
16888 }
16889
16890 default: // LCOV_EXCL_LINE
16891 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16892 }
16893 break;
16894 }
16895
16896 default: // decode found yet incomplete multi-byte code point
16897 {
16898 if (!ensure_ascii)
16899 {
16900 // code point will not be escaped - copy byte to buffer
16901 string_buffer[bytes++] = s[i];
16902 }
16904 break;
16905 }
16906 }
16907 }
16908
16909 // we finished processing the string
16911 {
16912 // write buffer
16913 if (bytes > 0)
16914 {
16916 }
16917 }
16918 else
16919 {
16920 // we finish reading, but do not accept: string was incomplete
16921 switch (error_handler)
16922 {
16923 case error_handler_t::strict:
16924 {
16925 std::string sn(9, '\0');
16926 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16927 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
16928 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType()));
16929 }
16930
16931 case error_handler_t::ignore:
16932 {
16933 // write all accepted bytes
16935 break;
16936 }
16937
16939 {
16940 // write all accepted bytes
16942 // add a replacement character
16943 if (ensure_ascii)
16944 {
16945 o->write_characters("\\ufffd", 6);
16946 }
16947 else
16948 {
16949 o->write_characters("\xEF\xBF\xBD", 3);
16950 }
16951 break;
16952 }
16953
16954 default: // LCOV_EXCL_LINE
16955 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16956 }
16957 }
16958 }
16959
16960 private:
16961 /*!
16962 @brief count digits
16963
16964 Count the number of decimal (base 10) digits for an input unsigned integer.
16965
16966 @param[in] x unsigned integer number to count its digits
16967 @return number of decimal digits
16968 */
16969 inline unsigned int count_digits(number_unsigned_t x) noexcept
16970 {
16971 unsigned int n_digits = 1;
16972 for (;;)
16973 {
16974 if (x < 10)
16975 {
16976 return n_digits;
16977 }
16978 if (x < 100)
16979 {
16980 return n_digits + 1;
16981 }
16982 if (x < 1000)
16983 {
16984 return n_digits + 2;
16985 }
16986 if (x < 10000)
16987 {
16988 return n_digits + 3;
16989 }
16990 x = x / 10000u;
16991 n_digits += 4;
16992 }
16993 }
16994
16995 /*!
16996 @brief dump an integer
16997
16998 Dump a given integer to output stream @a o. Works internally with
16999 @a number_buffer.
17000
17001 @param[in] x integer number (signed or unsigned) to dump
17002 @tparam NumberType either @a number_integer_t or @a number_unsigned_t
17003 */
17004 template < typename NumberType, detail::enable_if_t <
17005 std::is_integral<NumberType>::value ||
17006 std::is_same<NumberType, number_unsigned_t>::value ||
17007 std::is_same<NumberType, number_integer_t>::value ||
17008 std::is_same<NumberType, binary_char_t>::value,
17009 int > = 0 >
17010 void dump_integer(NumberType x)
17011 {
17012 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
17013 {
17014 {
17015 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
17016 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
17017 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
17018 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
17019 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
17020 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17021 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17022 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17023 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17024 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17025 }
17026 };
17027
17028 // special case for "0"
17029 if (x == 0)
17030 {
17031 o->write_character('0');
17032 return;
17033 }
17034
17035 // use a pointer to fill the buffer
17036 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17037
17038 const bool is_negative = std::is_signed<NumberType>::value && !(x >= 0); // see issue #755
17040
17041 unsigned int n_chars{};
17042
17043 if (is_negative)
17044 {
17045 *buffer_ptr = '-';
17046 abs_value = remove_sign(static_cast<number_integer_t>(x));
17047
17048 // account one more byte for the minus sign
17050 }
17051 else
17052 {
17053 abs_value = static_cast<number_unsigned_t>(x);
17055 }
17056
17057 // spare 1 byte for '\0'
17059
17060 // jump to the end to generate the string from backward
17061 // so we later avoid reversing the result
17063
17064 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
17065 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
17066 while (abs_value >= 100)
17067 {
17068 const auto digits_index = static_cast<unsigned>((abs_value % 100));
17069 abs_value /= 100;
17072 }
17073
17074 if (abs_value >= 10)
17075 {
17076 const auto digits_index = static_cast<unsigned>(abs_value);
17079 }
17080 else
17081 {
17082 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
17083 }
17084
17086 }
17087
17088 /*!
17089 @brief dump a floating-point number
17090
17091 Dump a given floating-point number to output stream @a o. Works internally
17092 with @a number_buffer.
17093
17094 @param[in] x floating-point number to dump
17095 */
17096 void dump_float(number_float_t x)
17097 {
17098 // NaN / inf
17099 if (!std::isfinite(x))
17100 {
17101 o->write_characters("null", 4);
17102 return;
17103 }
17104
17105 // If number_float_t is an IEEE-754 single or double precision number,
17106 // use the Grisu2 algorithm to produce short numbers which are
17107 // guaranteed to round-trip, using strtof and strtod, resp.
17108 //
17109 // NB: The test below works if <long double> == <double>.
17110 static constexpr bool is_ieee_single_or_double
17113
17115 }
17116
17117 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
17118 {
17119 auto* begin = number_buffer.data();
17121
17122 o->write_characters(begin, static_cast<size_t>(end - begin));
17123 }
17124
17125 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
17126 {
17127 // get number of digits for a float -> text -> float round-trip
17128 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
17129
17130 // the actual conversion
17131 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17133
17134 // negative value indicates an error
17135 JSON_ASSERT(len > 0);
17136 // check if buffer was large enough
17137 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
17138
17139 // erase thousands separator
17140 if (thousands_sep != '\0')
17141 {
17142 auto* const end = std::remove(number_buffer.begin(),
17144 std::fill(end, number_buffer.end(), '\0');
17146 len = (end - number_buffer.begin());
17147 }
17148
17149 // convert decimal point to '.'
17150 if (decimal_point != '\0' && decimal_point != '.')
17151 {
17153 if (dec_pos != number_buffer.end())
17154 {
17155 *dec_pos = '.';
17156 }
17157 }
17158
17159 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
17160
17161 // determine if need to append ".0"
17162 const bool value_is_int_like =
17164 [](char c)
17165 {
17166 return c == '.' || c == 'e';
17167 });
17168
17170 {
17171 o->write_characters(".0", 2);
17172 }
17173 }
17174
17175 /*!
17176 @brief check whether a string is UTF-8 encoded
17177
17178 The function checks each byte of a string whether it is UTF-8 encoded. The
17179 result of the check is stored in the @a state parameter. The function must
17180 be called initially with state 0 (accept). State 1 means the string must
17181 be rejected, because the current byte is not allowed. If the string is
17182 completely processed, but the state is non-zero, the string ended
17183 prematurely; that is, the last byte indicated more bytes should have
17184 followed.
17185
17186 @param[in,out] state the state of the decoding
17187 @param[in,out] codep codepoint (valid only if resulting state is UTF8_ACCEPT)
17188 @param[in] byte next byte to decode
17189 @return new state
17190
17191 @note The function has been edited: a std::array is used.
17192
17193 @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
17194 @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
17195 */
17196 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
17197 {
17198 static const std::array<std::uint8_t, 400> utf8d =
17199 {
17200 {
17201 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
17202 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
17203 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
17204 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
17205 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
17206 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
17207 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
17208 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
17209 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
17210 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
17211 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
17212 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
17213 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
17214 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
17215 }
17216 };
17217
17219 const std::uint8_t type = utf8d[byte];
17220
17221 codep = (state != UTF8_ACCEPT)
17222 ? (byte & 0x3fu) | (codep << 6u)
17223 : (0xFFu >> type) & (byte);
17224
17225 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
17226 JSON_ASSERT(index < 400);
17227 state = utf8d[index];
17228 return state;
17229 }
17230
17231 /*
17232 * Overload to make the compiler happy while it is instantiating
17233 * dump_integer for number_unsigned_t.
17234 * Must never be called.
17235 */
17236 number_unsigned_t remove_sign(number_unsigned_t x)
17237 {
17238 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17239 return x; // LCOV_EXCL_LINE
17240 }
17241
17242 /*
17243 * Helper function for dump_integer
17244 *
17245 * This function takes a negative signed integer and returns its absolute
17246 * value as unsigned integer. The plus/minus shuffling is necessary as we can
17247 * not directly remove the sign of an arbitrary signed integer as the
17248 * absolute values of INT_MIN and INT_MAX are usually not the same. See
17249 * #1708 for details.
17250 */
17251 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
17252 {
17253 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
17254 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
17255 }
17256
17257 private:
17258 /// the output of the serializer
17259 output_adapter_t<char> o = nullptr;
17260
17261 /// a (hopefully) large enough character buffer
17262 std::array<char, 64> number_buffer{ {} };
17263
17264 /// the locale
17265 const std::lconv* loc = nullptr;
17266 /// the locale's thousand separator character
17267 const char thousands_sep = '\0';
17268 /// the locale's decimal point character
17269 const char decimal_point = '\0';
17270
17271 /// string buffer
17272 std::array<char, 512> string_buffer{ {} };
17273
17274 /// the indentation character
17275 const char indent_char;
17276 /// the indentation string
17278
17279 /// error_handler how to react on decoding errors
17281 };
17282 } // namespace detail
17283} // namespace nlohmann
17284
17285// #include <nlohmann/detail/value_t.hpp>
17286
17287// #include <nlohmann/json_fwd.hpp>
17288
17289// #include <nlohmann/ordered_map.hpp>
17290
17291
17292#include <functional> // less
17293#include <initializer_list> // initializer_list
17294#include <iterator> // input_iterator_tag, iterator_traits
17295#include <memory> // allocator
17296#include <stdexcept> // for out_of_range
17297#include <type_traits> // enable_if, is_convertible
17298#include <utility> // pair
17299#include <vector> // vector
17300
17301// #include <nlohmann/detail/macro_scope.hpp>
17302
17303
17304namespace nlohmann
17305{
17306
17307 /// ordered_map: a minimal map-like container that preserves insertion order
17308 /// for use within nlohmann::basic_json<ordered_map>
17309 template <class Key, class T, class IgnoredLess = std::less<Key>,
17310 class Allocator = std::allocator<std::pair<const Key, T>>>
17311 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
17312 {
17313 using key_type = Key;
17314 using mapped_type = T;
17315 using Container = std::vector<std::pair<const Key, T>, Allocator>;
17316 using typename Container::iterator;
17317 using typename Container::const_iterator;
17318 using typename Container::size_type;
17319 using typename Container::value_type;
17320
17321 // Explicit constructors instead of `using Container::Container`
17322 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
17323 ordered_map(const Allocator& alloc = Allocator()) : Container{ alloc } {}
17324 template <class It>
17325 ordered_map(It first, It last, const Allocator& alloc = Allocator())
17326 : Container{ first, last, alloc } {}
17327 ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator())
17328 : Container{ init, alloc } {}
17329
17330 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
17331 {
17332 for (auto it = this->begin(); it != this->end(); ++it)
17333 {
17334 if (it->first == key)
17335 {
17336 return { it, false };
17337 }
17338 }
17339 Container::emplace_back(key, t);
17340 return { --this->end(), true };
17341 }
17342
17343 T& operator[](const Key& key)
17344 {
17345 return emplace(key, T{}).first->second;
17346 }
17347
17348 const T& operator[](const Key& key) const
17349 {
17350 return at(key);
17351 }
17352
17353 T& at(const Key& key)
17354 {
17355 for (auto it = this->begin(); it != this->end(); ++it)
17356 {
17357 if (it->first == key)
17358 {
17359 return it->second;
17360 }
17361 }
17362
17363 JSON_THROW(std::out_of_range("key not found"));
17364 }
17365
17366 const T& at(const Key& key) const
17367 {
17368 for (auto it = this->begin(); it != this->end(); ++it)
17369 {
17370 if (it->first == key)
17371 {
17372 return it->second;
17373 }
17374 }
17375
17376 JSON_THROW(std::out_of_range("key not found"));
17377 }
17378
17379 size_type erase(const Key& key)
17380 {
17381 for (auto it = this->begin(); it != this->end(); ++it)
17382 {
17383 if (it->first == key)
17384 {
17385 // Since we cannot move const Keys, re-construct them in place
17386 for (auto next = it; ++next != this->end(); ++it)
17387 {
17388 it->~value_type(); // Destroy but keep allocation
17389 new (&*it) value_type{ std::move(*next) };
17390 }
17391 Container::pop_back();
17392 return 1;
17393 }
17394 }
17395 return 0;
17396 }
17397
17398 iterator erase(iterator pos)
17399 {
17400 auto it = pos;
17401
17402 // Since we cannot move const Keys, re-construct them in place
17403 for (auto next = it; ++next != this->end(); ++it)
17404 {
17405 it->~value_type(); // Destroy but keep allocation
17406 new (&*it) value_type{ std::move(*next) };
17407 }
17408 Container::pop_back();
17409 return pos;
17410 }
17411
17412 size_type count(const Key& key) const
17413 {
17414 for (auto it = this->begin(); it != this->end(); ++it)
17415 {
17416 if (it->first == key)
17417 {
17418 return 1;
17419 }
17420 }
17421 return 0;
17422 }
17423
17424 iterator find(const Key& key)
17425 {
17426 for (auto it = this->begin(); it != this->end(); ++it)
17427 {
17428 if (it->first == key)
17429 {
17430 return it;
17431 }
17432 }
17433 return Container::end();
17434 }
17435
17436 const_iterator find(const Key& key) const
17437 {
17438 for (auto it = this->begin(); it != this->end(); ++it)
17439 {
17440 if (it->first == key)
17441 {
17442 return it;
17443 }
17444 }
17445 return Container::end();
17446 }
17447
17448 std::pair<iterator, bool> insert(value_type&& value)
17449 {
17450 return emplace(value.first, std::move(value.second));
17451 }
17452
17453 std::pair<iterator, bool> insert(const value_type& value)
17454 {
17455 for (auto it = this->begin(); it != this->end(); ++it)
17456 {
17457 if (it->first == value.first)
17458 {
17459 return { it, false };
17460 }
17461 }
17462 Container::push_back(value);
17463 return { --this->end(), true };
17464 }
17465
17466 template<typename InputIt>
17467 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
17468 std::input_iterator_tag>::value>::type;
17469
17470 template<typename InputIt, typename = require_input_iter<InputIt>>
17471 void insert(InputIt first, InputIt last)
17472 {
17473 for (auto it = first; it != last; ++it)
17474 {
17475 insert(*it);
17476 }
17477 }
17478 };
17479
17480} // namespace nlohmann
17481
17482
17483#if defined(JSON_HAS_CPP_17)
17484#include <string_view>
17485#endif
17486
17487/*!
17488@brief namespace for Niels Lohmann
17489@see https://github.com/nlohmann
17490@since version 1.0.0
17491*/
17492namespace nlohmann
17493{
17494
17495 /*!
17496 @brief a class to store JSON values
17497
17498 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
17499 in @ref object_t)
17500 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
17501 in @ref array_t)
17502 @tparam StringType type for JSON strings and object keys (`std::string` by
17503 default; will be used in @ref string_t)
17504 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
17505 in @ref boolean_t)
17506 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
17507 default; will be used in @ref number_integer_t)
17508 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
17509 `uint64_t` by default; will be used in @ref number_unsigned_t)
17510 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
17511 default; will be used in @ref number_float_t)
17512 @tparam BinaryType type for packed binary data for compatibility with binary
17513 serialization formats (`std::vector<std::uint8_t>` by default; will be used in
17514 @ref binary_t)
17515 @tparam AllocatorType type of the allocator to use (`std::allocator` by
17516 default)
17517 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
17518 and `from_json()` (@ref adl_serializer by default)
17519
17520 @requirement The class satisfies the following concept requirements:
17521 - Basic
17522 - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
17523 JSON values can be default constructed. The result will be a JSON null
17524 value.
17525 - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
17526 A JSON value can be constructed from an rvalue argument.
17527 - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
17528 A JSON value can be copy-constructed from an lvalue expression.
17529 - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
17530 A JSON value van be assigned from an rvalue argument.
17531 - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
17532 A JSON value can be copy-assigned from an lvalue expression.
17533 - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
17534 JSON values can be destructed.
17535 - Layout
17536 - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
17537 JSON values have
17538 [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
17539 All non-static data members are private and standard layout types, the
17540 class has no virtual functions or (virtual) base classes.
17541 - Library-wide
17542 - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
17543 JSON values can be compared with `==`, see @ref
17544 operator==(const_reference,const_reference).
17545 - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
17546 JSON values can be compared with `<`, see @ref
17547 operator<(const_reference,const_reference).
17548 - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
17549 Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
17550 other compatible types, using unqualified function call @ref swap().
17551 - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
17552 JSON values can be compared against `std::nullptr_t` objects which are used
17553 to model the `null` value.
17554 - Container
17555 - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
17556 JSON values can be used like STL containers and provide iterator access.
17557 - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
17558 JSON values can be used like STL containers and provide reverse iterator
17559 access.
17560
17561 @invariant The member variables @a m_value and @a m_type have the following
17562 relationship:
17563 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
17564 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
17565 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
17566 The invariants are checked by member function assert_invariant().
17567
17568 @internal
17569 @note ObjectType trick from https://stackoverflow.com/a/9860911
17570 @endinternal
17571
17572 @see [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange
17573 Format](https://tools.ietf.org/html/rfc8259)
17574
17575 @since version 1.0.0
17576
17577 @nosubgrouping
17578 */
17580 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
17581 {
17582 private:
17583 template<detail::value_t> friend struct detail::external_constructor;
17584 friend ::nlohmann::json_pointer<basic_json>;
17585
17586 template<typename BasicJsonType, typename InputType>
17587 friend class ::nlohmann::detail::parser;
17589 template<typename BasicJsonType>
17590 friend class ::nlohmann::detail::iter_impl;
17591 template<typename BasicJsonType, typename CharType>
17593 template<typename BasicJsonType, typename InputType, typename SAX>
17595 template<typename BasicJsonType>
17597 template<typename BasicJsonType>
17599 friend class ::nlohmann::detail::exception;
17600
17601 /// workaround type for MSVC
17603
17605 // convenience aliases for types residing in namespace detail;
17606 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
17607
17608 template<typename InputAdapterType>
17609 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
17610 InputAdapterType adapter,
17611 detail::parser_callback_t<basic_json>cb = nullptr,
17612 const bool allow_exceptions = true,
17613 const bool ignore_comments = false
17614 )
17615 {
17618 }
17619
17620 private:
17621 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
17622 template<typename BasicJsonType>
17623 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
17624 template<typename BasicJsonType>
17625 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
17626 template<typename Iterator>
17627 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
17628 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
17629
17630 template<typename CharType>
17632
17633 template<typename InputType>
17635 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
17636
17638 using serializer = ::nlohmann::detail::serializer<basic_json>;
17639
17640 public:
17641 using value_t = detail::value_t;
17642 /// JSON Pointer, see @ref nlohmann::json_pointer
17643 using json_pointer = ::nlohmann::json_pointer<basic_json>;
17644 template<typename T, typename SFINAE>
17645 using json_serializer = JSONSerializer<T, SFINAE>;
17646 /// how to treat decoding errors
17647 using error_handler_t = detail::error_handler_t;
17648 /// how to treat CBOR tags
17649 using cbor_tag_handler_t = detail::cbor_tag_handler_t;
17650 /// helper type for initializer lists of basic_json values
17651 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
17652
17653 using input_format_t = detail::input_format_t;
17654 /// SAX interface type, see @ref nlohmann::json_sax
17655 using json_sax_t = json_sax<basic_json>;
17656
17657 ////////////////
17658 // exceptions //
17659 ////////////////
17660
17661 /// @name exceptions
17662 /// Classes to implement user-defined exceptions.
17663 /// @{
17664
17665 /// @copydoc detail::exception
17666 using exception = detail::exception;
17667 /// @copydoc detail::parse_error
17668 using parse_error = detail::parse_error;
17669 /// @copydoc detail::invalid_iterator
17670 using invalid_iterator = detail::invalid_iterator;
17671 /// @copydoc detail::type_error
17672 using type_error = detail::type_error;
17673 /// @copydoc detail::out_of_range
17674 using out_of_range = detail::out_of_range;
17675 /// @copydoc detail::other_error
17676 using other_error = detail::other_error;
17677
17678 /// @}
17679
17680
17681 /////////////////////
17682 // container types //
17683 /////////////////////
17684
17685 /// @name container types
17686 /// The canonic container types to use @ref basic_json like any other STL
17687 /// container.
17688 /// @{
17689
17690 /// the type of elements in a basic_json container
17691 using value_type = basic_json;
17692
17693 /// the type of an element reference
17694 using reference = value_type&;
17695 /// the type of an element const reference
17696 using const_reference = const value_type&;
17697
17698 /// a type to represent differences between iterators
17699 using difference_type = std::ptrdiff_t;
17700 /// a type to represent container sizes
17701 using size_type = std::size_t;
17702
17703 /// the allocator type
17704 using allocator_type = AllocatorType<basic_json>;
17705
17706 /// the type of an element pointer
17707 using pointer = typename std::allocator_traits<allocator_type>::pointer;
17708 /// the type of an element const pointer
17709 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
17710
17711 /// an iterator for a basic_json container
17713 /// a const iterator for a basic_json container
17715 /// a reverse iterator for a basic_json container
17717 /// a const reverse iterator for a basic_json container
17719
17720 /// @}
17721
17722
17723 /*!
17724 @brief returns the allocator associated with the container
17725 */
17726 static allocator_type get_allocator()
17727 {
17728 return allocator_type();
17729 }
17730
17731 /*!
17732 @brief returns version information on the library
17733
17734 This function returns a JSON object with information about the library,
17735 including the version number and information on the platform and compiler.
17736
17737 @return JSON object holding version information
17738 key | description
17739 ----------- | ---------------
17740 `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).
17741 `copyright` | The copyright line for the library as string.
17742 `name` | The name of the library as string.
17743 `platform` | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
17744 `url` | The URL of the project as string.
17745 `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).
17746
17747 @liveexample{The following code shows an example output of the `meta()`
17748 function.,meta}
17749
17750 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17751 changes to any JSON value.
17752
17753 @complexity Constant.
17754
17755 @since 2.1.0
17756 */
17759 {
17761
17762 result["copyright"] = "(C) 2013-2021 Niels Lohmann";
17763 result["name"] = "JSON for Modern C++";
17764 result["url"] = "https://github.com/nlohmann/json";
17765 result["version"]["string"] =
17769 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
17770 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
17771 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
17772
17773#ifdef _WIN32
17774 result["platform"] = "win32";
17775#elif defined __linux__
17776 result["platform"] = "linux";
17777#elif defined __APPLE__
17778 result["platform"] = "apple";
17779#elif defined __unix__
17780 result["platform"] = "unix";
17781#else
17782 result["platform"] = "unknown";
17783#endif
17784
17785#if defined(__ICC) || defined(__INTEL_COMPILER)
17786 result["compiler"] = { {"family", "icc"}, {"version", __INTEL_COMPILER} };
17787#elif defined(__clang__)
17788 result["compiler"] = { {"family", "clang"}, {"version", __clang_version__} };
17789#elif defined(__GNUC__) || defined(__GNUG__)
17790 result["compiler"] = { {"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)} };
17791#elif defined(__HP_cc) || defined(__HP_aCC)
17792 result["compiler"] = "hp"
17793#elif defined(__IBMCPP__)
17794 result["compiler"] = { {"family", "ilecpp"}, {"version", __IBMCPP__} };
17795#elif defined(_MSC_VER)
17796 result["compiler"] = { {"family", "msvc"}, {"version", _MSC_VER} };
17797#elif defined(__PGI)
17798 result["compiler"] = { {"family", "pgcpp"}, {"version", __PGI} };
17799#elif defined(__SUNPRO_CC)
17800 result["compiler"] = { {"family", "sunpro"}, {"version", __SUNPRO_CC} };
17801#else
17802 result["compiler"] = { {"family", "unknown"}, {"version", "unknown"} };
17803#endif
17804
17805#ifdef __cplusplus
17806 result["compiler"]["c++"] = std::to_string(__cplusplus);
17807#else
17808 result["compiler"]["c++"] = "unknown";
17809#endif
17810 return result;
17811 }
17812
17813
17814 ///////////////////////////
17815 // JSON value data types //
17816 ///////////////////////////
17817
17818 /// @name JSON value data types
17819 /// The data types to store a JSON value. These types are derived from
17820 /// the template arguments passed to class @ref basic_json.
17821 /// @{
17822
17823#if defined(JSON_HAS_CPP_14)
17824 // Use transparent comparator if possible, combined with perfect forwarding
17825 // on find() and count() calls prevents unnecessary string construction.
17826 using object_comparator_t = std::less<>;
17827#else
17829#endif
17830
17831 /*!
17832 @brief a type for an object
17833
17834 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows:
17835 > An object is an unordered collection of zero or more name/value pairs,
17836 > where a name is a string and a value is a string, number, boolean, null,
17837 > object, or array.
17838
17839 To store objects in C++, a type is defined by the template parameters
17840 described below.
17841
17842 @tparam ObjectType the container to store objects (e.g., `std::map` or
17843 `std::unordered_map`)
17844 @tparam StringType the type of the keys or names (e.g., `std::string`).
17845 The comparison function `std::less<StringType>` is used to order elements
17846 inside the container.
17847 @tparam AllocatorType the allocator to use for objects (e.g.,
17848 `std::allocator`)
17849
17850 #### Default type
17851
17852 With the default values for @a ObjectType (`std::map`), @a StringType
17853 (`std::string`), and @a AllocatorType (`std::allocator`), the default
17854 value for @a object_t is:
17855
17856 @code {.cpp}
17857 std::map<
17858 std::string, // key_type
17859 basic_json, // value_type
17860 std::less<std::string>, // key_compare
17861 std::allocator<std::pair<const std::string, basic_json>> // allocator_type
17862 >
17863 @endcode
17864
17865 #### Behavior
17866
17867 The choice of @a object_t influences the behavior of the JSON class. With
17868 the default type, objects have the following behavior:
17869
17870 - When all names are unique, objects will be interoperable in the sense
17871 that all software implementations receiving that object will agree on
17872 the name-value mappings.
17873 - When the names within an object are not unique, it is unspecified which
17874 one of the values for a given key will be chosen. For instance,
17875 `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
17876 `{"key": 2}`.
17877 - Internally, name/value pairs are stored in lexicographical order of the
17878 names. Objects will also be serialized (see @ref dump) in this order.
17879 For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
17880 and serialized as `{"a": 2, "b": 1}`.
17881 - When comparing objects, the order of the name/value pairs is irrelevant.
17882 This makes objects interoperable in the sense that they will not be
17883 affected by these differences. For instance, `{"b": 1, "a": 2}` and
17884 `{"a": 2, "b": 1}` will be treated as equal.
17885
17886 #### Limits
17887
17888 [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
17889 > An implementation may set limits on the maximum depth of nesting.
17890
17891 In this class, the object's limit of nesting is not explicitly constrained.
17892 However, a maximum depth of nesting may be introduced by the compiler or
17893 runtime environment. A theoretical limit can be queried by calling the
17894 @ref max_size function of a JSON object.
17895
17896 #### Storage
17897
17898 Objects are stored as pointers in a @ref basic_json type. That is, for any
17899 access to object values, a pointer of type `object_t*` must be
17900 dereferenced.
17901
17902 @sa see @ref array_t -- type for an array value
17903
17904 @since version 1.0.0
17905
17906 @note The order name/value pairs are added to the object is *not*
17907 preserved by the library. Therefore, iterating an object may return
17908 name/value pairs in a different order than they were originally stored. In
17909 fact, keys will be traversed in alphabetical order as `std::map` with
17910 `std::less` is used by default. Please note this behavior conforms to [RFC
17911 8259](https://tools.ietf.org/html/rfc8259), because any order implements the
17912 specified "unordered" nature of JSON objects.
17913 */
17915 basic_json,
17918 basic_json>>>;
17919
17920 /*!
17921 @brief a type for an array
17922
17923 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows:
17924 > An array is an ordered sequence of zero or more values.
17925
17926 To store objects in C++, a type is defined by the template parameters
17927 explained below.
17928
17929 @tparam ArrayType container type to store arrays (e.g., `std::vector` or
17930 `std::list`)
17931 @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
17932
17933 #### Default type
17934
17935 With the default values for @a ArrayType (`std::vector`) and @a
17936 AllocatorType (`std::allocator`), the default value for @a array_t is:
17937
17938 @code {.cpp}
17939 std::vector<
17940 basic_json, // value_type
17941 std::allocator<basic_json> // allocator_type
17942 >
17943 @endcode
17944
17945 #### Limits
17946
17947 [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
17948 > An implementation may set limits on the maximum depth of nesting.
17949
17950 In this class, the array's limit of nesting is not explicitly constrained.
17951 However, a maximum depth of nesting may be introduced by the compiler or
17952 runtime environment. A theoretical limit can be queried by calling the
17953 @ref max_size function of a JSON array.
17954
17955 #### Storage
17956
17957 Arrays are stored as pointers in a @ref basic_json type. That is, for any
17958 access to array values, a pointer of type `array_t*` must be dereferenced.
17959
17960 @sa see @ref object_t -- type for an object value
17961
17962 @since version 1.0.0
17963 */
17964 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17965
17966 /*!
17967 @brief a type for a string
17968
17969 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows:
17970 > A string is a sequence of zero or more Unicode characters.
17971
17972 To store objects in C++, a type is defined by the template parameter
17973 described below. Unicode values are split by the JSON class into
17974 byte-sized characters during deserialization.
17975
17976 @tparam StringType the container to store strings (e.g., `std::string`).
17977 Note this container is used for keys/names in objects, see @ref object_t.
17978
17979 #### Default type
17980
17981 With the default values for @a StringType (`std::string`), the default
17982 value for @a string_t is:
17983
17984 @code {.cpp}
17985 std::string
17986 @endcode
17987
17988 #### Encoding
17989
17990 Strings are stored in UTF-8 encoding. Therefore, functions like
17991 `std::string::size()` or `std::string::length()` return the number of
17992 bytes in the string rather than the number of characters or glyphs.
17993
17994 #### String comparison
17995
17996 [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
17997 > Software implementations are typically required to test names of object
17998 > members for equality. Implementations that transform the textual
17999 > representation into sequences of Unicode code units and then perform the
18000 > comparison numerically, code unit by code unit, are interoperable in the
18001 > sense that implementations will agree in all cases on equality or
18002 > inequality of two strings. For example, implementations that compare
18003 > strings with escaped characters unconverted may incorrectly find that
18004 > `"a\\b"` and `"a\u005Cb"` are not equal.
18005
18006 This implementation is interoperable as it does compare strings code unit
18007 by code unit.
18008
18009 #### Storage
18010
18011 String values are stored as pointers in a @ref basic_json type. That is,
18012 for any access to string values, a pointer of type `string_t*` must be
18013 dereferenced.
18014
18015 @since version 1.0.0
18016 */
18017 using string_t = StringType;
18018
18019 /*!
18020 @brief a type for a boolean
18021
18022 [RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a
18023 type which differentiates the two literals `true` and `false`.
18024
18025 To store objects in C++, a type is defined by the template parameter @a
18026 BooleanType which chooses the type to use.
18027
18028 #### Default type
18029
18030 With the default values for @a BooleanType (`bool`), the default value for
18031 @a boolean_t is:
18032
18033 @code {.cpp}
18034 bool
18035 @endcode
18036
18037 #### Storage
18038
18039 Boolean values are stored directly inside a @ref basic_json type.
18040
18041 @since version 1.0.0
18042 */
18043 using boolean_t = BooleanType;
18044
18045 /*!
18046 @brief a type for a number (integer)
18047
18048 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18049 > The representation of numbers is similar to that used in most
18050 > programming languages. A number is represented in base 10 using decimal
18051 > digits. It contains an integer component that may be prefixed with an
18052 > optional minus sign, which may be followed by a fraction part and/or an
18053 > exponent part. Leading zeros are not allowed. (...) Numeric values that
18054 > cannot be represented in the grammar below (such as Infinity and NaN)
18055 > are not permitted.
18056
18057 This description includes both integer and floating-point numbers.
18058 However, C++ allows more precise storage if it is known whether the number
18059 is a signed integer, an unsigned integer or a floating-point number.
18060 Therefore, three different types, @ref number_integer_t, @ref
18061 number_unsigned_t and @ref number_float_t are used.
18062
18063 To store integer numbers in C++, a type is defined by the template
18064 parameter @a NumberIntegerType which chooses the type to use.
18065
18066 #### Default type
18067
18068 With the default values for @a NumberIntegerType (`int64_t`), the default
18069 value for @a number_integer_t is:
18070
18071 @code {.cpp}
18072 int64_t
18073 @endcode
18074
18075 #### Default behavior
18076
18077 - The restrictions about leading zeros is not enforced in C++. Instead,
18078 leading zeros in integer literals lead to an interpretation as octal
18079 number. Internally, the value will be stored as decimal number. For
18080 instance, the C++ integer literal `010` will be serialized to `8`.
18081 During deserialization, leading zeros yield an error.
18082 - Not-a-number (NaN) values will be serialized to `null`.
18083
18084 #### Limits
18085
18086 [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
18087 > An implementation may set limits on the range and precision of numbers.
18088
18089 When the default type is used, the maximal integer number that can be
18090 stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
18091 that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
18092 that are out of range will yield over/underflow when used in a
18093 constructor. During deserialization, too large or small integer numbers
18094 will be automatically be stored as @ref number_unsigned_t or @ref
18095 number_float_t.
18096
18097 [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
18098 > Note that when such software is used, numbers that are integers and are
18099 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
18100 > that implementations will agree exactly on their numeric values.
18101
18102 As this range is a subrange of the exactly supported range [INT64_MIN,
18103 INT64_MAX], this class's integer type is interoperable.
18104
18105 #### Storage
18106
18107 Integer number values are stored directly inside a @ref basic_json type.
18108
18109 @sa see @ref number_float_t -- type for number values (floating-point)
18110
18111 @sa see @ref number_unsigned_t -- type for number values (unsigned integer)
18112
18113 @since version 1.0.0
18114 */
18115 using number_integer_t = NumberIntegerType;
18116
18117 /*!
18118 @brief a type for a number (unsigned)
18119
18120 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18121 > The representation of numbers is similar to that used in most
18122 > programming languages. A number is represented in base 10 using decimal
18123 > digits. It contains an integer component that may be prefixed with an
18124 > optional minus sign, which may be followed by a fraction part and/or an
18125 > exponent part. Leading zeros are not allowed. (...) Numeric values that
18126 > cannot be represented in the grammar below (such as Infinity and NaN)
18127 > are not permitted.
18128
18129 This description includes both integer and floating-point numbers.
18130 However, C++ allows more precise storage if it is known whether the number
18131 is a signed integer, an unsigned integer or a floating-point number.
18132 Therefore, three different types, @ref number_integer_t, @ref
18133 number_unsigned_t and @ref number_float_t are used.
18134
18135 To store unsigned integer numbers in C++, a type is defined by the
18136 template parameter @a NumberUnsignedType which chooses the type to use.
18137
18138 #### Default type
18139
18140 With the default values for @a NumberUnsignedType (`uint64_t`), the
18141 default value for @a number_unsigned_t is:
18142
18143 @code {.cpp}
18144 uint64_t
18145 @endcode
18146
18147 #### Default behavior
18148
18149 - The restrictions about leading zeros is not enforced in C++. Instead,
18150 leading zeros in integer literals lead to an interpretation as octal
18151 number. Internally, the value will be stored as decimal number. For
18152 instance, the C++ integer literal `010` will be serialized to `8`.
18153 During deserialization, leading zeros yield an error.
18154 - Not-a-number (NaN) values will be serialized to `null`.
18155
18156 #### Limits
18157
18158 [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
18159 > An implementation may set limits on the range and precision of numbers.
18160
18161 When the default type is used, the maximal integer number that can be
18162 stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
18163 number that can be stored is `0`. Integer numbers that are out of range
18164 will yield over/underflow when used in a constructor. During
18165 deserialization, too large or small integer numbers will be automatically
18166 be stored as @ref number_integer_t or @ref number_float_t.
18167
18168 [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
18169 > Note that when such software is used, numbers that are integers and are
18170 > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
18171 > that implementations will agree exactly on their numeric values.
18172
18173 As this range is a subrange (when considered in conjunction with the
18174 number_integer_t type) of the exactly supported range [0, UINT64_MAX],
18175 this class's integer type is interoperable.
18176
18177 #### Storage
18178
18179 Integer number values are stored directly inside a @ref basic_json type.
18180
18181 @sa see @ref number_float_t -- type for number values (floating-point)
18182 @sa see @ref number_integer_t -- type for number values (integer)
18183
18184 @since version 2.0.0
18185 */
18186 using number_unsigned_t = NumberUnsignedType;
18187
18188 /*!
18189 @brief a type for a number (floating-point)
18190
18191 [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18192 > The representation of numbers is similar to that used in most
18193 > programming languages. A number is represented in base 10 using decimal
18194 > digits. It contains an integer component that may be prefixed with an
18195 > optional minus sign, which may be followed by a fraction part and/or an
18196 > exponent part. Leading zeros are not allowed. (...) Numeric values that
18197 > cannot be represented in the grammar below (such as Infinity and NaN)
18198 > are not permitted.
18199
18200 This description includes both integer and floating-point numbers.
18201 However, C++ allows more precise storage if it is known whether the number
18202 is a signed integer, an unsigned integer or a floating-point number.
18203 Therefore, three different types, @ref number_integer_t, @ref
18204 number_unsigned_t and @ref number_float_t are used.
18205
18206 To store floating-point numbers in C++, a type is defined by the template
18207 parameter @a NumberFloatType which chooses the type to use.
18208
18209 #### Default type
18210
18211 With the default values for @a NumberFloatType (`double`), the default
18212 value for @a number_float_t is:
18213
18214 @code {.cpp}
18215 double
18216 @endcode
18217
18218 #### Default behavior
18219
18220 - The restrictions about leading zeros is not enforced in C++. Instead,
18221 leading zeros in floating-point literals will be ignored. Internally,
18222 the value will be stored as decimal number. For instance, the C++
18223 floating-point literal `01.2` will be serialized to `1.2`. During
18224 deserialization, leading zeros yield an error.
18225 - Not-a-number (NaN) values will be serialized to `null`.
18226
18227 #### Limits
18228
18229 [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
18230 > This specification allows implementations to set limits on the range and
18231 > precision of numbers accepted. Since software that implements IEEE
18232 > 754-2008 binary64 (double precision) numbers is generally available and
18233 > widely used, good interoperability can be achieved by implementations
18234 > that expect no more precision or range than these provide, in the sense
18235 > that implementations will approximate JSON numbers within the expected
18236 > precision.
18237
18238 This implementation does exactly follow this approach, as it uses double
18239 precision floating-point numbers. Note values smaller than
18240 `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
18241 will be stored as NaN internally and be serialized to `null`.
18242
18243 #### Storage
18244
18245 Floating-point number values are stored directly inside a @ref basic_json
18246 type.
18247
18248 @sa see @ref number_integer_t -- type for number values (integer)
18249
18250 @sa see @ref number_unsigned_t -- type for number values (unsigned integer)
18251
18252 @since version 1.0.0
18253 */
18254 using number_float_t = NumberFloatType;
18255
18256 /*!
18257 @brief a type for a packed binary type
18258
18259 This type is a type designed to carry binary data that appears in various
18260 serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
18261 BSON's generic binary subtype. This type is NOT a part of standard JSON and
18262 exists solely for compatibility with these binary types. As such, it is
18263 simply defined as an ordered sequence of zero or more byte values.
18264
18265 Additionally, as an implementation detail, the subtype of the binary data is
18266 carried around as a `std::uint8_t`, which is compatible with both of the
18267 binary data formats that use binary subtyping, (though the specific
18268 numbering is incompatible with each other, and it is up to the user to
18269 translate between them).
18270
18271 [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
18272 as:
18273 > Major type 2: a byte string. The string's length in bytes is represented
18274 > following the rules for positive integers (major type 0).
18275
18276 [MessagePack's documentation on the bin type
18277 family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
18278 describes this type as:
18279 > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes
18280 > in addition to the size of the byte array.
18281
18282 [BSON's specifications](http://bsonspec.org/spec.html) describe several
18283 binary types; however, this type is intended to represent the generic binary
18284 type which has the description:
18285 > Generic binary subtype - This is the most commonly used binary subtype and
18286 > should be the 'default' for drivers and tools.
18287
18288 None of these impose any limitations on the internal representation other
18289 than the basic unit of storage be some type of array whose parts are
18290 decomposable into bytes.
18291
18292 The default representation of this binary format is a
18293 `std::vector<std::uint8_t>`, which is a very common way to represent a byte
18294 array in modern C++.
18295
18296 #### Default type
18297
18298 The default values for @a BinaryType is `std::vector<std::uint8_t>`
18299
18300 #### Storage
18301
18302 Binary Arrays are stored as pointers in a @ref basic_json type. That is,
18303 for any access to array values, a pointer of the type `binary_t*` must be
18304 dereferenced.
18305
18306 #### Notes on subtypes
18307
18308 - CBOR
18309 - Binary values are represented as byte strings. Subtypes are serialized
18310 as tagged values.
18311 - MessagePack
18312 - If a subtype is given and the binary array contains exactly 1, 2, 4, 8,
18313 or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8)
18314 is used. For other sizes, the ext family (ext8, ext16, ext32) is used.
18315 The subtype is then added as singed 8-bit integer.
18316 - If no subtype is given, the bin family (bin8, bin16, bin32) is used.
18317 - BSON
18318 - If a subtype is given, it is used and added as unsigned 8-bit integer.
18319 - If no subtype is given, the generic binary subtype 0x00 is used.
18320
18321 @sa see @ref binary -- create a binary array
18322
18323 @since version 3.8.0
18324 */
18325 using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
18326 /// @}
18327
18328 private:
18329
18330 /// helper for exception-safe object creation
18331 template<typename T, typename... Args>
18333 static T* create(Args&& ... args)
18334 {
18337
18338 auto deleter = [&](T* obj)
18339 {
18341 };
18344 JSON_ASSERT(obj != nullptr);
18345 return obj.release();
18346 }
18347
18348 ////////////////////////
18349 // JSON value storage //
18350 ////////////////////////
18351
18353 /*!
18354 @brief a JSON value
18355
18356 The actual storage for a JSON value of the @ref basic_json class. This
18357 union combines the different storage types for the JSON value types
18358 defined in @ref value_t.
18359
18360 JSON type | value_t type | used type
18361 --------- | --------------- | ------------------------
18362 object | object | pointer to @ref object_t
18363 array | array | pointer to @ref array_t
18364 string | string | pointer to @ref string_t
18365 boolean | boolean | @ref boolean_t
18366 number | number_integer | @ref number_integer_t
18367 number | number_unsigned | @ref number_unsigned_t
18368 number | number_float | @ref number_float_t
18369 binary | binary | pointer to @ref binary_t
18370 null | null | *no value is stored*
18371
18372 @note Variable-length types (objects, arrays, and strings) are stored as
18373 pointers. The size of the union should not exceed 64 bits if the default
18374 value types are used.
18375
18376 @since version 1.0.0
18377 */
18378 union json_value
18379 {
18380 /// object (stored with pointer to save storage)
18381 object_t* object;
18382 /// array (stored with pointer to save storage)
18383 array_t* array;
18384 /// string (stored with pointer to save storage)
18385 string_t* string;
18386 /// binary (stored with pointer to save storage)
18387 binary_t* binary;
18388 /// boolean
18389 boolean_t boolean;
18390 /// number (integer)
18391 number_integer_t number_integer;
18392 /// number (unsigned integer)
18393 number_unsigned_t number_unsigned;
18394 /// number (floating-point)
18395 number_float_t number_float;
18396
18397 /// default constructor (for null values)
18398 json_value() = default;
18399 /// constructor for booleans
18400 json_value(boolean_t v) noexcept : boolean(v) {}
18401 /// constructor for numbers (integer)
18402 json_value(number_integer_t v) noexcept : number_integer(v) {}
18403 /// constructor for numbers (unsigned)
18404 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
18405 /// constructor for numbers (floating-point)
18406 json_value(number_float_t v) noexcept : number_float(v) {}
18407 /// constructor for empty values of a given type
18408 json_value(value_t t)
18409 {
18410 switch (t)
18411 {
18412 case value_t::object:
18413 {
18414 object = create<object_t>();
18415 break;
18416 }
18417
18418 case value_t::array:
18419 {
18420 array = create<array_t>();
18421 break;
18422 }
18423
18424 case value_t::string:
18425 {
18426 string = create<string_t>("");
18427 break;
18428 }
18429
18430 case value_t::binary:
18431 {
18432 binary = create<binary_t>();
18433 break;
18434 }
18435
18436 case value_t::boolean:
18437 {
18438 boolean = boolean_t(false);
18439 break;
18440 }
18441
18442 case value_t::number_integer:
18443 {
18444 number_integer = number_integer_t(0);
18445 break;
18446 }
18447
18448 case value_t::number_unsigned:
18449 {
18450 number_unsigned = number_unsigned_t(0);
18451 break;
18452 }
18453
18454 case value_t::number_float:
18455 {
18456 number_float = number_float_t(0.0);
18457 break;
18458 }
18459
18460 case value_t::null:
18461 {
18462 object = nullptr; // silence warning, see #821
18463 break;
18464 }
18465
18466 case value_t::discarded:
18467 default:
18468 {
18469 object = nullptr; // silence warning, see #821
18470 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
18471 {
18472 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.2", basic_json())); // LCOV_EXCL_LINE
18473 }
18474 break;
18475 }
18476 }
18477 }
18478
18479 /// constructor for strings
18480 json_value(const string_t& value)
18481 {
18482 string = create<string_t>(value);
18483 }
18484
18485 /// constructor for rvalue strings
18486 json_value(string_t&& value)
18487 {
18488 string = create<string_t>(std::move(value));
18489 }
18490
18491 /// constructor for objects
18492 json_value(const object_t& value)
18493 {
18494 object = create<object_t>(value);
18495 }
18496
18497 /// constructor for rvalue objects
18498 json_value(object_t&& value)
18499 {
18500 object = create<object_t>(std::move(value));
18501 }
18502
18503 /// constructor for arrays
18504 json_value(const array_t& value)
18505 {
18506 array = create<array_t>(value);
18507 }
18508
18509 /// constructor for rvalue arrays
18510 json_value(array_t&& value)
18511 {
18512 array = create<array_t>(std::move(value));
18513 }
18514
18515 /// constructor for binary arrays
18516 json_value(const typename binary_t::container_type& value)
18517 {
18518 binary = create<binary_t>(value);
18519 }
18520
18521 /// constructor for rvalue binary arrays
18522 json_value(typename binary_t::container_type&& value)
18523 {
18524 binary = create<binary_t>(std::move(value));
18525 }
18526
18527 /// constructor for binary arrays (internal type)
18528 json_value(const binary_t& value)
18529 {
18530 binary = create<binary_t>(value);
18531 }
18532
18533 /// constructor for rvalue binary arrays (internal type)
18534 json_value(binary_t&& value)
18535 {
18536 binary = create<binary_t>(std::move(value));
18537 }
18538
18539 void destroy(value_t t)
18540 {
18541 if (t == value_t::array || t == value_t::object)
18542 {
18543 // flatten the current json_value to a heap-allocated stack
18544 std::vector<basic_json> stack;
18545
18546 // move the top-level items to stack
18547 if (t == value_t::array)
18548 {
18549 stack.reserve(array->size());
18550 std::move(array->begin(), array->end(), std::back_inserter(stack));
18551 }
18552 else
18553 {
18554 stack.reserve(object->size());
18555 for (auto&& it : *object)
18556 {
18557 stack.push_back(std::move(it.second));
18558 }
18559 }
18560
18561 while (!stack.empty())
18562 {
18563 // move the last item to local variable to be processed
18564 basic_json current_item(std::move(stack.back()));
18565 stack.pop_back();
18566
18567 // if current_item is array/object, move
18568 // its children to the stack to be processed later
18569 if (current_item.is_array())
18570 {
18571 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
18572
18573 current_item.m_value.array->clear();
18574 }
18575 else if (current_item.is_object())
18576 {
18577 for (auto&& it : *current_item.m_value.object)
18578 {
18579 stack.push_back(std::move(it.second));
18580 }
18581
18582 current_item.m_value.object->clear();
18583 }
18584
18585 // it's now safe that current_item get destructed
18586 // since it doesn't have any children
18587 }
18588 }
18589
18590 switch (t)
18591 {
18592 case value_t::object:
18593 {
18594 AllocatorType<object_t> alloc;
18595 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18596 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18597 break;
18598 }
18599
18600 case value_t::array:
18601 {
18602 AllocatorType<array_t> alloc;
18603 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18604 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18605 break;
18606 }
18607
18608 case value_t::string:
18609 {
18610 AllocatorType<string_t> alloc;
18611 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18612 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18613 break;
18614 }
18615
18616 case value_t::binary:
18617 {
18618 AllocatorType<binary_t> alloc;
18619 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18620 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18621 break;
18622 }
18623
18624 case value_t::null:
18625 case value_t::boolean:
18626 case value_t::number_integer:
18627 case value_t::number_unsigned:
18628 case value_t::number_float:
18629 case value_t::discarded:
18630 default:
18631 {
18632 break;
18633 }
18634 }
18635 }
18636 };
18637
18638 private:
18639 /*!
18640 @brief checks the class invariants
18641
18642 This function asserts the class invariants. It needs to be called at the
18643 end of every constructor to make sure that created objects respect the
18644 invariant. Furthermore, it has to be called each time the type of a JSON
18645 value is changed, because the invariant expresses a relationship between
18646 @a m_type and @a m_value.
18647
18648 Furthermore, the parent relation is checked for arrays and objects: If
18649 @a check_parents true and the value is an array or object, then the
18650 container's elements must have the current value as parent.
18651
18652 @param[in] check_parents whether the parent relation should be checked.
18653 The value is true by default and should only be set to false
18654 during destruction of objects when the invariant does not
18655 need to hold.
18656 */
18657 void assert_invariant(bool check_parents = true) const noexcept
18658 {
18659 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18660 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18661 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18662 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18663
18665 JSON_TRY
18666 {
18667 // cppcheck-suppress assertWithSideEffect
18668 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json& j)
18669 {
18670 return j.m_parent == this;
18671 }));
18672 }
18673 JSON_CATCH(...) {} // LCOV_EXCL_LINE
18674#endif
18675 static_cast<void>(check_parents);
18676 }
18677
18679 {
18681 switch (m_type)
18682 {
18683 case value_t::array:
18684 {
18685 for (auto& element : *m_value.array)
18686 {
18687 element.m_parent = this;
18688 }
18689 break;
18690 }
18691
18692 case value_t::object:
18693 {
18694 for (auto& element : *m_value.object)
18695 {
18696 element.second.m_parent = this;
18697 }
18698 break;
18699 }
18700
18701 case value_t::null:
18702 case value_t::string:
18703 case value_t::boolean:
18704 case value_t::number_integer:
18706 case value_t::number_float:
18707 case value_t::binary:
18708 case value_t::discarded:
18709 default:
18710 break;
18711 }
18712#endif
18713 }
18714
18715 iterator set_parents(iterator it, typename iterator::difference_type count)
18716 {
18718 for (typename iterator::difference_type i = 0; i < count; ++i)
18719 {
18720 (it + i)->m_parent = this;
18721 }
18722#else
18723 static_cast<void>(count);
18724#endif
18725 return it;
18726 }
18727
18728 reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1))
18729 {
18731 if (old_capacity != std::size_t(-1))
18732 {
18733 // see https://github.com/nlohmann/json/issues/2838
18736 {
18737 // capacity has changed: update all parents
18738 set_parents();
18739 return j;
18740 }
18741 }
18742
18743 // ordered_json uses a vector internally, so pointers could have
18744 // been invalidated; see https://github.com/nlohmann/json/issues/2962
18745#ifdef JSON_HEDLEY_MSVC_VERSION
18746#pragma warning(push )
18747#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
18748#endif
18750 {
18751 set_parents();
18752 return j;
18753 }
18754#ifdef JSON_HEDLEY_MSVC_VERSION
18755#pragma warning( pop )
18756#endif
18757
18758 j.m_parent = this;
18759#else
18760 static_cast<void>(j);
18761 static_cast<void>(old_capacity);
18762#endif
18763 return j;
18764 }
18765
18766 public:
18767 //////////////////////////
18768 // JSON parser callback //
18769 //////////////////////////
18770
18771 /*!
18772 @brief parser event types
18773
18774 The parser callback distinguishes the following events:
18775 - `object_start`: the parser read `{` and started to process a JSON object
18776 - `key`: the parser read a key of a value in an object
18777 - `object_end`: the parser read `}` and finished processing a JSON object
18778 - `array_start`: the parser read `[` and started to process a JSON array
18779 - `array_end`: the parser read `]` and finished processing a JSON array
18780 - `value`: the parser finished reading a JSON value
18781
18782 @image html callback_events.png "Example when certain parse events are triggered"
18783
18784 @sa see @ref parser_callback_t for more information and examples
18785 */
18786 using parse_event_t = detail::parse_event_t;
18787
18788 /*!
18789 @brief per-element parser callback type
18790
18791 With a parser callback function, the result of parsing a JSON text can be
18792 influenced. When passed to @ref parse, it is called on certain events
18793 (passed as @ref parse_event_t via parameter @a event) with a set recursion
18794 depth @a depth and context JSON value @a parsed. The return value of the
18795 callback function is a boolean indicating whether the element that emitted
18796 the callback shall be kept or not.
18797
18798 We distinguish six scenarios (determined by the event type) in which the
18799 callback function can be called. The following table describes the values
18800 of the parameters @a depth, @a event, and @a parsed.
18801
18802 parameter @a event | description | parameter @a depth | parameter @a parsed
18803 ------------------ | ----------- | ------------------ | -------------------
18804 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
18805 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
18806 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
18807 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
18808 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
18809 parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
18810
18811 @image html callback_events.png "Example when certain parse events are triggered"
18812
18813 Discarding a value (i.e., returning `false`) has different effects
18814 depending on the context in which function was called:
18815
18816 - Discarded values in structured types are skipped. That is, the parser
18817 will behave as if the discarded value was never read.
18818 - In case a value outside a structured type is skipped, it is replaced
18819 with `null`. This case happens if the top-level element is skipped.
18820
18821 @param[in] depth the depth of the recursion during parsing
18822
18823 @param[in] event an event of type parse_event_t indicating the context in
18824 the callback function has been called
18825
18826 @param[in,out] parsed the current intermediate parse result; note that
18827 writing to this value has no effect for parse_event_t::key events
18828
18829 @return Whether the JSON value which called the function during parsing
18830 should be kept (`true`) or not (`false`). In the latter case, it is either
18831 skipped completely or replaced by an empty discarded object.
18832
18833 @sa see @ref parse for examples
18834
18835 @since version 1.0.0
18836 */
18838
18839 //////////////////
18840 // constructors //
18841 //////////////////
18842
18843 /// @name constructors and destructors
18844 /// Constructors of class @ref basic_json, copy/move constructor, copy
18845 /// assignment, static functions creating objects, and the destructor.
18846 /// @{
18847
18848 /*!
18849 @brief create an empty value with a given type
18850
18851 Create an empty JSON value with a given type. The value will be default
18852 initialized with an empty value which depends on the type:
18853
18854 Value type | initial value
18855 ----------- | -------------
18856 null | `null`
18857 boolean | `false`
18858 string | `""`
18859 number | `0`
18860 object | `{}`
18861 array | `[]`
18862 binary | empty array
18863
18864 @param[in] v the type of the value to create
18865
18866 @complexity Constant.
18867
18868 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18869 changes to any JSON value.
18870
18871 @liveexample{The following code shows the constructor for different @ref
18872 value_t values,basic_json__value_t}
18873
18874 @sa see @ref clear() -- restores the postcondition of this constructor
18875
18876 @since version 1.0.0
18877 */
18878 basic_json(const value_t v)
18879 : m_type(v), m_value(v)
18880 {
18882 }
18883
18884 /*!
18885 @brief create a null object
18886
18887 Create a `null` JSON value. It either takes a null pointer as parameter
18888 (explicitly creating `null`) or no parameter (implicitly creating `null`).
18889 The passed null pointer itself is not read -- it is only used to choose
18890 the right constructor.
18891
18892 @complexity Constant.
18893
18894 @exceptionsafety No-throw guarantee: this constructor never throws
18895 exceptions.
18896
18897 @liveexample{The following code shows the constructor with and without a
18898 null pointer parameter.,basic_json__nullptr_t}
18899
18900 @since version 1.0.0
18901 */
18902 basic_json(std::nullptr_t = nullptr) noexcept
18904 {
18906 }
18907
18908 /*!
18909 @brief create a JSON value
18910
18911 This is a "catch all" constructor for all compatible JSON types; that is,
18912 types for which a `to_json()` method exists. The constructor forwards the
18913 parameter @a val to that method (to `json_serializer<U>::to_json` method
18914 with `U = uncvref_t<CompatibleType>`, to be exact).
18915
18916 Template type @a CompatibleType includes, but is not limited to, the
18917 following types:
18918 - **arrays**: @ref array_t and all kinds of compatible containers such as
18919 `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
18920 `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
18921 `std::multiset`, and `std::unordered_multiset` with a `value_type` from
18922 which a @ref basic_json value can be constructed.
18923 - **objects**: @ref object_t and all kinds of compatible associative
18924 containers such as `std::map`, `std::unordered_map`, `std::multimap`,
18925 and `std::unordered_multimap` with a `key_type` compatible to
18926 @ref string_t and a `value_type` from which a @ref basic_json value can
18927 be constructed.
18928 - **strings**: @ref string_t, string literals, and all compatible string
18929 containers can be used.
18930 - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
18931 @ref number_float_t, and all convertible number types such as `int`,
18932 `size_t`, `int64_t`, `float` or `double` can be used.
18933 - **boolean**: @ref boolean_t / `bool` can be used.
18934 - **binary**: @ref binary_t / `std::vector<std::uint8_t>` may be used,
18935 unfortunately because string literals cannot be distinguished from binary
18936 character arrays by the C++ type system, all types compatible with `const
18937 char*` will be directed to the string constructor instead. This is both
18938 for backwards compatibility, and due to the fact that a binary type is not
18939 a standard JSON type.
18940
18941 See the examples below.
18942
18943 @tparam CompatibleType a type such that:
18944 - @a CompatibleType is not derived from `std::istream`,
18945 - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
18946 constructors),
18947 - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
18948 - @a CompatibleType is not a @ref basic_json nested type (e.g.,
18949 @ref json_pointer, @ref iterator, etc ...)
18950 - `json_serializer<U>` has a `to_json(basic_json_t&, CompatibleType&&)` method
18951
18952 @tparam U = `uncvref_t<CompatibleType>`
18953
18954 @param[in] val the value to be forwarded to the respective constructor
18955
18956 @complexity Usually linear in the size of the passed @a val, also
18957 depending on the implementation of the called `to_json()`
18958 method.
18959
18960 @exceptionsafety Depends on the called constructor. For types directly
18961 supported by the library (i.e., all types for which no `to_json()` function
18962 was provided), strong guarantee holds: if an exception is thrown, there are
18963 no changes to any JSON value.
18964
18965 @liveexample{The following code shows the constructor with several
18966 compatible types.,basic_json__CompatibleType}
18967
18968 @since version 2.1.0
18969 */
18970 template < typename CompatibleType,
18971 typename U = detail::uncvref_t<CompatibleType>,
18972 detail::enable_if_t <
18973 !detail::is_basic_json<U>::value&& detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
18974 basic_json(CompatibleType&& val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
18977 {
18979 set_parents();
18981 }
18982
18983 /*!
18984 @brief create a JSON value from an existing one
18985
18986 This is a constructor for existing @ref basic_json types.
18987 It does not hijack copy/move constructors, since the parameter has different
18988 template arguments than the current ones.
18989
18990 The constructor tries to convert the internal @ref m_value of the parameter.
18991
18992 @tparam BasicJsonType a type such that:
18993 - @a BasicJsonType is a @ref basic_json type.
18994 - @a BasicJsonType has different template arguments than @ref basic_json_t.
18995
18996 @param[in] val the @ref basic_json value to be converted.
18997
18998 @complexity Usually linear in the size of the passed @a val, also
18999 depending on the implementation of the called `to_json()`
19000 method.
19001
19002 @exceptionsafety Depends on the called constructor. For types directly
19003 supported by the library (i.e., all types for which no `to_json()` function
19004 was provided), strong guarantee holds: if an exception is thrown, there are
19005 no changes to any JSON value.
19006
19007 @since version 3.2.0
19008 */
19009 template < typename BasicJsonType,
19010 detail::enable_if_t <
19011 detail::is_basic_json<BasicJsonType>::value && !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
19012 basic_json(const BasicJsonType& val)
19013 {
19014 using other_boolean_t = typename BasicJsonType::boolean_t;
19018 using other_string_t = typename BasicJsonType::string_t;
19019 using other_object_t = typename BasicJsonType::object_t;
19020 using other_array_t = typename BasicJsonType::array_t;
19021 using other_binary_t = typename BasicJsonType::binary_t;
19022
19023 switch (val.type())
19024 {
19025 case value_t::boolean:
19027 break;
19028 case value_t::number_float:
19030 break;
19031 case value_t::number_integer:
19033 break;
19036 break;
19037 case value_t::string:
19038 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
19039 break;
19040 case value_t::object:
19041 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
19042 break;
19043 case value_t::array:
19044 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
19045 break;
19046 case value_t::binary:
19047 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
19048 break;
19049 case value_t::null:
19050 *this = nullptr;
19051 break;
19052 case value_t::discarded:
19054 break;
19055 default: // LCOV_EXCL_LINE
19056 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19057 }
19058 set_parents();
19060 }
19061
19062 /*!
19063 @brief create a container (array or object) from an initializer list
19064
19065 Creates a JSON value of type array or object from the passed initializer
19066 list @a init. In case @a type_deduction is `true` (default), the type of
19067 the JSON value to be created is deducted from the initializer list @a init
19068 according to the following rules:
19069
19070 1. If the list is empty, an empty JSON object value `{}` is created.
19071 2. If the list consists of pairs whose first element is a string, a JSON
19072 object value is created where the first elements of the pairs are
19073 treated as keys and the second elements are as values.
19074 3. In all other cases, an array is created.
19075
19076 The rules aim to create the best fit between a C++ initializer list and
19077 JSON values. The rationale is as follows:
19078
19079 1. The empty initializer list is written as `{}` which is exactly an empty
19080 JSON object.
19081 2. C++ has no way of describing mapped types other than to list a list of
19082 pairs. As JSON requires that keys must be of type string, rule 2 is the
19083 weakest constraint one can pose on initializer lists to interpret them
19084 as an object.
19085 3. In all other cases, the initializer list could not be interpreted as
19086 JSON object type, so interpreting it as JSON array type is safe.
19087
19088 With the rules described above, the following JSON values cannot be
19089 expressed by an initializer list:
19090
19091 - the empty array (`[]`): use @ref array(initializer_list_t)
19092 with an empty initializer list in this case
19093 - arrays whose elements satisfy rule 2: use @ref
19094 array(initializer_list_t) with the same initializer list
19095 in this case
19096
19097 @note When used without parentheses around an empty initializer list, @ref
19098 basic_json() is called instead of this function, yielding the JSON null
19099 value.
19100
19101 @param[in] init initializer list with JSON values
19102
19103 @param[in] type_deduction internal parameter; when set to `true`, the type
19104 of the JSON value is deducted from the initializer list @a init; when set
19105 to `false`, the type provided via @a manual_type is forced. This mode is
19106 used by the functions @ref array(initializer_list_t) and
19107 @ref object(initializer_list_t).
19108
19109 @param[in] manual_type internal parameter; when @a type_deduction is set
19110 to `false`, the created JSON value will use the provided type (only @ref
19111 value_t::array and @ref value_t::object are valid); when @a type_deduction
19112 is set to `true`, this parameter has no effect
19113
19114 @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
19115 `value_t::object`, but @a init contains an element which is not a pair
19116 whose first element is a string. In this case, the constructor could not
19117 create an object. If @a type_deduction would have be `true`, an array
19118 would have been created. See @ref object(initializer_list_t)
19119 for an example.
19120
19121 @complexity Linear in the size of the initializer list @a init.
19122
19123 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19124 changes to any JSON value.
19125
19126 @liveexample{The example below shows how JSON values are created from
19127 initializer lists.,basic_json__list_init_t}
19128
19129 @sa see @ref array(initializer_list_t) -- create a JSON array
19130 value from an initializer list
19131 @sa see @ref object(initializer_list_t) -- create a JSON object
19132 value from an initializer list
19133
19134 @since version 1.0.0
19135 */
19136 basic_json(initializer_list_t init,
19137 bool type_deduction = true,
19138 value_t manual_type = value_t::array)
19139 {
19140 // check if each element is an array with two elements whose first
19141 // element is a string
19142 bool is_an_object = std::all_of(init.begin(), init.end(),
19144 {
19145 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19146 });
19147
19148 // adjust type if type deduction is not wanted
19149 if (!type_deduction)
19150 {
19151 // if array is wanted, do not create an object though possible
19152 if (manual_type == value_t::array)
19153 {
19154 is_an_object = false;
19155 }
19156
19157 // if object is wanted but impossible, throw an exception
19159 {
19160 JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
19161 }
19162 }
19163
19164 if (is_an_object)
19165 {
19166 // the initializer list is a list of pairs -> create object
19169
19170 for (auto& element_ref : init)
19171 {
19175 std::move((*element.m_value.array)[1]));
19176 }
19177 }
19178 else
19179 {
19180 // the initializer list describes an array -> create array
19181 m_type = value_t::array;
19183 }
19184
19185 set_parents();
19187 }
19188
19189 /*!
19190 @brief explicitly create a binary array (without subtype)
19191
19192 Creates a JSON binary array value from a given binary container. Binary
19193 values are part of various binary formats, such as CBOR, MessagePack, and
19194 BSON. This constructor is used to create a value for serialization to those
19195 formats.
19196
19197 @note Note, this function exists because of the difficulty in correctly
19198 specifying the correct template overload in the standard value ctor, as both
19199 JSON arrays and JSON binary arrays are backed with some form of a
19200 `std::vector`. Because JSON binary arrays are a non-standard extension it
19201 was decided that it would be best to prevent automatic initialization of a
19202 binary array type, for backwards compatibility and so it does not happen on
19203 accident.
19204
19205 @param[in] init container containing bytes to use as binary type
19206
19207 @return JSON binary array value
19208
19209 @complexity Linear in the size of @a init.
19210
19211 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19212 changes to any JSON value.
19213
19214 @since version 3.8.0
19215 */
19217 static basic_json binary(const typename binary_t::container_type& init)
19218 {
19219 auto res = basic_json();
19221 res.m_value = init;
19222 return res;
19223 }
19224
19225 /*!
19226 @brief explicitly create a binary array (with subtype)
19227
19228 Creates a JSON binary array value from a given binary container. Binary
19229 values are part of various binary formats, such as CBOR, MessagePack, and
19230 BSON. This constructor is used to create a value for serialization to those
19231 formats.
19232
19233 @note Note, this function exists because of the difficulty in correctly
19234 specifying the correct template overload in the standard value ctor, as both
19235 JSON arrays and JSON binary arrays are backed with some form of a
19236 `std::vector`. Because JSON binary arrays are a non-standard extension it
19237 was decided that it would be best to prevent automatic initialization of a
19238 binary array type, for backwards compatibility and so it does not happen on
19239 accident.
19240
19241 @param[in] init container containing bytes to use as binary type
19242 @param[in] subtype subtype to use in MessagePack and BSON
19243
19244 @return JSON binary array value
19245
19246 @complexity Linear in the size of @a init.
19247
19248 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19249 changes to any JSON value.
19250
19251 @since version 3.8.0
19252 */
19254 static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
19255 {
19256 auto res = basic_json();
19259 return res;
19260 }
19261
19262 /// @copydoc binary(const typename binary_t::container_type&)
19264 static basic_json binary(typename binary_t::container_type&& init)
19265 {
19266 auto res = basic_json();
19268 res.m_value = std::move(init);
19269 return res;
19270 }
19271
19272 /// @copydoc binary(const typename binary_t::container_type&, typename binary_t::subtype_type)
19274 static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
19275 {
19276 auto res = basic_json();
19279 return res;
19280 }
19281
19282 /*!
19283 @brief explicitly create an array from an initializer list
19284
19285 Creates a JSON array value from a given initializer list. That is, given a
19286 list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
19287 initializer list is empty, the empty array `[]` is created.
19288
19289 @note This function is only needed to express two edge cases that cannot
19290 be realized with the initializer list constructor (@ref
19291 basic_json(initializer_list_t, bool, value_t)). These cases
19292 are:
19293 1. creating an array whose elements are all pairs whose first element is a
19294 string -- in this case, the initializer list constructor would create an
19295 object, taking the first elements as keys
19296 2. creating an empty array -- passing the empty initializer list to the
19297 initializer list constructor yields an empty object
19298
19299 @param[in] init initializer list with JSON values to create an array from
19300 (optional)
19301
19302 @return JSON array value
19303
19304 @complexity Linear in the size of @a init.
19305
19306 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19307 changes to any JSON value.
19308
19309 @liveexample{The following code shows an example for the `array`
19310 function.,array}
19311
19312 @sa see @ref basic_json(initializer_list_t, bool, value_t) --
19313 create a JSON value from an initializer list
19314 @sa see @ref object(initializer_list_t) -- create a JSON object
19315 value from an initializer list
19316
19317 @since version 1.0.0
19318 */
19320 static basic_json array(initializer_list_t init = {})
19321 {
19322 return basic_json(init, false, value_t::array);
19323 }
19324
19325 /*!
19326 @brief explicitly create an object from an initializer list
19327
19328 Creates a JSON object value from a given initializer list. The initializer
19329 lists elements must be pairs, and their first elements must be strings. If
19330 the initializer list is empty, the empty object `{}` is created.
19331
19332 @note This function is only added for symmetry reasons. In contrast to the
19333 related function @ref array(initializer_list_t), there are
19334 no cases which can only be expressed by this function. That is, any
19335 initializer list @a init can also be passed to the initializer list
19336 constructor @ref basic_json(initializer_list_t, bool, value_t).
19337
19338 @param[in] init initializer list to create an object from (optional)
19339
19340 @return JSON object value
19341
19342 @throw type_error.301 if @a init is not a list of pairs whose first
19343 elements are strings. In this case, no object can be created. When such a
19344 value is passed to @ref basic_json(initializer_list_t, bool, value_t),
19345 an array would have been created from the passed initializer list @a init.
19346 See example below.
19347
19348 @complexity Linear in the size of @a init.
19349
19350 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19351 changes to any JSON value.
19352
19353 @liveexample{The following code shows an example for the `object`
19354 function.,object}
19355
19356 @sa see @ref basic_json(initializer_list_t, bool, value_t) --
19357 create a JSON value from an initializer list
19358 @sa see @ref array(initializer_list_t) -- create a JSON array
19359 value from an initializer list
19360
19361 @since version 1.0.0
19362 */
19364 static basic_json object(initializer_list_t init = {})
19365 {
19366 return basic_json(init, false, value_t::object);
19367 }
19368
19369 /*!
19370 @brief construct an array with count copies of given value
19371
19372 Constructs a JSON array value by creating @a cnt copies of a passed value.
19373 In case @a cnt is `0`, an empty array is created.
19374
19375 @param[in] cnt the number of JSON copies of @a val to create
19376 @param[in] val the JSON value to copy
19377
19378 @post `std::distance(begin(),end()) == cnt` holds.
19379
19380 @complexity Linear in @a cnt.
19381
19382 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19383 changes to any JSON value.
19384
19385 @liveexample{The following code shows examples for the @ref
19386 basic_json(size_type\, const basic_json&)
19387 constructor.,basic_json__size_type_basic_json}
19388
19389 @since version 1.0.0
19390 */
19391 basic_json(size_type cnt, const basic_json& val)
19392 : m_type(value_t::array)
19393 {
19395 set_parents();
19397 }
19398
19399 /*!
19400 @brief construct a JSON container given an iterator range
19401
19402 Constructs the JSON value with the contents of the range `[first, last)`.
19403 The semantics depends on the different types a JSON value can have:
19404 - In case of a null type, invalid_iterator.206 is thrown.
19405 - In case of other primitive types (number, boolean, or string), @a first
19406 must be `begin()` and @a last must be `end()`. In this case, the value is
19407 copied. Otherwise, invalid_iterator.204 is thrown.
19408 - In case of structured types (array, object), the constructor behaves as
19409 similar versions for `std::vector` or `std::map`; that is, a JSON array
19410 or object is constructed from the values in the range.
19411
19412 @tparam InputIT an input iterator type (@ref iterator or @ref
19413 const_iterator)
19414
19415 @param[in] first begin of the range to copy from (included)
19416 @param[in] last end of the range to copy from (excluded)
19417
19418 @pre Iterators @a first and @a last must be initialized. **This
19419 precondition is enforced with an assertion (see warning).** If
19420 assertions are switched off, a violation of this precondition yields
19421 undefined behavior.
19422
19423 @pre Range `[first, last)` is valid. Usually, this precondition cannot be
19424 checked efficiently. Only certain edge cases are detected; see the
19425 description of the exceptions below. A violation of this precondition
19426 yields undefined behavior.
19427
19428 @warning A precondition is enforced with a runtime assertion that will
19429 result in calling `std::abort` if this precondition is not met.
19430 Assertions can be disabled by defining `NDEBUG` at compile time.
19431 See https://en.cppreference.com/w/cpp/error/assert for more
19432 information.
19433
19434 @throw invalid_iterator.201 if iterators @a first and @a last are not
19435 compatible (i.e., do not belong to the same JSON value). In this case,
19436 the range `[first, last)` is undefined.
19437 @throw invalid_iterator.204 if iterators @a first and @a last belong to a
19438 primitive type (number, boolean, or string), but @a first does not point
19439 to the first element any more. In this case, the range `[first, last)` is
19440 undefined. See example code below.
19441 @throw invalid_iterator.206 if iterators @a first and @a last belong to a
19442 null value. In this case, the range `[first, last)` is undefined.
19443
19444 @complexity Linear in distance between @a first and @a last.
19445
19446 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19447 changes to any JSON value.
19448
19449 @liveexample{The example below shows several ways to create JSON values by
19450 specifying a subrange with iterators.,basic_json__InputIt_InputIt}
19451
19452 @since version 1.0.0
19453 */
19454 template < class InputIT, typename std::enable_if <
19455 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19456 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19457 basic_json(InputIT first, InputIT last)
19458 {
19459 JSON_ASSERT(first.m_object != nullptr);
19460 JSON_ASSERT(last.m_object != nullptr);
19461
19462 // make sure iterator fits the current value
19464 {
19465 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
19466 }
19467
19468 // copy type from first iterator
19470
19471 // check if iterator range is complete for primitive values
19472 switch (m_type)
19473 {
19474 case value_t::boolean:
19475 case value_t::number_float:
19476 case value_t::number_integer:
19478 case value_t::string:
19479 {
19482 {
19483 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
19484 }
19485 break;
19486 }
19487
19488 case value_t::null:
19489 case value_t::object:
19490 case value_t::array:
19491 case value_t::binary:
19492 case value_t::discarded:
19493 default:
19494 break;
19495 }
19496
19497 switch (m_type)
19498 {
19499 case value_t::number_integer:
19500 {
19502 break;
19503 }
19504
19506 {
19508 break;
19509 }
19510
19511 case value_t::number_float:
19512 {
19514 break;
19515 }
19516
19517 case value_t::boolean:
19518 {
19520 break;
19521 }
19522
19523 case value_t::string:
19524 {
19526 break;
19527 }
19528
19529 case value_t::object:
19530 {
19533 break;
19534 }
19535
19536 case value_t::array:
19537 {
19540 break;
19541 }
19542
19543 case value_t::binary:
19544 {
19546 break;
19547 }
19548
19549 case value_t::null:
19550 case value_t::discarded:
19551 default:
19552 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
19553 }
19554
19555 set_parents();
19557 }
19558
19559
19560 ///////////////////////////////////////
19561 // other constructors and destructor //
19562 ///////////////////////////////////////
19563
19564 template<typename JsonRef,
19565 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
19566 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19567 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19568
19569 /*!
19570 @brief copy constructor
19571
19572 Creates a copy of a given JSON value.
19573
19574 @param[in] other the JSON value to copy
19575
19576 @post `*this == other`
19577
19578 @complexity Linear in the size of @a other.
19579
19580 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19581 changes to any JSON value.
19582
19583 @requirement This function helps `basic_json` satisfying the
19584 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19585 requirements:
19586 - The complexity is linear.
19587 - As postcondition, it holds: `other == basic_json(other)`.
19588
19589 @liveexample{The following code shows an example for the copy
19590 constructor.,basic_json__basic_json}
19591
19592 @since version 1.0.0
19593 */
19594 basic_json(const basic_json& other)
19596 {
19597 // check of passed value is valid
19599
19600 switch (m_type)
19601 {
19602 case value_t::object:
19603 {
19605 break;
19606 }
19607
19608 case value_t::array:
19609 {
19611 break;
19612 }
19613
19614 case value_t::string:
19615 {
19617 break;
19618 }
19619
19620 case value_t::boolean:
19621 {
19623 break;
19624 }
19625
19626 case value_t::number_integer:
19627 {
19629 break;
19630 }
19631
19633 {
19635 break;
19636 }
19637
19638 case value_t::number_float:
19639 {
19641 break;
19642 }
19643
19644 case value_t::binary:
19645 {
19647 break;
19648 }
19649
19650 case value_t::null:
19651 case value_t::discarded:
19652 default:
19653 break;
19654 }
19655
19656 set_parents();
19658 }
19659
19660 /*!
19661 @brief move constructor
19662
19663 Move constructor. Constructs a JSON value with the contents of the given
19664 value @a other using move semantics. It "steals" the resources from @a
19665 other and leaves it as JSON null value.
19666
19667 @param[in,out] other value to move to this object
19668
19669 @post `*this` has the same value as @a other before the call.
19670 @post @a other is a JSON null value.
19671
19672 @complexity Constant.
19673
19674 @exceptionsafety No-throw guarantee: this constructor never throws
19675 exceptions.
19676
19677 @requirement This function helps `basic_json` satisfying the
19678 [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
19679 requirements.
19680
19681 @liveexample{The code below shows the move constructor explicitly called
19682 via std::move.,basic_json__moveconstructor}
19683
19684 @since version 1.0.0
19685 */
19686 basic_json(basic_json&& other) noexcept
19687 : m_type(std::move(other.m_type)),
19689 {
19690 // check that passed value is valid
19691 other.assert_invariant(false);
19692
19693 // invalidate payload
19695 other.m_value = {};
19696
19697 set_parents();
19699 }
19700
19701 /*!
19702 @brief copy assignment
19703
19704 Copy assignment operator. Copies a JSON value via the "copy and swap"
19705 strategy: It is expressed in terms of the copy constructor, destructor,
19706 and the `swap()` member function.
19707
19708 @param[in] other value to copy from
19709
19710 @complexity Linear.
19711
19712 @requirement This function helps `basic_json` satisfying the
19713 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19714 requirements:
19715 - The complexity is linear.
19716
19717 @liveexample{The code below shows and example for the copy assignment. It
19718 creates a copy of value `a` which is then swapped with `b`. Finally\, the
19719 copy of `a` (which is the null value after the swap) is
19720 destroyed.,basic_json__copyassignment}
19721
19722 @since version 1.0.0
19723 */
19724 basic_json& operator=(basic_json other) noexcept (
19725 std::is_nothrow_move_constructible<value_t>::value&&
19726 std::is_nothrow_move_assignable<value_t>::value&&
19727 std::is_nothrow_move_constructible<json_value>::value&&
19728 std::is_nothrow_move_assignable<json_value>::value
19729 )
19730 {
19731 // check that passed value is valid
19733
19734 using std::swap;
19737
19738 set_parents();
19740 return *this;
19741 }
19742
19743 /*!
19744 @brief destructor
19745
19746 Destroys the JSON value and frees all allocated memory.
19747
19748 @complexity Linear.
19749
19750 @requirement This function helps `basic_json` satisfying the
19751 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19752 requirements:
19753 - The complexity is linear.
19754 - All stored elements are destroyed and all memory is freed.
19755
19756 @since version 1.0.0
19757 */
19758 ~basic_json() noexcept
19759 {
19760 assert_invariant(false);
19762 }
19763
19764 /// @}
19765
19766 public:
19767 ///////////////////////
19768 // object inspection //
19769 ///////////////////////
19770
19771 /// @name object inspection
19772 /// Functions to inspect the type of a JSON value.
19773 /// @{
19774
19775 /*!
19776 @brief serialization
19777
19778 Serialization function for JSON values. The function tries to mimic
19779 Python's `json.dumps()` function, and currently supports its @a indent
19780 and @a ensure_ascii parameters.
19781
19782 @param[in] indent If indent is nonnegative, then array elements and object
19783 members will be pretty-printed with that indent level. An indent level of
19784 `0` will only insert newlines. `-1` (the default) selects the most compact
19785 representation.
19786 @param[in] indent_char The character to use for indentation if @a indent is
19787 greater than `0`. The default is ` ` (space).
19788 @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
19789 in the output are escaped with `\uXXXX` sequences, and the result consists
19790 of ASCII characters only.
19791 @param[in] error_handler how to react on decoding errors; there are three
19792 possible values: `strict` (throws and exception in case a decoding error
19793 occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
19794 and `ignore` (ignore invalid UTF-8 sequences during serialization; all
19795 bytes are copied to the output unchanged).
19796
19797 @return string containing the serialization of the JSON value
19798
19799 @throw type_error.316 if a string stored inside the JSON value is not
19800 UTF-8 encoded and @a error_handler is set to strict
19801
19802 @note Binary values are serialized as object containing two keys:
19803 - "bytes": an array of bytes as integers
19804 - "subtype": the subtype as integer or "null" if the binary has no subtype
19805
19806 @complexity Linear.
19807
19808 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19809 changes in the JSON value.
19810
19811 @liveexample{The following example shows the effect of different @a indent\,
19812 @a indent_char\, and @a ensure_ascii parameters to the result of the
19813 serialization.,dump}
19814
19815 @see https://docs.python.org/2/library/json.html#json.dump
19816
19817 @since version 1.0.0; indentation character @a indent_char, option
19818 @a ensure_ascii and exceptions added in version 3.0.0; error
19819 handlers added in version 3.4.0; serialization of binary values added
19820 in version 3.8.0.
19821 */
19822 string_t dump(const int indent = -1,
19823 const char indent_char = ' ',
19824 const bool ensure_ascii = false,
19825 const error_handler_t error_handler = error_handler_t::strict) const
19826 {
19829
19830 if (indent >= 0)
19831 {
19832 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19833 }
19834 else
19835 {
19836 s.dump(*this, false, ensure_ascii, 0);
19837 }
19838
19839 return result;
19840 }
19841
19842 /*!
19843 @brief return the type of the JSON value (explicit)
19844
19845 Return the type of the JSON value as a value from the @ref value_t
19846 enumeration.
19847
19848 @return the type of the JSON value
19849 Value type | return value
19850 ------------------------- | -------------------------
19851 null | value_t::null
19852 boolean | value_t::boolean
19853 string | value_t::string
19854 number (integer) | value_t::number_integer
19855 number (unsigned integer) | value_t::number_unsigned
19856 number (floating-point) | value_t::number_float
19857 object | value_t::object
19858 array | value_t::array
19859 binary | value_t::binary
19860 discarded | value_t::discarded
19861
19862 @complexity Constant.
19863
19864 @exceptionsafety No-throw guarantee: this member function never throws
19865 exceptions.
19866
19867 @liveexample{The following code exemplifies `type()` for all JSON
19868 types.,type}
19869
19870 @sa see @ref operator value_t() -- return the type of the JSON value (implicit)
19871 @sa see @ref type_name() -- return the type as string
19872
19873 @since version 1.0.0
19874 */
19875 constexpr value_t type() const noexcept
19876 {
19877 return m_type;
19878 }
19879
19880 /*!
19881 @brief return whether type is primitive
19882
19883 This function returns true if and only if the JSON type is primitive
19884 (string, number, boolean, or null).
19885
19886 @return `true` if type is primitive (string, number, boolean, or null),
19887 `false` otherwise.
19888
19889 @complexity Constant.
19890
19891 @exceptionsafety No-throw guarantee: this member function never throws
19892 exceptions.
19893
19894 @liveexample{The following code exemplifies `is_primitive()` for all JSON
19895 types.,is_primitive}
19896
19897 @sa see @ref is_structured() -- returns whether JSON value is structured
19898 @sa see @ref is_null() -- returns whether JSON value is `null`
19899 @sa see @ref is_string() -- returns whether JSON value is a string
19900 @sa see @ref is_boolean() -- returns whether JSON value is a boolean
19901 @sa see @ref is_number() -- returns whether JSON value is a number
19902 @sa see @ref is_binary() -- returns whether JSON value is a binary array
19903
19904 @since version 1.0.0
19905 */
19906 constexpr bool is_primitive() const noexcept
19907 {
19908 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
19909 }
19910
19911 /*!
19912 @brief return whether type is structured
19913
19914 This function returns true if and only if the JSON type is structured
19915 (array or object).
19916
19917 @return `true` if type is structured (array or object), `false` otherwise.
19918
19919 @complexity Constant.
19920
19921 @exceptionsafety No-throw guarantee: this member function never throws
19922 exceptions.
19923
19924 @liveexample{The following code exemplifies `is_structured()` for all JSON
19925 types.,is_structured}
19926
19927 @sa see @ref is_primitive() -- returns whether value is primitive
19928 @sa see @ref is_array() -- returns whether value is an array
19929 @sa see @ref is_object() -- returns whether value is an object
19930
19931 @since version 1.0.0
19932 */
19933 constexpr bool is_structured() const noexcept
19934 {
19935 return is_array() || is_object();
19936 }
19937
19938 /*!
19939 @brief return whether value is null
19940
19941 This function returns true if and only if the JSON value is null.
19942
19943 @return `true` if type is null, `false` otherwise.
19944
19945 @complexity Constant.
19946
19947 @exceptionsafety No-throw guarantee: this member function never throws
19948 exceptions.
19949
19950 @liveexample{The following code exemplifies `is_null()` for all JSON
19951 types.,is_null}
19952
19953 @since version 1.0.0
19954 */
19955 constexpr bool is_null() const noexcept
19956 {
19957 return m_type == value_t::null;
19958 }
19959
19960 /*!
19961 @brief return whether value is a boolean
19962
19963 This function returns true if and only if the JSON value is a boolean.
19964
19965 @return `true` if type is boolean, `false` otherwise.
19966
19967 @complexity Constant.
19968
19969 @exceptionsafety No-throw guarantee: this member function never throws
19970 exceptions.
19971
19972 @liveexample{The following code exemplifies `is_boolean()` for all JSON
19973 types.,is_boolean}
19974
19975 @since version 1.0.0
19976 */
19977 constexpr bool is_boolean() const noexcept
19978 {
19979 return m_type == value_t::boolean;
19980 }
19981
19982 /*!
19983 @brief return whether value is a number
19984
19985 This function returns true if and only if the JSON value is a number. This
19986 includes both integer (signed and unsigned) and floating-point values.
19987
19988 @return `true` if type is number (regardless whether integer, unsigned
19989 integer or floating-type), `false` otherwise.
19990
19991 @complexity Constant.
19992
19993 @exceptionsafety No-throw guarantee: this member function never throws
19994 exceptions.
19995
19996 @liveexample{The following code exemplifies `is_number()` for all JSON
19997 types.,is_number}
19998
19999 @sa see @ref is_number_integer() -- check if value is an integer or unsigned
20000 integer number
20001 @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20002 number
20003 @sa see @ref is_number_float() -- check if value is a floating-point number
20004
20005 @since version 1.0.0
20006 */
20007 constexpr bool is_number() const noexcept
20008 {
20009 return is_number_integer() || is_number_float();
20010 }
20011
20012 /*!
20013 @brief return whether value is an integer number
20014
20015 This function returns true if and only if the JSON value is a signed or
20016 unsigned integer number. This excludes floating-point values.
20017
20018 @return `true` if type is an integer or unsigned integer number, `false`
20019 otherwise.
20020
20021 @complexity Constant.
20022
20023 @exceptionsafety No-throw guarantee: this member function never throws
20024 exceptions.
20025
20026 @liveexample{The following code exemplifies `is_number_integer()` for all
20027 JSON types.,is_number_integer}
20028
20029 @sa see @ref is_number() -- check if value is a number
20030 @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20031 number
20032 @sa see @ref is_number_float() -- check if value is a floating-point number
20033
20034 @since version 1.0.0
20035 */
20036 constexpr bool is_number_integer() const noexcept
20037 {
20038 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
20039 }
20040
20041 /*!
20042 @brief return whether value is an unsigned integer number
20043
20044 This function returns true if and only if the JSON value is an unsigned
20045 integer number. This excludes floating-point and signed integer values.
20046
20047 @return `true` if type is an unsigned integer number, `false` otherwise.
20048
20049 @complexity Constant.
20050
20051 @exceptionsafety No-throw guarantee: this member function never throws
20052 exceptions.
20053
20054 @liveexample{The following code exemplifies `is_number_unsigned()` for all
20055 JSON types.,is_number_unsigned}
20056
20057 @sa see @ref is_number() -- check if value is a number
20058 @sa see @ref is_number_integer() -- check if value is an integer or unsigned
20059 integer number
20060 @sa see @ref is_number_float() -- check if value is a floating-point number
20061
20062 @since version 2.0.0
20063 */
20064 constexpr bool is_number_unsigned() const noexcept
20065 {
20066 return m_type == value_t::number_unsigned;
20067 }
20068
20069 /*!
20070 @brief return whether value is a floating-point number
20071
20072 This function returns true if and only if the JSON value is a
20073 floating-point number. This excludes signed and unsigned integer values.
20074
20075 @return `true` if type is a floating-point number, `false` otherwise.
20076
20077 @complexity Constant.
20078
20079 @exceptionsafety No-throw guarantee: this member function never throws
20080 exceptions.
20081
20082 @liveexample{The following code exemplifies `is_number_float()` for all
20083 JSON types.,is_number_float}
20084
20085 @sa see @ref is_number() -- check if value is number
20086 @sa see @ref is_number_integer() -- check if value is an integer number
20087 @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20088 number
20089
20090 @since version 1.0.0
20091 */
20092 constexpr bool is_number_float() const noexcept
20093 {
20094 return m_type == value_t::number_float;
20095 }
20096
20097 /*!
20098 @brief return whether value is an object
20099
20100 This function returns true if and only if the JSON value is an object.
20101
20102 @return `true` if type is object, `false` otherwise.
20103
20104 @complexity Constant.
20105
20106 @exceptionsafety No-throw guarantee: this member function never throws
20107 exceptions.
20108
20109 @liveexample{The following code exemplifies `is_object()` for all JSON
20110 types.,is_object}
20111
20112 @since version 1.0.0
20113 */
20114 constexpr bool is_object() const noexcept
20115 {
20116 return m_type == value_t::object;
20117 }
20118
20119 /*!
20120 @brief return whether value is an array
20121
20122 This function returns true if and only if the JSON value is an array.
20123
20124 @return `true` if type is array, `false` otherwise.
20125
20126 @complexity Constant.
20127
20128 @exceptionsafety No-throw guarantee: this member function never throws
20129 exceptions.
20130
20131 @liveexample{The following code exemplifies `is_array()` for all JSON
20132 types.,is_array}
20133
20134 @since version 1.0.0
20135 */
20136 constexpr bool is_array() const noexcept
20137 {
20138 return m_type == value_t::array;
20139 }
20140
20141 /*!
20142 @brief return whether value is a string
20143
20144 This function returns true if and only if the JSON value is a string.
20145
20146 @return `true` if type is string, `false` otherwise.
20147
20148 @complexity Constant.
20149
20150 @exceptionsafety No-throw guarantee: this member function never throws
20151 exceptions.
20152
20153 @liveexample{The following code exemplifies `is_string()` for all JSON
20154 types.,is_string}
20155
20156 @since version 1.0.0
20157 */
20158 constexpr bool is_string() const noexcept
20159 {
20160 return m_type == value_t::string;
20161 }
20162
20163 /*!
20164 @brief return whether value is a binary array
20165
20166 This function returns true if and only if the JSON value is a binary array.
20167
20168 @return `true` if type is binary array, `false` otherwise.
20169
20170 @complexity Constant.
20171
20172 @exceptionsafety No-throw guarantee: this member function never throws
20173 exceptions.
20174
20175 @liveexample{The following code exemplifies `is_binary()` for all JSON
20176 types.,is_binary}
20177
20178 @since version 3.8.0
20179 */
20180 constexpr bool is_binary() const noexcept
20181 {
20182 return m_type == value_t::binary;
20183 }
20184
20185 /*!
20186 @brief return whether value is discarded
20187
20188 This function returns true if and only if the JSON value was discarded
20189 during parsing with a callback function (see @ref parser_callback_t).
20190
20191 @note This function will always be `false` for JSON values after parsing.
20192 That is, discarded values can only occur during parsing, but will be
20193 removed when inside a structured value or replaced by null in other cases.
20194
20195 @return `true` if type is discarded, `false` otherwise.
20196
20197 @complexity Constant.
20198
20199 @exceptionsafety No-throw guarantee: this member function never throws
20200 exceptions.
20201
20202 @liveexample{The following code exemplifies `is_discarded()` for all JSON
20203 types.,is_discarded}
20204
20205 @since version 1.0.0
20206 */
20207 constexpr bool is_discarded() const noexcept
20208 {
20209 return m_type == value_t::discarded;
20210 }
20211
20212 /*!
20213 @brief return the type of the JSON value (implicit)
20214
20215 Implicitly return the type of the JSON value as a value from the @ref
20216 value_t enumeration.
20217
20218 @return the type of the JSON value
20219
20220 @complexity Constant.
20221
20222 @exceptionsafety No-throw guarantee: this member function never throws
20223 exceptions.
20224
20225 @liveexample{The following code exemplifies the @ref value_t operator for
20226 all JSON types.,operator__value_t}
20227
20228 @sa see @ref type() -- return the type of the JSON value (explicit)
20229 @sa see @ref type_name() -- return the type as string
20230
20231 @since version 1.0.0
20232 */
20233 constexpr operator value_t() const noexcept
20234 {
20235 return m_type;
20236 }
20237
20238 /// @}
20239
20240 private:
20241 //////////////////
20242 // value access //
20243 //////////////////
20244
20245 /// get a boolean (explicit)
20246 boolean_t get_impl(boolean_t* /*unused*/) const
20247 {
20249 {
20250 return m_value.boolean;
20251 }
20252
20253 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
20254 }
20255
20256 /// get a pointer to the value (object)
20257 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20258 {
20259 return is_object() ? m_value.object : nullptr;
20260 }
20261
20262 /// get a pointer to the value (object)
20263 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20264 {
20265 return is_object() ? m_value.object : nullptr;
20266 }
20267
20268 /// get a pointer to the value (array)
20269 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20270 {
20271 return is_array() ? m_value.array : nullptr;
20272 }
20273
20274 /// get a pointer to the value (array)
20275 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20276 {
20277 return is_array() ? m_value.array : nullptr;
20278 }
20279
20280 /// get a pointer to the value (string)
20281 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20282 {
20283 return is_string() ? m_value.string : nullptr;
20284 }
20285
20286 /// get a pointer to the value (string)
20287 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20288 {
20289 return is_string() ? m_value.string : nullptr;
20290 }
20291
20292 /// get a pointer to the value (boolean)
20293 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20294 {
20295 return is_boolean() ? &m_value.boolean : nullptr;
20296 }
20297
20298 /// get a pointer to the value (boolean)
20299 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20300 {
20301 return is_boolean() ? &m_value.boolean : nullptr;
20302 }
20303
20304 /// get a pointer to the value (integer number)
20305 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
20306 {
20307 return is_number_integer() ? &m_value.number_integer : nullptr;
20308 }
20309
20310 /// get a pointer to the value (integer number)
20311 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20312 {
20313 return is_number_integer() ? &m_value.number_integer : nullptr;
20314 }
20315
20316 /// get a pointer to the value (unsigned number)
20317 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
20318 {
20319 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20320 }
20321
20322 /// get a pointer to the value (unsigned number)
20323 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20324 {
20325 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20326 }
20327
20328 /// get a pointer to the value (floating-point number)
20329 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
20330 {
20331 return is_number_float() ? &m_value.number_float : nullptr;
20332 }
20333
20334 /// get a pointer to the value (floating-point number)
20335 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20336 {
20337 return is_number_float() ? &m_value.number_float : nullptr;
20338 }
20339
20340 /// get a pointer to the value (binary)
20341 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20342 {
20343 return is_binary() ? m_value.binary : nullptr;
20344 }
20345
20346 /// get a pointer to the value (binary)
20347 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20348 {
20349 return is_binary() ? m_value.binary : nullptr;
20350 }
20351
20352 /*!
20353 @brief helper function to implement get_ref()
20354
20355 This function helps to implement get_ref() without code duplication for
20356 const and non-const overloads
20357
20358 @tparam ThisType will be deduced as `basic_json` or `const basic_json`
20359
20360 @throw type_error.303 if ReferenceType does not match underlying value
20361 type of the current JSON
20362 */
20363 template<typename ReferenceType, typename ThisType>
20364 static ReferenceType get_ref_impl(ThisType& obj)
20365 {
20366 // delegate the call to get_ptr<>()
20367 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20368
20369 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20370 {
20371 return *ptr;
20372 }
20373
20374 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
20375 }
20376
20377 public:
20378 /// @name value access
20379 /// Direct access to the stored value of a JSON value.
20380 /// @{
20381
20382 /*!
20383 @brief get a pointer value (implicit)
20384
20385 Implicit pointer access to the internally stored JSON value. No copies are
20386 made.
20387
20388 @warning Writing data to the pointee of the result yields an undefined
20389 state.
20390
20391 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
20392 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
20393 @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
20394 assertion.
20395
20396 @return pointer to the internally stored JSON value if the requested
20397 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
20398
20399 @complexity Constant.
20400
20401 @liveexample{The example below shows how pointers to internal values of a
20402 JSON value can be requested. Note that no type conversions are made and a
20403 `nullptr` is returned if the value and the requested pointer type does not
20404 match.,get_ptr}
20405
20406 @since version 1.0.0
20407 */
20408 template<typename PointerType, typename std::enable_if<
20409 std::is_pointer<PointerType>::value, int>::type = 0>
20410 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20411 {
20412 // delegate the call to get_impl_ptr<>()
20413 return get_impl_ptr(static_cast<PointerType>(nullptr));
20414 }
20415
20416 /*!
20417 @brief get a pointer value (implicit)
20418 @copydoc get_ptr()
20419 */
20420 template < typename PointerType, typename std::enable_if <
20421 std::is_pointer<PointerType>::value&&
20422 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20423 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20424 {
20425 // delegate the call to get_impl_ptr<>() const
20426 return get_impl_ptr(static_cast<PointerType>(nullptr));
20427 }
20428
20429 private:
20430 /*!
20431 @brief get a value (explicit)
20432
20433 Explicit type conversion between the JSON value and a compatible value
20434 which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
20435 and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
20436 The value is converted by calling the @ref json_serializer<ValueType>
20437 `from_json()` method.
20438
20439 The function is equivalent to executing
20440 @code {.cpp}
20441 ValueType ret;
20442 JSONSerializer<ValueType>::from_json(*this, ret);
20443 return ret;
20444 @endcode
20445
20446 This overloads is chosen if:
20447 - @a ValueType is not @ref basic_json,
20448 - @ref json_serializer<ValueType> has a `from_json()` method of the form
20449 `void from_json(const basic_json&, ValueType&)`, and
20450 - @ref json_serializer<ValueType> does not have a `from_json()` method of
20451 the form `ValueType from_json(const basic_json&)`
20452
20453 @tparam ValueType the returned value type
20454
20455 @return copy of the JSON value, converted to @a ValueType
20456
20457 @throw what @ref json_serializer<ValueType> `from_json()` method throws
20458
20459 @liveexample{The example below shows several conversions from JSON values
20460 to other types. There a few things to note: (1) Floating-point numbers can
20461 be converted to integers\, (2) A JSON array can be converted to a standard
20462 `std::vector<short>`\, (3) A JSON object can be converted to C++
20463 associative containers such as `std::unordered_map<std::string\,
20464 json>`.,get__ValueType_const}
20465
20466 @since version 2.1.0
20467 */
20468 template < typename ValueType,
20469 detail::enable_if_t <
20470 detail::is_default_constructible<ValueType>::value&&
20471 detail::has_from_json<basic_json_t, ValueType>::value,
20472 int > = 0 >
20473 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20474 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20475 {
20476 ValueType ret{};
20478 return ret;
20479 }
20480
20481 /*!
20482 @brief get a value (explicit); special case
20483
20484 Explicit type conversion between the JSON value and a compatible value
20485 which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
20486 and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
20487 The value is converted by calling the @ref json_serializer<ValueType>
20488 `from_json()` method.
20489
20490 The function is equivalent to executing
20491 @code {.cpp}
20492 return JSONSerializer<ValueType>::from_json(*this);
20493 @endcode
20494
20495 This overloads is chosen if:
20496 - @a ValueType is not @ref basic_json and
20497 - @ref json_serializer<ValueType> has a `from_json()` method of the form
20498 `ValueType from_json(const basic_json&)`
20499
20500 @note If @ref json_serializer<ValueType> has both overloads of
20501 `from_json()`, this one is chosen.
20502
20503 @tparam ValueType the returned value type
20504
20505 @return copy of the JSON value, converted to @a ValueType
20506
20507 @throw what @ref json_serializer<ValueType> `from_json()` method throws
20508
20509 @since version 2.1.0
20510 */
20511 template < typename ValueType,
20512 detail::enable_if_t <
20513 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
20514 int > = 0 >
20515 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20516 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20517 {
20518 return JSONSerializer<ValueType>::from_json(*this);
20519 }
20520
20521 /*!
20522 @brief get special-case overload
20523
20524 This overloads converts the current @ref basic_json in a different
20525 @ref basic_json type
20526
20527 @tparam BasicJsonType == @ref basic_json
20528
20529 @return a copy of *this, converted into @a BasicJsonType
20530
20531 @complexity Depending on the implementation of the called `from_json()`
20532 method.
20533
20534 @since version 3.2.0
20535 */
20536 template < typename BasicJsonType,
20537 detail::enable_if_t <
20538 detail::is_basic_json<BasicJsonType>::value,
20539 int > = 0 >
20540 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20541 {
20542 return *this;
20543 }
20544
20545 /*!
20546 @brief get special-case overload
20547
20548 This overloads avoids a lot of template boilerplate, it can be seen as the
20549 identity method
20550
20551 @tparam BasicJsonType == @ref basic_json
20552
20553 @return a copy of *this
20554
20555 @complexity Constant.
20556
20557 @since version 2.1.0
20558 */
20559 template<typename BasicJsonType,
20560 detail::enable_if_t<
20561 std::is_same<BasicJsonType, basic_json_t>::value,
20562 int> = 0>
20563 basic_json get_impl(detail::priority_tag<3> /*unused*/) const
20564 {
20565 return *this;
20566 }
20567
20568 /*!
20569 @brief get a pointer value (explicit)
20570 @copydoc get()
20571 */
20572 template<typename PointerType,
20573 detail::enable_if_t<
20574 std::is_pointer<PointerType>::value,
20575 int> = 0>
20576 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20577 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20578 {
20579 // delegate the call to get_ptr
20580 return get_ptr<PointerType>();
20581 }
20582
20583 public:
20584 /*!
20585 @brief get a (pointer) value (explicit)
20586
20587 Performs explicit type conversion between the JSON value and a compatible value if required.
20588
20589 - If the requested type is a pointer to the internally stored JSON value that pointer is returned.
20590 No copies are made.
20591
20592 - If the requested type is the current @ref basic_json, or a different @ref basic_json convertible
20593 from the current @ref basic_json.
20594
20595 - Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`
20596 method.
20597
20598 @tparam ValueTypeCV the provided value type
20599 @tparam ValueType the returned value type
20600
20601 @return copy of the JSON value, converted to @tparam ValueType if necessary
20602
20603 @throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
20604
20605 @since version 2.1.0
20606 */
20607 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20608#if defined(JSON_HAS_CPP_14)
20609 constexpr
20610#endif
20611 auto get() const noexcept(
20612 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20613 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20614 {
20615 // we cannot static_assert on ValueTypeCV being non-const, because
20616 // there is support for get<const basic_json_t>(), which is why we
20617 // still need the uncvref
20618 static_assert(!std::is_reference<ValueTypeCV>::value,
20619 "get() cannot be used with reference types, you might want to use get_ref()");
20620 return get_impl<ValueType>(detail::priority_tag<4> {});
20621 }
20622
20623 /*!
20624 @brief get a pointer value (explicit)
20625
20626 Explicit pointer access to the internally stored JSON value. No copies are
20627 made.
20628
20629 @warning The pointer becomes invalid if the underlying JSON object
20630 changes.
20631
20632 @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
20633 object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
20634 @ref number_unsigned_t, or @ref number_float_t.
20635
20636 @return pointer to the internally stored JSON value if the requested
20637 pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
20638
20639 @complexity Constant.
20640
20641 @liveexample{The example below shows how pointers to internal values of a
20642 JSON value can be requested. Note that no type conversions are made and a
20643 `nullptr` is returned if the value and the requested pointer type does not
20644 match.,get__PointerType}
20645
20646 @sa see @ref get_ptr() for explicit pointer-member access
20647
20648 @since version 1.0.0
20649 */
20650 template<typename PointerType, typename std::enable_if<
20651 std::is_pointer<PointerType>::value, int>::type = 0>
20652 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20653 {
20654 // delegate the call to get_ptr
20655 return get_ptr<PointerType>();
20656 }
20657
20658 /*!
20659 @brief get a value (explicit)
20660
20661 Explicit type conversion between the JSON value and a compatible value.
20662 The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
20663 `from_json()` method.
20664
20665 The function is equivalent to executing
20666 @code {.cpp}
20667 ValueType v;
20668 JSONSerializer<ValueType>::from_json(*this, v);
20669 @endcode
20670
20671 This overloads is chosen if:
20672 - @a ValueType is not @ref basic_json,
20673 - @ref json_serializer<ValueType> has a `from_json()` method of the form
20674 `void from_json(const basic_json&, ValueType&)`, and
20675
20676 @tparam ValueType the input parameter type.
20677
20678 @return the input parameter, allowing chaining calls.
20679
20680 @throw what @ref json_serializer<ValueType> `from_json()` method throws
20681
20682 @liveexample{The example below shows several conversions from JSON values
20683 to other types. There a few things to note: (1) Floating-point numbers can
20684 be converted to integers\, (2) A JSON array can be converted to a standard
20685 `std::vector<short>`\, (3) A JSON object can be converted to C++
20686 associative containers such as `std::unordered_map<std::string\,
20687 json>`.,get_to}
20688
20689 @since version 3.3.0
20690 */
20691 template < typename ValueType,
20692 detail::enable_if_t <
20693 !detail::is_basic_json<ValueType>::value&&
20694 detail::has_from_json<basic_json_t, ValueType>::value,
20695 int > = 0 >
20696 ValueType& get_to(ValueType& v) const noexcept(noexcept(
20697 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20698 {
20700 return v;
20701 }
20702
20703 // specialization to allow to call get_to with a basic_json value
20704 // see https://github.com/nlohmann/json/issues/2175
20705 template<typename ValueType,
20706 detail::enable_if_t <
20707 detail::is_basic_json<ValueType>::value,
20708 int> = 0>
20709 ValueType& get_to(ValueType& v) const
20710 {
20711 v = *this;
20712 return v;
20713 }
20714
20715 template <
20716 typename T, std::size_t N,
20717 typename Array = T(&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20718 detail::enable_if_t <
20719 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
20720 Array get_to(T(&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20721 noexcept(noexcept(JSONSerializer<Array>::from_json(
20722 std::declval<const basic_json_t&>(), v)))
20723 {
20724 JSONSerializer<Array>::from_json(*this, v);
20725 return v;
20726 }
20727
20728 /*!
20729 @brief get a reference value (implicit)
20730
20731 Implicit reference access to the internally stored JSON value. No copies
20732 are made.
20733
20734 @warning Writing data to the referee of the result yields an undefined
20735 state.
20736
20737 @tparam ReferenceType reference type; must be a reference to @ref array_t,
20738 @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
20739 @ref number_float_t. Enforced by static assertion.
20740
20741 @return reference to the internally stored JSON value if the requested
20742 reference type @a ReferenceType fits to the JSON value; throws
20743 type_error.303 otherwise
20744
20745 @throw type_error.303 in case passed type @a ReferenceType is incompatible
20746 with the stored JSON value; see example below
20747
20748 @complexity Constant.
20749
20750 @liveexample{The example shows several calls to `get_ref()`.,get_ref}
20751
20752 @since version 1.1.0
20753 */
20754 template<typename ReferenceType, typename std::enable_if<
20755 std::is_reference<ReferenceType>::value, int>::type = 0>
20756 ReferenceType get_ref()
20757 {
20758 // delegate call to get_ref_impl
20759 return get_ref_impl<ReferenceType>(*this);
20760 }
20761
20762 /*!
20763 @brief get a reference value (implicit)
20764 @copydoc get_ref()
20765 */
20766 template < typename ReferenceType, typename std::enable_if <
20767 std::is_reference<ReferenceType>::value&&
20768 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
20769 ReferenceType get_ref() const
20770 {
20771 // delegate call to get_ref_impl
20772 return get_ref_impl<ReferenceType>(*this);
20773 }
20774
20775 /*!
20776 @brief get a value (implicit)
20777
20778 Implicit type conversion between the JSON value and a compatible value.
20779 The call is realized by calling @ref get() const.
20780
20781 @tparam ValueType non-pointer type compatible to the JSON value, for
20782 instance `int` for JSON integer numbers, `bool` for JSON booleans, or
20783 `std::vector` types for JSON arrays. The character type of @ref string_t
20784 as well as an initializer list of this type is excluded to avoid
20785 ambiguities as these types implicitly convert to `std::string`.
20786
20787 @return copy of the JSON value, converted to type @a ValueType
20788
20789 @throw type_error.302 in case passed type @a ValueType is incompatible
20790 to the JSON value type (e.g., the JSON value is of type boolean, but a
20791 string is requested); see example below
20792
20793 @complexity Linear in the size of the JSON value.
20794
20795 @liveexample{The example below shows several conversions from JSON values
20796 to other types. There a few things to note: (1) Floating-point numbers can
20797 be converted to integers\, (2) A JSON array can be converted to a standard
20798 `std::vector<short>`\, (3) A JSON object can be converted to C++
20799 associative containers such as `std::unordered_map<std::string\,
20800 json>`.,operator__ValueType}
20801
20802 @since version 1.0.0
20803 */
20804 template < typename ValueType, typename std::enable_if <
20805 detail::conjunction <
20806 detail::negation<std::is_pointer<ValueType>>,
20807 detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
20808 detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
20809 detail::negation<detail::is_basic_json<ValueType>>,
20810 detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,
20811
20812#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20813 detail::negation<std::is_same<ValueType, std::string_view>>,
20814#endif
20815 detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>
20816 >::value, int >::type = 0 >
20817 JSON_EXPLICIT operator ValueType() const
20818 {
20819 // delegate the call to get<>() const
20820 return get<ValueType>();
20821 }
20822
20823 /*!
20824 @return reference to the binary value
20825
20826 @throw type_error.302 if the value is not binary
20827
20828 @sa see @ref is_binary() to check if the value is binary
20829
20830 @since version 3.8.0
20831 */
20832 binary_t& get_binary()
20833 {
20834 if (!is_binary())
20835 {
20836 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20837 }
20838
20839 return *get_ptr<binary_t*>();
20840 }
20841
20842 /// @copydoc get_binary()
20843 const binary_t& get_binary() const
20844 {
20845 if (!is_binary())
20846 {
20847 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20848 }
20849
20850 return *get_ptr<const binary_t*>();
20851 }
20852
20853 /// @}
20854
20855
20856 ////////////////////
20857 // element access //
20858 ////////////////////
20859
20860 /// @name element access
20861 /// Access to the JSON value.
20862 /// @{
20863
20864 /*!
20865 @brief access specified array element with bounds checking
20866
20867 Returns a reference to the element at specified location @a idx, with
20868 bounds checking.
20869
20870 @param[in] idx index of the element to access
20871
20872 @return reference to the element at index @a idx
20873
20874 @throw type_error.304 if the JSON value is not an array; in this case,
20875 calling `at` with an index makes no sense. See example below.
20876 @throw out_of_range.401 if the index @a idx is out of range of the array;
20877 that is, `idx >= size()`. See example below.
20878
20879 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20880 changes in the JSON value.
20881
20882 @complexity Constant.
20883
20884 @since version 1.0.0
20885
20886 @liveexample{The example below shows how array elements can be read and
20887 written using `at()`. It also demonstrates the different exceptions that
20888 can be thrown.,at__size_type}
20889 */
20890 reference at(size_type idx)
20891 {
20892 // at only works for arrays
20894 {
20895 JSON_TRY
20896 {
20897 return set_parent(m_value.array->at(idx));
20898 }
20900 {
20901 // create better exception explanation
20902 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20903 }
20904 }
20905 else
20906 {
20907 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20908 }
20909 }
20910
20911 /*!
20912 @brief access specified array element with bounds checking
20913
20914 Returns a const reference to the element at specified location @a idx,
20915 with bounds checking.
20916
20917 @param[in] idx index of the element to access
20918
20919 @return const reference to the element at index @a idx
20920
20921 @throw type_error.304 if the JSON value is not an array; in this case,
20922 calling `at` with an index makes no sense. See example below.
20923 @throw out_of_range.401 if the index @a idx is out of range of the array;
20924 that is, `idx >= size()`. See example below.
20925
20926 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20927 changes in the JSON value.
20928
20929 @complexity Constant.
20930
20931 @since version 1.0.0
20932
20933 @liveexample{The example below shows how array elements can be read using
20934 `at()`. It also demonstrates the different exceptions that can be thrown.,
20935 at__size_type_const}
20936 */
20937 const_reference at(size_type idx) const
20938 {
20939 // at only works for arrays
20941 {
20942 JSON_TRY
20943 {
20944 return m_value.array->at(idx);
20945 }
20947 {
20948 // create better exception explanation
20949 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20950 }
20951 }
20952 else
20953 {
20954 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20955 }
20956 }
20957
20958 /*!
20959 @brief access specified object element with bounds checking
20960
20961 Returns a reference to the element at with specified key @a key, with
20962 bounds checking.
20963
20964 @param[in] key key of the element to access
20965
20966 @return reference to the element at key @a key
20967
20968 @throw type_error.304 if the JSON value is not an object; in this case,
20969 calling `at` with a key makes no sense. See example below.
20970 @throw out_of_range.403 if the key @a key is is not stored in the object;
20971 that is, `find(key) == end()`. See example below.
20972
20973 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20974 changes in the JSON value.
20975
20976 @complexity Logarithmic in the size of the container.
20977
20978 @sa see @ref operator[](const typename object_t::key_type&) for unchecked
20979 access by reference
20980 @sa see @ref value() for access by value with a default value
20981
20982 @since version 1.0.0
20983
20984 @liveexample{The example below shows how object elements can be read and
20985 written using `at()`. It also demonstrates the different exceptions that
20986 can be thrown.,at__object_t_key_type}
20987 */
20988 reference at(const typename object_t::key_type& key)
20989 {
20990 // at only works for objects
20992 {
20993 JSON_TRY
20994 {
20995 return set_parent(m_value.object->at(key));
20996 }
20998 {
20999 // create better exception explanation
21000 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21001 }
21002 }
21003 else
21004 {
21005 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21006 }
21007 }
21008
21009 /*!
21010 @brief access specified object element with bounds checking
21011
21012 Returns a const reference to the element at with specified key @a key,
21013 with bounds checking.
21014
21015 @param[in] key key of the element to access
21016
21017 @return const reference to the element at key @a key
21018
21019 @throw type_error.304 if the JSON value is not an object; in this case,
21020 calling `at` with a key makes no sense. See example below.
21021 @throw out_of_range.403 if the key @a key is is not stored in the object;
21022 that is, `find(key) == end()`. See example below.
21023
21024 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21025 changes in the JSON value.
21026
21027 @complexity Logarithmic in the size of the container.
21028
21029 @sa see @ref operator[](const typename object_t::key_type&) for unchecked
21030 access by reference
21031 @sa see @ref value() for access by value with a default value
21032
21033 @since version 1.0.0
21034
21035 @liveexample{The example below shows how object elements can be read using
21036 `at()`. It also demonstrates the different exceptions that can be thrown.,
21037 at__object_t_key_type_const}
21038 */
21039 const_reference at(const typename object_t::key_type& key) const
21040 {
21041 // at only works for objects
21043 {
21044 JSON_TRY
21045 {
21046 return m_value.object->at(key);
21047 }
21049 {
21050 // create better exception explanation
21051 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21052 }
21053 }
21054 else
21055 {
21056 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21057 }
21058 }
21059
21060 /*!
21061 @brief access specified array element
21062
21063 Returns a reference to the element at specified location @a idx.
21064
21065 @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
21066 then the array is silently filled up with `null` values to make `idx` a
21067 valid reference to the last stored element.
21068
21069 @param[in] idx index of the element to access
21070
21071 @return reference to the element at index @a idx
21072
21073 @throw type_error.305 if the JSON value is not an array or null; in that
21074 cases, using the [] operator with an index makes no sense.
21075
21076 @complexity Constant if @a idx is in the range of the array. Otherwise
21077 linear in `idx - size()`.
21078
21079 @liveexample{The example below shows how array elements can be read and
21080 written using `[]` operator. Note the addition of `null`
21081 values.,operatorarray__size_type}
21082
21083 @since version 1.0.0
21084 */
21085 reference operator[](size_type idx)
21086 {
21087 // implicitly convert null value to an empty array
21088 if (is_null())
21089 {
21090 m_type = value_t::array;
21093 }
21094
21095 // operator[] only works for arrays
21097 {
21098 // fill up array with null values if given idx is outside range
21099 if (idx >= m_value.array->size())
21100 {
21102 // remember array size before resizing
21103 const auto previous_size = m_value.array->size();
21104#endif
21105 m_value.array->resize(idx + 1);
21106
21108 // set parent for values added above
21109 set_parents(begin() + static_cast<typename iterator::difference_type>(previous_size), static_cast<typename iterator::difference_type>(idx + 1 - previous_size));
21110#endif
21111 }
21112
21113 return m_value.array->operator[](idx);
21114 }
21115
21116 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21117 }
21118
21119 /*!
21120 @brief access specified array element
21121
21122 Returns a const reference to the element at specified location @a idx.
21123
21124 @param[in] idx index of the element to access
21125
21126 @return const reference to the element at index @a idx
21127
21128 @throw type_error.305 if the JSON value is not an array; in that case,
21129 using the [] operator with an index makes no sense.
21130
21131 @complexity Constant.
21132
21133 @liveexample{The example below shows how array elements can be read using
21134 the `[]` operator.,operatorarray__size_type_const}
21135
21136 @since version 1.0.0
21137 */
21138 const_reference operator[](size_type idx) const
21139 {
21140 // const operator[] only works for arrays
21142 {
21143 return m_value.array->operator[](idx);
21144 }
21145
21146 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21147 }
21148
21149 /*!
21150 @brief access specified object element
21151
21152 Returns a reference to the element at with specified key @a key.
21153
21154 @note If @a key is not found in the object, then it is silently added to
21155 the object and filled with a `null` value to make `key` a valid reference.
21156 In case the value was `null` before, it is converted to an object.
21157
21158 @param[in] key key of the element to access
21159
21160 @return reference to the element at key @a key
21161
21162 @throw type_error.305 if the JSON value is not an object or null; in that
21163 cases, using the [] operator with a key makes no sense.
21164
21165 @complexity Logarithmic in the size of the container.
21166
21167 @liveexample{The example below shows how object elements can be read and
21168 written using the `[]` operator.,operatorarray__key_type}
21169
21170 @sa see @ref at(const typename object_t::key_type&) for access by reference
21171 with range checking
21172 @sa see @ref value() for access by value with a default value
21173
21174 @since version 1.0.0
21175 */
21176 reference operator[](const typename object_t::key_type& key)
21177 {
21178 // implicitly convert null value to an empty object
21179 if (is_null())
21180 {
21184 }
21185
21186 // operator[] only works for objects
21188 {
21189 return set_parent(m_value.object->operator[](key));
21190 }
21191
21192 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21193 }
21194
21195 /*!
21196 @brief read-only access specified object element
21197
21198 Returns a const reference to the element at with specified key @a key. No
21199 bounds checking is performed.
21200
21201 @warning If the element with key @a key does not exist, the behavior is
21202 undefined.
21203
21204 @param[in] key key of the element to access
21205
21206 @return const reference to the element at key @a key
21207
21208 @pre The element with key @a key must exist. **This precondition is
21209 enforced with an assertion.**
21210
21211 @throw type_error.305 if the JSON value is not an object; in that case,
21212 using the [] operator with a key makes no sense.
21213
21214 @complexity Logarithmic in the size of the container.
21215
21216 @liveexample{The example below shows how object elements can be read using
21217 the `[]` operator.,operatorarray__key_type_const}
21218
21219 @sa see @ref at(const typename object_t::key_type&) for access by reference
21220 with range checking
21221 @sa see @ref value() for access by value with a default value
21222
21223 @since version 1.0.0
21224 */
21225 const_reference operator[](const typename object_t::key_type& key) const
21226 {
21227 // const operator[] only works for objects
21229 {
21231 return m_value.object->find(key)->second;
21232 }
21233
21234 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21235 }
21236
21237 /*!
21238 @brief access specified object element
21239
21240 Returns a reference to the element at with specified key @a key.
21241
21242 @note If @a key is not found in the object, then it is silently added to
21243 the object and filled with a `null` value to make `key` a valid reference.
21244 In case the value was `null` before, it is converted to an object.
21245
21246 @param[in] key key of the element to access
21247
21248 @return reference to the element at key @a key
21249
21250 @throw type_error.305 if the JSON value is not an object or null; in that
21251 cases, using the [] operator with a key makes no sense.
21252
21253 @complexity Logarithmic in the size of the container.
21254
21255 @liveexample{The example below shows how object elements can be read and
21256 written using the `[]` operator.,operatorarray__key_type}
21257
21258 @sa see @ref at(const typename object_t::key_type&) for access by reference
21259 with range checking
21260 @sa see @ref value() for access by value with a default value
21261
21262 @since version 1.1.0
21263 */
21264 template<typename T>
21266 reference operator[](T* key)
21267 {
21268 // implicitly convert null to object
21269 if (is_null())
21270 {
21274 }
21275
21276 // at only works for objects
21278 {
21279 return set_parent(m_value.object->operator[](key));
21280 }
21281
21282 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21283 }
21284
21285 /*!
21286 @brief read-only access specified object element
21287
21288 Returns a const reference to the element at with specified key @a key. No
21289 bounds checking is performed.
21290
21291 @warning If the element with key @a key does not exist, the behavior is
21292 undefined.
21293
21294 @param[in] key key of the element to access
21295
21296 @return const reference to the element at key @a key
21297
21298 @pre The element with key @a key must exist. **This precondition is
21299 enforced with an assertion.**
21300
21301 @throw type_error.305 if the JSON value is not an object; in that case,
21302 using the [] operator with a key makes no sense.
21303
21304 @complexity Logarithmic in the size of the container.
21305
21306 @liveexample{The example below shows how object elements can be read using
21307 the `[]` operator.,operatorarray__key_type_const}
21308
21309 @sa see @ref at(const typename object_t::key_type&) for access by reference
21310 with range checking
21311 @sa see @ref value() for access by value with a default value
21312
21313 @since version 1.1.0
21314 */
21315 template<typename T>
21317 const_reference operator[](T* key) const
21318 {
21319 // at only works for objects
21321 {
21323 return m_value.object->find(key)->second;
21324 }
21325
21326 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21327 }
21328
21329 /*!
21330 @brief access specified object element with default value
21331
21332 Returns either a copy of an object's element at the specified key @a key
21333 or a given default value if no element with key @a key exists.
21334
21335 The function is basically equivalent to executing
21336 @code {.cpp}
21337 try {
21338 return at(key);
21339 } catch(out_of_range) {
21340 return default_value;
21341 }
21342 @endcode
21343
21344 @note Unlike @ref at(const typename object_t::key_type&), this function
21345 does not throw if the given key @a key was not found.
21346
21347 @note Unlike @ref operator[](const typename object_t::key_type& key), this
21348 function does not implicitly add an element to the position defined by @a
21349 key. This function is furthermore also applicable to const objects.
21350
21351 @param[in] key key of the element to access
21352 @param[in] default_value the value to return if @a key is not found
21353
21354 @tparam ValueType type compatible to JSON values, for instance `int` for
21355 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
21356 JSON arrays. Note the type of the expected value at @a key and the default
21357 value @a default_value must be compatible.
21358
21359 @return copy of the element at key @a key or @a default_value if @a key
21360 is not found
21361
21362 @throw type_error.302 if @a default_value does not match the type of the
21363 value at @a key
21364 @throw type_error.306 if the JSON value is not an object; in that case,
21365 using `value()` with a key makes no sense.
21366
21367 @complexity Logarithmic in the size of the container.
21368
21369 @liveexample{The example below shows how object elements can be queried
21370 with a default value.,basic_json__value}
21371
21372 @sa see @ref at(const typename object_t::key_type&) for access by reference
21373 with range checking
21374 @sa see @ref operator[](const typename object_t::key_type&) for unchecked
21375 access by reference
21376
21377 @since version 1.0.0
21378 */
21379 // using std::is_convertible in a std::enable_if will fail when using explicit conversions
21380 template < class ValueType, typename std::enable_if <
21381 detail::is_getable<basic_json_t, ValueType>::value
21382 && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
21383 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21384 {
21385 // at only works for objects
21387 {
21388 // if key is found, return value and given default value otherwise
21389 const auto it = find(key);
21390 if (it != end())
21391 {
21392 return it->template get<ValueType>();
21393 }
21394
21395 return default_value;
21396 }
21397
21398 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21399 }
21400
21401 /*!
21402 @brief overload for a default value of type const char*
21403 @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
21404 */
21405 string_t value(const typename object_t::key_type& key, const char* default_value) const
21406 {
21407 return value(key, string_t(default_value));
21408 }
21409
21410 /*!
21411 @brief access specified object element via JSON Pointer with default value
21412
21413 Returns either a copy of an object's element at the specified key @a key
21414 or a given default value if no element with key @a key exists.
21415
21416 The function is basically equivalent to executing
21417 @code {.cpp}
21418 try {
21419 return at(ptr);
21420 } catch(out_of_range) {
21421 return default_value;
21422 }
21423 @endcode
21424
21425 @note Unlike @ref at(const json_pointer&), this function does not throw
21426 if the given key @a key was not found.
21427
21428 @param[in] ptr a JSON pointer to the element to access
21429 @param[in] default_value the value to return if @a ptr found no value
21430
21431 @tparam ValueType type compatible to JSON values, for instance `int` for
21432 JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
21433 JSON arrays. Note the type of the expected value at @a key and the default
21434 value @a default_value must be compatible.
21435
21436 @return copy of the element at key @a key or @a default_value if @a key
21437 is not found
21438
21439 @throw type_error.302 if @a default_value does not match the type of the
21440 value at @a ptr
21441 @throw type_error.306 if the JSON value is not an object; in that case,
21442 using `value()` with a key makes no sense.
21443
21444 @complexity Logarithmic in the size of the container.
21445
21446 @liveexample{The example below shows how object elements can be queried
21447 with a default value.,basic_json__value_ptr}
21448
21449 @sa see @ref operator[](const json_pointer&) for unchecked access by reference
21450
21451 @since version 2.0.2
21452 */
21453 template<class ValueType, typename std::enable_if<
21454 detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
21455 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21456 {
21457 // at only works for objects
21459 {
21460 // if pointer resolves a value, return it or use default value
21461 JSON_TRY
21462 {
21463 return ptr.get_checked(this).template get<ValueType>();
21464 }
21466 {
21467 return default_value;
21468 }
21469 }
21470
21471 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21472 }
21473
21474 /*!
21475 @brief overload for a default value of type const char*
21476 @copydoc basic_json::value(const json_pointer&, ValueType) const
21477 */
21479 string_t value(const json_pointer& ptr, const char* default_value) const
21480 {
21481 return value(ptr, string_t(default_value));
21482 }
21483
21484 /*!
21485 @brief access the first element
21486
21487 Returns a reference to the first element in the container. For a JSON
21488 container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
21489
21490 @return In case of a structured type (array or object), a reference to the
21491 first element is returned. In case of number, string, boolean, or binary
21492 values, a reference to the value is returned.
21493
21494 @complexity Constant.
21495
21496 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
21497 or an empty array or object (undefined behavior, **guarded by
21498 assertions**).
21499 @post The JSON value remains unchanged.
21500
21501 @throw invalid_iterator.214 when called on `null` value
21502
21503 @liveexample{The following code shows an example for `front()`.,front}
21504
21505 @sa see @ref back() -- access the last element
21506
21507 @since version 1.0.0
21508 */
21509 reference front()
21510 {
21511 return *begin();
21512 }
21513
21514 /*!
21515 @copydoc basic_json::front()
21516 */
21517 const_reference front() const
21518 {
21519 return *cbegin();
21520 }
21521
21522 /*!
21523 @brief access the last element
21524
21525 Returns a reference to the last element in the container. For a JSON
21526 container `c`, the expression `c.back()` is equivalent to
21527 @code {.cpp}
21528 auto tmp = c.end();
21529 --tmp;
21530 return *tmp;
21531 @endcode
21532
21533 @return In case of a structured type (array or object), a reference to the
21534 last element is returned. In case of number, string, boolean, or binary
21535 values, a reference to the value is returned.
21536
21537 @complexity Constant.
21538
21539 @pre The JSON value must not be `null` (would throw `std::out_of_range`)
21540 or an empty array or object (undefined behavior, **guarded by
21541 assertions**).
21542 @post The JSON value remains unchanged.
21543
21544 @throw invalid_iterator.214 when called on a `null` value. See example
21545 below.
21546
21547 @liveexample{The following code shows an example for `back()`.,back}
21548
21549 @sa see @ref front() -- access the first element
21550
21551 @since version 1.0.0
21552 */
21553 reference back()
21554 {
21555 auto tmp = end();
21556 --tmp;
21557 return *tmp;
21558 }
21559
21560 /*!
21561 @copydoc basic_json::back()
21562 */
21563 const_reference back() const
21564 {
21565 auto tmp = cend();
21566 --tmp;
21567 return *tmp;
21568 }
21569
21570 /*!
21571 @brief remove element given an iterator
21572
21573 Removes the element specified by iterator @a pos. The iterator @a pos must
21574 be valid and dereferenceable. Thus the `end()` iterator (which is valid,
21575 but is not dereferenceable) cannot be used as a value for @a pos.
21576
21577 If called on a primitive type other than `null`, the resulting JSON value
21578 will be `null`.
21579
21580 @param[in] pos iterator to the element to remove
21581 @return Iterator following the last removed element. If the iterator @a
21582 pos refers to the last element, the `end()` iterator is returned.
21583
21584 @tparam IteratorType an @ref iterator or @ref const_iterator
21585
21586 @post Invalidates iterators and references at or after the point of the
21587 erase, including the `end()` iterator.
21588
21589 @throw type_error.307 if called on a `null` value; example: `"cannot use
21590 erase() with null"`
21591 @throw invalid_iterator.202 if called on an iterator which does not belong
21592 to the current JSON value; example: `"iterator does not fit current
21593 value"`
21594 @throw invalid_iterator.205 if called on a primitive type with invalid
21595 iterator (i.e., any iterator which is not `begin()`); example: `"iterator
21596 out of range"`
21597
21598 @complexity The complexity depends on the type:
21599 - objects: amortized constant
21600 - arrays: linear in distance between @a pos and the end of the container
21601 - strings and binary: linear in the length of the member
21602 - other types: constant
21603
21604 @liveexample{The example shows the result of `erase()` for different JSON
21605 types.,erase__IteratorType}
21606
21607 @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21608 the given range
21609 @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21610 from an object at the given key
21611 @sa see @ref erase(const size_type) -- removes the element from an array at
21612 the given index
21613
21614 @since version 1.0.0
21615 */
21616 template < class IteratorType, typename std::enable_if <
21617 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21618 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21619 = 0 >
21620 IteratorType erase(IteratorType pos)
21621 {
21622 // make sure iterator fits the current value
21623 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21624 {
21625 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
21626 }
21627
21629
21630 switch (m_type)
21631 {
21632 case value_t::boolean:
21633 case value_t::number_float:
21634 case value_t::number_integer:
21636 case value_t::string:
21637 case value_t::binary:
21638 {
21640 {
21641 JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
21642 }
21643
21644 if (is_string())
21645 {
21649 m_value.string = nullptr;
21650 }
21651 else if (is_binary())
21652 {
21656 m_value.binary = nullptr;
21657 }
21658
21659 m_type = value_t::null;
21661 break;
21662 }
21663
21664 case value_t::object:
21665 {
21667 break;
21668 }
21669
21670 case value_t::array:
21671 {
21673 break;
21674 }
21675
21676 case value_t::null:
21677 case value_t::discarded:
21678 default:
21679 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21680 }
21681
21682 return result;
21683 }
21684
21685 /*!
21686 @brief remove elements given an iterator range
21687
21688 Removes the element specified by the range `[first; last)`. The iterator
21689 @a first does not need to be dereferenceable if `first == last`: erasing
21690 an empty range is a no-op.
21691
21692 If called on a primitive type other than `null`, the resulting JSON value
21693 will be `null`.
21694
21695 @param[in] first iterator to the beginning of the range to remove
21696 @param[in] last iterator past the end of the range to remove
21697 @return Iterator following the last removed element. If the iterator @a
21698 second refers to the last element, the `end()` iterator is returned.
21699
21700 @tparam IteratorType an @ref iterator or @ref const_iterator
21701
21702 @post Invalidates iterators and references at or after the point of the
21703 erase, including the `end()` iterator.
21704
21705 @throw type_error.307 if called on a `null` value; example: `"cannot use
21706 erase() with null"`
21707 @throw invalid_iterator.203 if called on iterators which does not belong
21708 to the current JSON value; example: `"iterators do not fit current value"`
21709 @throw invalid_iterator.204 if called on a primitive type with invalid
21710 iterators (i.e., if `first != begin()` and `last != end()`); example:
21711 `"iterators out of range"`
21712
21713 @complexity The complexity depends on the type:
21714 - objects: `log(size()) + std::distance(first, last)`
21715 - arrays: linear in the distance between @a first and @a last, plus linear
21716 in the distance between @a last and end of the container
21717 - strings and binary: linear in the length of the member
21718 - other types: constant
21719
21720 @liveexample{The example shows the result of `erase()` for different JSON
21721 types.,erase__IteratorType_IteratorType}
21722
21723 @sa see @ref erase(IteratorType) -- removes the element at a given position
21724 @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21725 from an object at the given key
21726 @sa see @ref erase(const size_type) -- removes the element from an array at
21727 the given index
21728
21729 @since version 1.0.0
21730 */
21731 template < class IteratorType, typename std::enable_if <
21732 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21733 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21734 = 0 >
21735 IteratorType erase(IteratorType first, IteratorType last)
21736 {
21737 // make sure iterator fits the current value
21738 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21739 {
21740 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
21741 }
21742
21744
21745 switch (m_type)
21746 {
21747 case value_t::boolean:
21748 case value_t::number_float:
21749 case value_t::number_integer:
21751 case value_t::string:
21752 case value_t::binary:
21753 {
21756 {
21757 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
21758 }
21759
21760 if (is_string())
21761 {
21765 m_value.string = nullptr;
21766 }
21767 else if (is_binary())
21768 {
21772 m_value.binary = nullptr;
21773 }
21774
21775 m_type = value_t::null;
21777 break;
21778 }
21779
21780 case value_t::object:
21781 {
21784 break;
21785 }
21786
21787 case value_t::array:
21788 {
21791 break;
21792 }
21793
21794 case value_t::null:
21795 case value_t::discarded:
21796 default:
21797 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21798 }
21799
21800 return result;
21801 }
21802
21803 /*!
21804 @brief remove element from a JSON object given a key
21805
21806 Removes elements from a JSON object with the key value @a key.
21807
21808 @param[in] key value of the elements to remove
21809
21810 @return Number of elements removed. If @a ObjectType is the default
21811 `std::map` type, the return value will always be `0` (@a key was not
21812 found) or `1` (@a key was found).
21813
21814 @post References and iterators to the erased elements are invalidated.
21815 Other references and iterators are not affected.
21816
21817 @throw type_error.307 when called on a type other than JSON object;
21818 example: `"cannot use erase() with null"`
21819
21820 @complexity `log(size()) + count(key)`
21821
21822 @liveexample{The example shows the effect of `erase()`.,erase__key_type}
21823
21824 @sa see @ref erase(IteratorType) -- removes the element at a given position
21825 @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21826 the given range
21827 @sa see @ref erase(const size_type) -- removes the element from an array at
21828 the given index
21829
21830 @since version 1.0.0
21831 */
21832 size_type erase(const typename object_t::key_type& key)
21833 {
21834 // this erase only works for objects
21836 {
21837 return m_value.object->erase(key);
21838 }
21839
21840 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21841 }
21842
21843 /*!
21844 @brief remove element from a JSON array given an index
21845
21846 Removes element from a JSON array at the index @a idx.
21847
21848 @param[in] idx index of the element to remove
21849
21850 @throw type_error.307 when called on a type other than JSON object;
21851 example: `"cannot use erase() with null"`
21852 @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
21853 is out of range"`
21854
21855 @complexity Linear in distance between @a idx and the end of the container.
21856
21857 @liveexample{The example shows the effect of `erase()`.,erase__size_type}
21858
21859 @sa see @ref erase(IteratorType) -- removes the element at a given position
21860 @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21861 the given range
21862 @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21863 from an object at the given key
21864
21865 @since version 1.0.0
21866 */
21867 void erase(const size_type idx)
21868 {
21869 // this erase only works for arrays
21871 {
21872 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21873 {
21874 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21875 }
21876
21877 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21878 }
21879 else
21880 {
21881 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21882 }
21883 }
21884
21885 /// @}
21886
21887
21888 ////////////
21889 // lookup //
21890 ////////////
21891
21892 /// @name lookup
21893 /// @{
21894
21895 /*!
21896 @brief find an element in a JSON object
21897
21898 Finds an element in a JSON object with key equivalent to @a key. If the
21899 element is not found or the JSON value is not an object, end() is
21900 returned.
21901
21902 @note This method always returns @ref end() when executed on a JSON type
21903 that is not an object.
21904
21905 @param[in] key key value of the element to search for.
21906
21907 @return Iterator to an element with key equivalent to @a key. If no such
21908 element is found or the JSON value is not an object, past-the-end (see
21909 @ref end()) iterator is returned.
21910
21911 @complexity Logarithmic in the size of the JSON object.
21912
21913 @liveexample{The example shows how `find()` is used.,find__key_type}
21914
21915 @sa see @ref contains(KeyT&&) const -- checks whether a key exists
21916
21917 @since version 1.0.0
21918 */
21919 template<typename KeyT>
21920 iterator find(KeyT&& key)
21921 {
21922 auto result = end();
21923
21924 if (is_object())
21925 {
21927 }
21928
21929 return result;
21930 }
21931
21932 /*!
21933 @brief find an element in a JSON object
21934 @copydoc find(KeyT&&)
21935 */
21936 template<typename KeyT>
21937 const_iterator find(KeyT&& key) const
21938 {
21939 auto result = cend();
21940
21941 if (is_object())
21942 {
21944 }
21945
21946 return result;
21947 }
21948
21949 /*!
21950 @brief returns the number of occurrences of a key in a JSON object
21951
21952 Returns the number of elements with key @a key. If ObjectType is the
21953 default `std::map` type, the return value will always be `0` (@a key was
21954 not found) or `1` (@a key was found).
21955
21956 @note This method always returns `0` when executed on a JSON type that is
21957 not an object.
21958
21959 @param[in] key key value of the element to count
21960
21961 @return Number of elements with key @a key. If the JSON value is not an
21962 object, the return value will be `0`.
21963
21964 @complexity Logarithmic in the size of the JSON object.
21965
21966 @liveexample{The example shows how `count()` is used.,count}
21967
21968 @since version 1.0.0
21969 */
21970 template<typename KeyT>
21971 size_type count(KeyT&& key) const
21972 {
21973 // return 0 for all nonobject types
21974 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
21975 }
21976
21977 /*!
21978 @brief check the existence of an element in a JSON object
21979
21980 Check whether an element exists in a JSON object with key equivalent to
21981 @a key. If the element is not found or the JSON value is not an object,
21982 false is returned.
21983
21984 @note This method always returns false when executed on a JSON type
21985 that is not an object.
21986
21987 @param[in] key key value to check its existence.
21988
21989 @return true if an element with specified @a key exists. If no such
21990 element with such key is found or the JSON value is not an object,
21991 false is returned.
21992
21993 @complexity Logarithmic in the size of the JSON object.
21994
21995 @liveexample{The following code shows an example for `contains()`.,contains}
21996
21997 @sa see @ref find(KeyT&&) -- returns an iterator to an object element
21998 @sa see @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
21999
22000 @since version 3.6.0
22001 */
22002 template < typename KeyT, typename std::enable_if <
22003 !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
22004 bool contains(KeyT&& key) const
22005 {
22006 return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
22007 }
22008
22009 /*!
22010 @brief check the existence of an element in a JSON object given a JSON pointer
22011
22012 Check whether the given JSON pointer @a ptr can be resolved in the current
22013 JSON value.
22014
22015 @note This method can be executed on any JSON value type.
22016
22017 @param[in] ptr JSON pointer to check its existence.
22018
22019 @return true if the JSON pointer can be resolved to a stored value, false
22020 otherwise.
22021
22022 @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
22023
22024 @throw parse_error.106 if an array index begins with '0'
22025 @throw parse_error.109 if an array index was not a number
22026
22027 @complexity Logarithmic in the size of the JSON object.
22028
22029 @liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
22030
22031 @sa see @ref contains(KeyT &&) const -- checks the existence of a key
22032
22033 @since version 3.7.0
22034 */
22035 bool contains(const json_pointer& ptr) const
22036 {
22037 return ptr.contains(this);
22038 }
22039
22040 /// @}
22041
22042
22043 ///////////////
22044 // iterators //
22045 ///////////////
22046
22047 /// @name iterators
22048 /// @{
22049
22050 /*!
22051 @brief returns an iterator to the first element
22052
22053 Returns an iterator to the first element.
22054
22055 @image html range-begin-end.svg "Illustration from cppreference.com"
22056
22057 @return iterator to the first element
22058
22059 @complexity Constant.
22060
22061 @requirement This function helps `basic_json` satisfying the
22062 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22063 requirements:
22064 - The complexity is constant.
22065
22066 @liveexample{The following code shows an example for `begin()`.,begin}
22067
22068 @sa see @ref cbegin() -- returns a const iterator to the beginning
22069 @sa see @ref end() -- returns an iterator to the end
22070 @sa see @ref cend() -- returns a const iterator to the end
22071
22072 @since version 1.0.0
22073 */
22074 iterator begin() noexcept
22075 {
22076 iterator result(this);
22077 result.set_begin();
22078 return result;
22079 }
22080
22081 /*!
22082 @copydoc basic_json::cbegin()
22083 */
22084 const_iterator begin() const noexcept
22085 {
22086 return cbegin();
22087 }
22088
22089 /*!
22090 @brief returns a const iterator to the first element
22091
22092 Returns a const iterator to the first element.
22093
22094 @image html range-begin-end.svg "Illustration from cppreference.com"
22095
22096 @return const iterator to the first element
22097
22098 @complexity Constant.
22099
22100 @requirement This function helps `basic_json` satisfying the
22101 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22102 requirements:
22103 - The complexity is constant.
22104 - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
22105
22106 @liveexample{The following code shows an example for `cbegin()`.,cbegin}
22107
22108 @sa see @ref begin() -- returns an iterator to the beginning
22109 @sa see @ref end() -- returns an iterator to the end
22110 @sa see @ref cend() -- returns a const iterator to the end
22111
22112 @since version 1.0.0
22113 */
22114 const_iterator cbegin() const noexcept
22115 {
22116 const_iterator result(this);
22117 result.set_begin();
22118 return result;
22119 }
22120
22121 /*!
22122 @brief returns an iterator to one past the last element
22123
22124 Returns an iterator to one past the last element.
22125
22126 @image html range-begin-end.svg "Illustration from cppreference.com"
22127
22128 @return iterator one past the last element
22129
22130 @complexity Constant.
22131
22132 @requirement This function helps `basic_json` satisfying the
22133 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22134 requirements:
22135 - The complexity is constant.
22136
22137 @liveexample{The following code shows an example for `end()`.,end}
22138
22139 @sa see @ref cend() -- returns a const iterator to the end
22140 @sa see @ref begin() -- returns an iterator to the beginning
22141 @sa see @ref cbegin() -- returns a const iterator to the beginning
22142
22143 @since version 1.0.0
22144 */
22145 iterator end() noexcept
22146 {
22147 iterator result(this);
22148 result.set_end();
22149 return result;
22150 }
22151
22152 /*!
22153 @copydoc basic_json::cend()
22154 */
22155 const_iterator end() const noexcept
22156 {
22157 return cend();
22158 }
22159
22160 /*!
22161 @brief returns a const iterator to one past the last element
22162
22163 Returns a const iterator to one past the last element.
22164
22165 @image html range-begin-end.svg "Illustration from cppreference.com"
22166
22167 @return const iterator one past the last element
22168
22169 @complexity Constant.
22170
22171 @requirement This function helps `basic_json` satisfying the
22172 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22173 requirements:
22174 - The complexity is constant.
22175 - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
22176
22177 @liveexample{The following code shows an example for `cend()`.,cend}
22178
22179 @sa see @ref end() -- returns an iterator to the end
22180 @sa see @ref begin() -- returns an iterator to the beginning
22181 @sa see @ref cbegin() -- returns a const iterator to the beginning
22182
22183 @since version 1.0.0
22184 */
22185 const_iterator cend() const noexcept
22186 {
22187 const_iterator result(this);
22188 result.set_end();
22189 return result;
22190 }
22191
22192 /*!
22193 @brief returns an iterator to the reverse-beginning
22194
22195 Returns an iterator to the reverse-beginning; that is, the last element.
22196
22197 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22198
22199 @complexity Constant.
22200
22201 @requirement This function helps `basic_json` satisfying the
22202 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22203 requirements:
22204 - The complexity is constant.
22205 - Has the semantics of `reverse_iterator(end())`.
22206
22207 @liveexample{The following code shows an example for `rbegin()`.,rbegin}
22208
22209 @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22210 @sa see @ref rend() -- returns a reverse iterator to the end
22211 @sa see @ref crend() -- returns a const reverse iterator to the end
22212
22213 @since version 1.0.0
22214 */
22215 reverse_iterator rbegin() noexcept
22216 {
22217 return reverse_iterator(end());
22218 }
22219
22220 /*!
22221 @copydoc basic_json::crbegin()
22222 */
22223 const_reverse_iterator rbegin() const noexcept
22224 {
22225 return crbegin();
22226 }
22227
22228 /*!
22229 @brief returns an iterator to the reverse-end
22230
22231 Returns an iterator to the reverse-end; that is, one before the first
22232 element.
22233
22234 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22235
22236 @complexity Constant.
22237
22238 @requirement This function helps `basic_json` satisfying the
22239 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22240 requirements:
22241 - The complexity is constant.
22242 - Has the semantics of `reverse_iterator(begin())`.
22243
22244 @liveexample{The following code shows an example for `rend()`.,rend}
22245
22246 @sa see @ref crend() -- returns a const reverse iterator to the end
22247 @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22248 @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22249
22250 @since version 1.0.0
22251 */
22252 reverse_iterator rend() noexcept
22253 {
22254 return reverse_iterator(begin());
22255 }
22256
22257 /*!
22258 @copydoc basic_json::crend()
22259 */
22260 const_reverse_iterator rend() const noexcept
22261 {
22262 return crend();
22263 }
22264
22265 /*!
22266 @brief returns a const reverse iterator to the last element
22267
22268 Returns a const iterator to the reverse-beginning; that is, the last
22269 element.
22270
22271 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22272
22273 @complexity Constant.
22274
22275 @requirement This function helps `basic_json` satisfying the
22276 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22277 requirements:
22278 - The complexity is constant.
22279 - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
22280
22281 @liveexample{The following code shows an example for `crbegin()`.,crbegin}
22282
22283 @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22284 @sa see @ref rend() -- returns a reverse iterator to the end
22285 @sa see @ref crend() -- returns a const reverse iterator to the end
22286
22287 @since version 1.0.0
22288 */
22289 const_reverse_iterator crbegin() const noexcept
22290 {
22291 return const_reverse_iterator(cend());
22292 }
22293
22294 /*!
22295 @brief returns a const reverse iterator to one before the first
22296
22297 Returns a const reverse iterator to the reverse-end; that is, one before
22298 the first element.
22299
22300 @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22301
22302 @complexity Constant.
22303
22304 @requirement This function helps `basic_json` satisfying the
22305 [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22306 requirements:
22307 - The complexity is constant.
22308 - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
22309
22310 @liveexample{The following code shows an example for `crend()`.,crend}
22311
22312 @sa see @ref rend() -- returns a reverse iterator to the end
22313 @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22314 @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22315
22316 @since version 1.0.0
22317 */
22318 const_reverse_iterator crend() const noexcept
22319 {
22321 }
22322
22323 public:
22324 /*!
22325 @brief wrapper to access iterator member functions in range-based for
22326
22327 This function allows to access @ref iterator::key() and @ref
22328 iterator::value() during range-based for loops. In these loops, a
22329 reference to the JSON values is returned, so there is no access to the
22330 underlying iterator.
22331
22332 For loop without iterator_wrapper:
22333
22334 @code{cpp}
22335 for (auto it = j_object.begin(); it != j_object.end(); ++it)
22336 {
22337 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22338 }
22339 @endcode
22340
22341 Range-based for loop without iterator proxy:
22342
22343 @code{cpp}
22344 for (auto it : j_object)
22345 {
22346 // "it" is of type json::reference and has no key() member
22347 std::cout << "value: " << it << '\n';
22348 }
22349 @endcode
22350
22351 Range-based for loop with iterator proxy:
22352
22353 @code{cpp}
22354 for (auto it : json::iterator_wrapper(j_object))
22355 {
22356 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22357 }
22358 @endcode
22359
22360 @note When iterating over an array, `key()` will return the index of the
22361 element as string (see example).
22362
22363 @param[in] ref reference to a JSON value
22364 @return iteration proxy object wrapping @a ref with an interface to use in
22365 range-based for loops
22366
22367 @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
22368
22369 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
22370 changes in the JSON value.
22371
22372 @complexity Constant.
22373
22374 @note The name of this function is not yet final and may change in the
22375 future.
22376
22377 @deprecated This stream operator is deprecated and will be removed in
22378 future 4.0.0 of the library. Please use @ref items() instead;
22379 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
22380 */
22381 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22382 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22383 {
22384 return ref.items();
22385 }
22386
22387 /*!
22388 @copydoc iterator_wrapper(reference)
22389 */
22390 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22391 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22392 {
22393 return ref.items();
22394 }
22395
22396 /*!
22397 @brief helper to access iterator member functions in range-based for
22398
22399 This function allows to access @ref iterator::key() and @ref
22400 iterator::value() during range-based for loops. In these loops, a
22401 reference to the JSON values is returned, so there is no access to the
22402 underlying iterator.
22403
22404 For loop without `items()` function:
22405
22406 @code{cpp}
22407 for (auto it = j_object.begin(); it != j_object.end(); ++it)
22408 {
22409 std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22410 }
22411 @endcode
22412
22413 Range-based for loop without `items()` function:
22414
22415 @code{cpp}
22416 for (auto it : j_object)
22417 {
22418 // "it" is of type json::reference and has no key() member
22419 std::cout << "value: " << it << '\n';
22420 }
22421 @endcode
22422
22423 Range-based for loop with `items()` function:
22424
22425 @code{cpp}
22426 for (auto& el : j_object.items())
22427 {
22428 std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
22429 }
22430 @endcode
22431
22432 The `items()` function also allows to use
22433 [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
22434 (C++17):
22435
22436 @code{cpp}
22437 for (auto& [key, val] : j_object.items())
22438 {
22439 std::cout << "key: " << key << ", value:" << val << '\n';
22440 }
22441 @endcode
22442
22443 @note When iterating over an array, `key()` will return the index of the
22444 element as string (see example). For primitive types (e.g., numbers),
22445 `key()` returns an empty string.
22446
22447 @warning Using `items()` on temporary objects is dangerous. Make sure the
22448 object's lifetime exeeds the iteration. See
22449 <https://github.com/nlohmann/json/issues/2040> for more
22450 information.
22451
22452 @return iteration proxy object wrapping @a ref with an interface to use in
22453 range-based for loops
22454
22455 @liveexample{The following code shows how the function is used.,items}
22456
22457 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
22458 changes in the JSON value.
22459
22460 @complexity Constant.
22461
22462 @since version 3.1.0, structured bindings support since 3.5.0.
22463 */
22464 iteration_proxy<iterator> items() noexcept
22465 {
22466 return iteration_proxy<iterator>(*this);
22467 }
22468
22469 /*!
22470 @copydoc items()
22471 */
22472 iteration_proxy<const_iterator> items() const noexcept
22473 {
22474 return iteration_proxy<const_iterator>(*this);
22475 }
22476
22477 /// @}
22478
22479
22480 //////////////
22481 // capacity //
22482 //////////////
22483
22484 /// @name capacity
22485 /// @{
22486
22487 /*!
22488 @brief checks whether the container is empty.
22489
22490 Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
22491
22492 @return The return value depends on the different types and is
22493 defined as follows:
22494 Value type | return value
22495 ----------- | -------------
22496 null | `true`
22497 boolean | `false`
22498 string | `false`
22499 number | `false`
22500 binary | `false`
22501 object | result of function `object_t::empty()`
22502 array | result of function `array_t::empty()`
22503
22504 @liveexample{The following code uses `empty()` to check if a JSON
22505 object contains any elements.,empty}
22506
22507 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22508 the Container concept; that is, their `empty()` functions have constant
22509 complexity.
22510
22511 @iterators No changes.
22512
22513 @exceptionsafety No-throw guarantee: this function never throws exceptions.
22514
22515 @note This function does not return whether a string stored as JSON value
22516 is empty - it returns whether the JSON container itself is empty which is
22517 false in the case of a string.
22518
22519 @requirement This function helps `basic_json` satisfying the
22520 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22521 requirements:
22522 - The complexity is constant.
22523 - Has the semantics of `begin() == end()`.
22524
22525 @sa see @ref size() -- returns the number of elements
22526
22527 @since version 1.0.0
22528 */
22529 bool empty() const noexcept
22530 {
22531 switch (m_type)
22532 {
22533 case value_t::null:
22534 {
22535 // null values are empty
22536 return true;
22537 }
22538
22539 case value_t::array:
22540 {
22541 // delegate call to array_t::empty()
22542 return m_value.array->empty();
22543 }
22544
22545 case value_t::object:
22546 {
22547 // delegate call to object_t::empty()
22548 return m_value.object->empty();
22549 }
22550
22551 case value_t::string:
22552 case value_t::boolean:
22553 case value_t::number_integer:
22555 case value_t::number_float:
22556 case value_t::binary:
22557 case value_t::discarded:
22558 default:
22559 {
22560 // all other types are nonempty
22561 return false;
22562 }
22563 }
22564 }
22565
22566 /*!
22567 @brief returns the number of elements
22568
22569 Returns the number of elements in a JSON value.
22570
22571 @return The return value depends on the different types and is
22572 defined as follows:
22573 Value type | return value
22574 ----------- | -------------
22575 null | `0`
22576 boolean | `1`
22577 string | `1`
22578 number | `1`
22579 binary | `1`
22580 object | result of function object_t::size()
22581 array | result of function array_t::size()
22582
22583 @liveexample{The following code calls `size()` on the different value
22584 types.,size}
22585
22586 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22587 the Container concept; that is, their size() functions have constant
22588 complexity.
22589
22590 @iterators No changes.
22591
22592 @exceptionsafety No-throw guarantee: this function never throws exceptions.
22593
22594 @note This function does not return the length of a string stored as JSON
22595 value - it returns the number of elements in the JSON value which is 1 in
22596 the case of a string.
22597
22598 @requirement This function helps `basic_json` satisfying the
22599 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22600 requirements:
22601 - The complexity is constant.
22602 - Has the semantics of `std::distance(begin(), end())`.
22603
22604 @sa see @ref empty() -- checks whether the container is empty
22605 @sa see @ref max_size() -- returns the maximal number of elements
22606
22607 @since version 1.0.0
22608 */
22609 size_type size() const noexcept
22610 {
22611 switch (m_type)
22612 {
22613 case value_t::null:
22614 {
22615 // null values are empty
22616 return 0;
22617 }
22618
22619 case value_t::array:
22620 {
22621 // delegate call to array_t::size()
22622 return m_value.array->size();
22623 }
22624
22625 case value_t::object:
22626 {
22627 // delegate call to object_t::size()
22628 return m_value.object->size();
22629 }
22630
22631 case value_t::string:
22632 case value_t::boolean:
22633 case value_t::number_integer:
22635 case value_t::number_float:
22636 case value_t::binary:
22637 case value_t::discarded:
22638 default:
22639 {
22640 // all other types have size 1
22641 return 1;
22642 }
22643 }
22644 }
22645
22646 /*!
22647 @brief returns the maximum possible number of elements
22648
22649 Returns the maximum number of elements a JSON value is able to hold due to
22650 system or library implementation limitations, i.e. `std::distance(begin(),
22651 end())` for the JSON value.
22652
22653 @return The return value depends on the different types and is
22654 defined as follows:
22655 Value type | return value
22656 ----------- | -------------
22657 null | `0` (same as `size()`)
22658 boolean | `1` (same as `size()`)
22659 string | `1` (same as `size()`)
22660 number | `1` (same as `size()`)
22661 binary | `1` (same as `size()`)
22662 object | result of function `object_t::max_size()`
22663 array | result of function `array_t::max_size()`
22664
22665 @liveexample{The following code calls `max_size()` on the different value
22666 types. Note the output is implementation specific.,max_size}
22667
22668 @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22669 the Container concept; that is, their `max_size()` functions have constant
22670 complexity.
22671
22672 @iterators No changes.
22673
22674 @exceptionsafety No-throw guarantee: this function never throws exceptions.
22675
22676 @requirement This function helps `basic_json` satisfying the
22677 [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22678 requirements:
22679 - The complexity is constant.
22680 - Has the semantics of returning `b.size()` where `b` is the largest
22681 possible JSON value.
22682
22683 @sa see @ref size() -- returns the number of elements
22684
22685 @since version 1.0.0
22686 */
22687 size_type max_size() const noexcept
22688 {
22689 switch (m_type)
22690 {
22691 case value_t::array:
22692 {
22693 // delegate call to array_t::max_size()
22694 return m_value.array->max_size();
22695 }
22696
22697 case value_t::object:
22698 {
22699 // delegate call to object_t::max_size()
22700 return m_value.object->max_size();
22701 }
22702
22703 case value_t::null:
22704 case value_t::string:
22705 case value_t::boolean:
22706 case value_t::number_integer:
22708 case value_t::number_float:
22709 case value_t::binary:
22710 case value_t::discarded:
22711 default:
22712 {
22713 // all other types have max_size() == size()
22714 return size();
22715 }
22716 }
22717 }
22718
22719 /// @}
22720
22721
22722 ///////////////
22723 // modifiers //
22724 ///////////////
22725
22726 /// @name modifiers
22727 /// @{
22728
22729 /*!
22730 @brief clears the contents
22731
22732 Clears the content of a JSON value and resets it to the default value as
22733 if @ref basic_json(value_t) would have been called with the current value
22734 type from @ref type():
22735
22736 Value type | initial value
22737 ----------- | -------------
22738 null | `null`
22739 boolean | `false`
22740 string | `""`
22741 number | `0`
22742 binary | An empty byte vector
22743 object | `{}`
22744 array | `[]`
22745
22746 @post Has the same effect as calling
22747 @code {.cpp}
22748 *this = basic_json(type());
22749 @endcode
22750
22751 @liveexample{The example below shows the effect of `clear()` to different
22752 JSON types.,clear}
22753
22754 @complexity Linear in the size of the JSON value.
22755
22756 @iterators All iterators, pointers and references related to this container
22757 are invalidated.
22758
22759 @exceptionsafety No-throw guarantee: this function never throws exceptions.
22760
22761 @sa see @ref basic_json(value_t) -- constructor that creates an object with the
22762 same value than calling `clear()`
22763
22764 @since version 1.0.0
22765 */
22766 void clear() noexcept
22767 {
22768 switch (m_type)
22769 {
22770 case value_t::number_integer:
22771 {
22773 break;
22774 }
22775
22777 {
22779 break;
22780 }
22781
22782 case value_t::number_float:
22783 {
22784 m_value.number_float = 0.0;
22785 break;
22786 }
22787
22788 case value_t::boolean:
22789 {
22790 m_value.boolean = false;
22791 break;
22792 }
22793
22794 case value_t::string:
22795 {
22796 m_value.string->clear();
22797 break;
22798 }
22799
22800 case value_t::binary:
22801 {
22802 m_value.binary->clear();
22803 break;
22804 }
22805
22806 case value_t::array:
22807 {
22808 m_value.array->clear();
22809 break;
22810 }
22811
22812 case value_t::object:
22813 {
22814 m_value.object->clear();
22815 break;
22816 }
22817
22818 case value_t::null:
22819 case value_t::discarded:
22820 default:
22821 break;
22822 }
22823 }
22824
22825 /*!
22826 @brief add an object to an array
22827
22828 Appends the given element @a val to the end of the JSON value. If the
22829 function is called on a JSON null value, an empty array is created before
22830 appending @a val.
22831
22832 @param[in] val the value to add to the JSON array
22833
22834 @throw type_error.308 when called on a type other than JSON array or
22835 null; example: `"cannot use push_back() with number"`
22836
22837 @complexity Amortized constant.
22838
22839 @liveexample{The example shows how `push_back()` and `+=` can be used to
22840 add elements to a JSON array. Note how the `null` value was silently
22841 converted to a JSON array.,push_back}
22842
22843 @since version 1.0.0
22844 */
22845 void push_back(basic_json&& val)
22846 {
22847 // push_back only works for null objects or arrays
22848 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22849 {
22850 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22851 }
22852
22853 // transform null object into an array
22854 if (is_null())
22855 {
22856 m_type = value_t::array;
22859 }
22860
22861 // add element to array (move semantics)
22862 const auto old_capacity = m_value.array->capacity();
22865 // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
22866 }
22867
22868 /*!
22869 @brief add an object to an array
22870 @copydoc push_back(basic_json&&)
22871 */
22872 reference operator+=(basic_json&& val)
22873 {
22874 push_back(std::move(val));
22875 return *this;
22876 }
22877
22878 /*!
22879 @brief add an object to an array
22880 @copydoc push_back(basic_json&&)
22881 */
22882 void push_back(const basic_json& val)
22883 {
22884 // push_back only works for null objects or arrays
22885 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22886 {
22887 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22888 }
22889
22890 // transform null object into an array
22891 if (is_null())
22892 {
22893 m_type = value_t::array;
22896 }
22897
22898 // add element to array
22899 const auto old_capacity = m_value.array->capacity();
22902 }
22903
22904 /*!
22905 @brief add an object to an array
22906 @copydoc push_back(basic_json&&)
22907 */
22908 reference operator+=(const basic_json& val)
22909 {
22910 push_back(val);
22911 return *this;
22912 }
22913
22914 /*!
22915 @brief add an object to an object
22916
22917 Inserts the given element @a val to the JSON object. If the function is
22918 called on a JSON null value, an empty object is created before inserting
22919 @a val.
22920
22921 @param[in] val the value to add to the JSON object
22922
22923 @throw type_error.308 when called on a type other than JSON object or
22924 null; example: `"cannot use push_back() with number"`
22925
22926 @complexity Logarithmic in the size of the container, O(log(`size()`)).
22927
22928 @liveexample{The example shows how `push_back()` and `+=` can be used to
22929 add elements to a JSON object. Note how the `null` value was silently
22930 converted to a JSON object.,push_back__object_t__value}
22931
22932 @since version 1.0.0
22933 */
22934 void push_back(const typename object_t::value_type& val)
22935 {
22936 // push_back only works for null objects or objects
22937 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22938 {
22939 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22940 }
22941
22942 // transform null object into an object
22943 if (is_null())
22944 {
22948 }
22949
22950 // add element to object
22951 auto res = m_value.object->insert(val);
22953 }
22954
22955 /*!
22956 @brief add an object to an object
22957 @copydoc push_back(const typename object_t::value_type&)
22958 */
22959 reference operator+=(const typename object_t::value_type& val)
22960 {
22961 push_back(val);
22962 return *this;
22963 }
22964
22965 /*!
22966 @brief add an object to an object
22967
22968 This function allows to use `push_back` with an initializer list. In case
22969
22970 1. the current value is an object,
22971 2. the initializer list @a init contains only two elements, and
22972 3. the first element of @a init is a string,
22973
22974 @a init is converted into an object element and added using
22975 @ref push_back(const typename object_t::value_type&). Otherwise, @a init
22976 is converted to a JSON value and added using @ref push_back(basic_json&&).
22977
22978 @param[in] init an initializer list
22979
22980 @complexity Linear in the size of the initializer list @a init.
22981
22982 @note This function is required to resolve an ambiguous overload error,
22983 because pairs like `{"key", "value"}` can be both interpreted as
22984 `object_t::value_type` or `std::initializer_list<basic_json>`, see
22985 https://github.com/nlohmann/json/issues/235 for more information.
22986
22987 @liveexample{The example shows how initializer lists are treated as
22988 objects when possible.,push_back__initializer_list}
22989 */
22990 void push_back(initializer_list_t init)
22991 {
22992 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22993 {
22995 push_back(typename object_t::value_type(
22996 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22997 }
22998 else
22999 {
23001 }
23002 }
23003
23004 /*!
23005 @brief add an object to an object
23006 @copydoc push_back(initializer_list_t)
23007 */
23008 reference operator+=(initializer_list_t init)
23009 {
23010 push_back(init);
23011 return *this;
23012 }
23013
23014 /*!
23015 @brief add an object to an array
23016
23017 Creates a JSON value from the passed parameters @a args to the end of the
23018 JSON value. If the function is called on a JSON null value, an empty array
23019 is created before appending the value created from @a args.
23020
23021 @param[in] args arguments to forward to a constructor of @ref basic_json
23022 @tparam Args compatible types to create a @ref basic_json object
23023
23024 @return reference to the inserted element
23025
23026 @throw type_error.311 when called on a type other than JSON array or
23027 null; example: `"cannot use emplace_back() with number"`
23028
23029 @complexity Amortized constant.
23030
23031 @liveexample{The example shows how `push_back()` can be used to add
23032 elements to a JSON array. Note how the `null` value was silently converted
23033 to a JSON array.,emplace_back}
23034
23035 @since version 2.0.8, returns reference since 3.7.0
23036 */
23037 template<class... Args>
23038 reference emplace_back(Args&& ... args)
23039 {
23040 // emplace_back only works for null objects or arrays
23041 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23042 {
23043 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
23044 }
23045
23046 // transform null object into an array
23047 if (is_null())
23048 {
23049 m_type = value_t::array;
23052 }
23053
23054 // add element to array (perfect forwarding)
23055 const auto old_capacity = m_value.array->capacity();
23058 }
23059
23060 /*!
23061 @brief add an object to an object if key does not exist
23062
23063 Inserts a new element into a JSON object constructed in-place with the
23064 given @a args if there is no element with the key in the container. If the
23065 function is called on a JSON null value, an empty object is created before
23066 appending the value created from @a args.
23067
23068 @param[in] args arguments to forward to a constructor of @ref basic_json
23069 @tparam Args compatible types to create a @ref basic_json object
23070
23071 @return a pair consisting of an iterator to the inserted element, or the
23072 already-existing element if no insertion happened, and a bool
23073 denoting whether the insertion took place.
23074
23075 @throw type_error.311 when called on a type other than JSON object or
23076 null; example: `"cannot use emplace() with number"`
23077
23078 @complexity Logarithmic in the size of the container, O(log(`size()`)).
23079
23080 @liveexample{The example shows how `emplace()` can be used to add elements
23081 to a JSON object. Note how the `null` value was silently converted to a
23082 JSON object. Further note how no value is added if there was already one
23083 value stored with the same key.,emplace}
23084
23085 @since version 2.0.8
23086 */
23087 template<class... Args>
23088 std::pair<iterator, bool> emplace(Args&& ... args)
23089 {
23090 // emplace only works for null objects or arrays
23091 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23092 {
23093 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
23094 }
23095
23096 // transform null object into an object
23097 if (is_null())
23098 {
23102 }
23103
23104 // add element to array (perfect forwarding)
23105 auto res = m_value.object->emplace(std::forward<Args>(args)...);
23107
23108 // create result iterator and set iterator to the result of emplace
23109 auto it = begin();
23111
23112 // return pair of iterator and boolean
23113 return { it, res.second };
23114 }
23115
23116 /// Helper for insertion of an iterator
23117 /// @note: This uses std::distance to support GCC 4.8,
23118 /// see https://github.com/nlohmann/json/pull/1257
23119 template<typename... Args>
23120 iterator insert_iterator(const_iterator pos, Args&& ... args)
23121 {
23122 iterator result(this);
23123 JSON_ASSERT(m_value.array != nullptr);
23124
23128
23129 // This could have been written as:
23130 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
23131 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
23132
23133 set_parents();
23134 return result;
23135 }
23136
23137 /*!
23138 @brief inserts element
23139
23140 Inserts element @a val before iterator @a pos.
23141
23142 @param[in] pos iterator before which the content will be inserted; may be
23143 the end() iterator
23144 @param[in] val element to insert
23145 @return iterator pointing to the inserted @a val.
23146
23147 @throw type_error.309 if called on JSON values other than arrays;
23148 example: `"cannot use insert() with string"`
23149 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23150 example: `"iterator does not fit current value"`
23151
23152 @complexity Constant plus linear in the distance between @a pos and end of
23153 the container.
23154
23155 @liveexample{The example shows how `insert()` is used.,insert}
23156
23157 @since version 1.0.0
23158 */
23159 iterator insert(const_iterator pos, const basic_json& val)
23160 {
23161 // insert only works for arrays
23163 {
23164 // check if iterator pos fits to this JSON value
23165 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23166 {
23167 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23168 }
23169
23170 // insert to array and return iterator
23171 return insert_iterator(pos, val);
23172 }
23173
23174 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23175 }
23176
23177 /*!
23178 @brief inserts element
23179 @copydoc insert(const_iterator, const basic_json&)
23180 */
23181 iterator insert(const_iterator pos, basic_json&& val)
23182 {
23183 return insert(pos, val);
23184 }
23185
23186 /*!
23187 @brief inserts elements
23188
23189 Inserts @a cnt copies of @a val before iterator @a pos.
23190
23191 @param[in] pos iterator before which the content will be inserted; may be
23192 the end() iterator
23193 @param[in] cnt number of copies of @a val to insert
23194 @param[in] val element to insert
23195 @return iterator pointing to the first element inserted, or @a pos if
23196 `cnt==0`
23197
23198 @throw type_error.309 if called on JSON values other than arrays; example:
23199 `"cannot use insert() with string"`
23200 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23201 example: `"iterator does not fit current value"`
23202
23203 @complexity Linear in @a cnt plus linear in the distance between @a pos
23204 and end of the container.
23205
23206 @liveexample{The example shows how `insert()` is used.,insert__count}
23207
23208 @since version 1.0.0
23209 */
23210 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
23211 {
23212 // insert only works for arrays
23214 {
23215 // check if iterator pos fits to this JSON value
23216 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23217 {
23218 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23219 }
23220
23221 // insert to array and return iterator
23222 return insert_iterator(pos, cnt, val);
23223 }
23224
23225 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23226 }
23227
23228 /*!
23229 @brief inserts elements
23230
23231 Inserts elements from range `[first, last)` before iterator @a pos.
23232
23233 @param[in] pos iterator before which the content will be inserted; may be
23234 the end() iterator
23235 @param[in] first begin of the range of elements to insert
23236 @param[in] last end of the range of elements to insert
23237
23238 @throw type_error.309 if called on JSON values other than arrays; example:
23239 `"cannot use insert() with string"`
23240 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23241 example: `"iterator does not fit current value"`
23242 @throw invalid_iterator.210 if @a first and @a last do not belong to the
23243 same JSON value; example: `"iterators do not fit"`
23244 @throw invalid_iterator.211 if @a first or @a last are iterators into
23245 container for which insert is called; example: `"passed iterators may not
23246 belong to container"`
23247
23248 @return iterator pointing to the first element inserted, or @a pos if
23249 `first==last`
23250
23251 @complexity Linear in `std::distance(first, last)` plus linear in the
23252 distance between @a pos and end of the container.
23253
23254 @liveexample{The example shows how `insert()` is used.,insert__range}
23255
23256 @since version 1.0.0
23257 */
23258 iterator insert(const_iterator pos, const_iterator first, const_iterator last)
23259 {
23260 // insert only works for arrays
23262 {
23263 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23264 }
23265
23266 // check if iterator pos fits to this JSON value
23267 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23268 {
23269 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23270 }
23271
23272 // check if range iterators belong to the same JSON object
23274 {
23275 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23276 }
23277
23278 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
23279 {
23280 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
23281 }
23282
23283 // insert to array and return iterator
23285 }
23286
23287 /*!
23288 @brief inserts elements
23289
23290 Inserts elements from initializer list @a ilist before iterator @a pos.
23291
23292 @param[in] pos iterator before which the content will be inserted; may be
23293 the end() iterator
23294 @param[in] ilist initializer list to insert the values from
23295
23296 @throw type_error.309 if called on JSON values other than arrays; example:
23297 `"cannot use insert() with string"`
23298 @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23299 example: `"iterator does not fit current value"`
23300
23301 @return iterator pointing to the first element inserted, or @a pos if
23302 `ilist` is empty
23303
23304 @complexity Linear in `ilist.size()` plus linear in the distance between
23305 @a pos and end of the container.
23306
23307 @liveexample{The example shows how `insert()` is used.,insert__ilist}
23308
23309 @since version 1.0.0
23310 */
23311 iterator insert(const_iterator pos, initializer_list_t ilist)
23312 {
23313 // insert only works for arrays
23315 {
23316 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23317 }
23318
23319 // check if iterator pos fits to this JSON value
23320 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23321 {
23322 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23323 }
23324
23325 // insert to array and return iterator
23326 return insert_iterator(pos, ilist.begin(), ilist.end());
23327 }
23328
23329 /*!
23330 @brief inserts elements
23331
23332 Inserts elements from range `[first, last)`.
23333
23334 @param[in] first begin of the range of elements to insert
23335 @param[in] last end of the range of elements to insert
23336
23337 @throw type_error.309 if called on JSON values other than objects; example:
23338 `"cannot use insert() with string"`
23339 @throw invalid_iterator.202 if iterator @a first or @a last does does not
23340 point to an object; example: `"iterators first and last must point to
23341 objects"`
23342 @throw invalid_iterator.210 if @a first and @a last do not belong to the
23343 same JSON value; example: `"iterators do not fit"`
23344
23345 @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
23346 of elements to insert.
23347
23348 @liveexample{The example shows how `insert()` is used.,insert__range_object}
23349
23350 @since version 3.0.0
23351 */
23352 void insert(const_iterator first, const_iterator last)
23353 {
23354 // insert only works for objects
23356 {
23357 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23358 }
23359
23360 // check if range iterators belong to the same JSON object
23362 {
23363 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23364 }
23365
23366 // passed iterators must belong to objects
23368 {
23369 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23370 }
23371
23373 }
23374
23375 /*!
23376 @brief updates a JSON object from another object, overwriting existing keys
23377
23378 Inserts all values from JSON object @a j and overwrites existing keys.
23379
23380 @param[in] j JSON object to read values from
23381
23382 @throw type_error.312 if called on JSON values other than objects; example:
23383 `"cannot use update() with string"`
23384
23385 @complexity O(N*log(size() + N)), where N is the number of elements to
23386 insert.
23387
23388 @liveexample{The example shows how `update()` is used.,update}
23389
23390 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
23391
23392 @since version 3.0.0
23393 */
23394 void update(const_reference j)
23395 {
23396 // implicitly convert null value to an empty object
23397 if (is_null())
23398 {
23402 }
23403
23405 {
23406 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23407 }
23409 {
23410 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
23411 }
23412
23413 for (auto it = j.cbegin(); it != j.cend(); ++it)
23414 {
23415 m_value.object->operator[](it.key()) = it.value();
23416 }
23417 }
23418
23419 /*!
23420 @brief updates a JSON object from another object, overwriting existing keys
23421
23422 Inserts all values from from range `[first, last)` and overwrites existing
23423 keys.
23424
23425 @param[in] first begin of the range of elements to insert
23426 @param[in] last end of the range of elements to insert
23427
23428 @throw type_error.312 if called on JSON values other than objects; example:
23429 `"cannot use update() with string"`
23430 @throw invalid_iterator.202 if iterator @a first or @a last does does not
23431 point to an object; example: `"iterators first and last must point to
23432 objects"`
23433 @throw invalid_iterator.210 if @a first and @a last do not belong to the
23434 same JSON value; example: `"iterators do not fit"`
23435
23436 @complexity O(N*log(size() + N)), where N is the number of elements to
23437 insert.
23438
23439 @liveexample{The example shows how `update()` is used__range.,update}
23440
23441 @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
23442
23443 @since version 3.0.0
23444 */
23445 void update(const_iterator first, const_iterator last)
23446 {
23447 // implicitly convert null value to an empty object
23448 if (is_null())
23449 {
23453 }
23454
23456 {
23457 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23458 }
23459
23460 // check if range iterators belong to the same JSON object
23462 {
23463 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23464 }
23465
23466 // passed iterators must belong to objects
23468 || !last.m_object->is_object()))
23469 {
23470 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23471 }
23472
23473 for (auto it = first; it != last; ++it)
23474 {
23475 m_value.object->operator[](it.key()) = it.value();
23476 }
23477 }
23478
23479 /*!
23480 @brief exchanges the values
23481
23482 Exchanges the contents of the JSON value with those of @a other. Does not
23483 invoke any move, copy, or swap operations on individual elements. All
23484 iterators and references remain valid. The past-the-end iterator is
23485 invalidated.
23486
23487 @param[in,out] other JSON value to exchange the contents with
23488
23489 @complexity Constant.
23490
23491 @liveexample{The example below shows how JSON values can be swapped with
23492 `swap()`.,swap__reference}
23493
23494 @since version 1.0.0
23495 */
23496 void swap(reference other) noexcept (
23497 std::is_nothrow_move_constructible<value_t>::value&&
23498 std::is_nothrow_move_assignable<value_t>::value&&
23499 std::is_nothrow_move_constructible<json_value>::value&&
23500 std::is_nothrow_move_assignable<json_value>::value
23501 )
23502 {
23505
23506 set_parents();
23509 }
23510
23511 /*!
23512 @brief exchanges the values
23513
23514 Exchanges the contents of the JSON value from @a left with those of @a right. Does not
23515 invoke any move, copy, or swap operations on individual elements. All
23516 iterators and references remain valid. The past-the-end iterator is
23517 invalidated. implemented as a friend function callable via ADL.
23518
23519 @param[in,out] left JSON value to exchange the contents with
23520 @param[in,out] right JSON value to exchange the contents with
23521
23522 @complexity Constant.
23523
23524 @liveexample{The example below shows how JSON values can be swapped with
23525 `swap()`.,swap__reference}
23526
23527 @since version 1.0.0
23528 */
23529 friend void swap(reference left, reference right) noexcept (
23534 )
23535 {
23536 left.swap(right);
23537 }
23538
23539 /*!
23540 @brief exchanges the values
23541
23542 Exchanges the contents of a JSON array with those of @a other. Does not
23543 invoke any move, copy, or swap operations on individual elements. All
23544 iterators and references remain valid. The past-the-end iterator is
23545 invalidated.
23546
23547 @param[in,out] other array to exchange the contents with
23548
23549 @throw type_error.310 when JSON value is not an array; example: `"cannot
23550 use swap() with string"`
23551
23552 @complexity Constant.
23553
23554 @liveexample{The example below shows how arrays can be swapped with
23555 `swap()`.,swap__array_t}
23556
23557 @since version 1.0.0
23558 */
23559 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
23560 {
23561 // swap only works for arrays
23563 {
23564 std::swap(*(m_value.array), other);
23565 }
23566 else
23567 {
23568 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23569 }
23570 }
23571
23572 /*!
23573 @brief exchanges the values
23574
23575 Exchanges the contents of a JSON object with those of @a other. Does not
23576 invoke any move, copy, or swap operations on individual elements. All
23577 iterators and references remain valid. The past-the-end iterator is
23578 invalidated.
23579
23580 @param[in,out] other object to exchange the contents with
23581
23582 @throw type_error.310 when JSON value is not an object; example:
23583 `"cannot use swap() with string"`
23584
23585 @complexity Constant.
23586
23587 @liveexample{The example below shows how objects can be swapped with
23588 `swap()`.,swap__object_t}
23589
23590 @since version 1.0.0
23591 */
23592 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
23593 {
23594 // swap only works for objects
23596 {
23597 std::swap(*(m_value.object), other);
23598 }
23599 else
23600 {
23601 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23602 }
23603 }
23604
23605 /*!
23606 @brief exchanges the values
23607
23608 Exchanges the contents of a JSON string with those of @a other. Does not
23609 invoke any move, copy, or swap operations on individual elements. All
23610 iterators and references remain valid. The past-the-end iterator is
23611 invalidated.
23612
23613 @param[in,out] other string to exchange the contents with
23614
23615 @throw type_error.310 when JSON value is not a string; example: `"cannot
23616 use swap() with boolean"`
23617
23618 @complexity Constant.
23619
23620 @liveexample{The example below shows how strings can be swapped with
23621 `swap()`.,swap__string_t}
23622
23623 @since version 1.0.0
23624 */
23625 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
23626 {
23627 // swap only works for strings
23629 {
23630 std::swap(*(m_value.string), other);
23631 }
23632 else
23633 {
23634 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23635 }
23636 }
23637
23638 /*!
23639 @brief exchanges the values
23640
23641 Exchanges the contents of a JSON string with those of @a other. Does not
23642 invoke any move, copy, or swap operations on individual elements. All
23643 iterators and references remain valid. The past-the-end iterator is
23644 invalidated.
23645
23646 @param[in,out] other binary to exchange the contents with
23647
23648 @throw type_error.310 when JSON value is not a string; example: `"cannot
23649 use swap() with boolean"`
23650
23651 @complexity Constant.
23652
23653 @liveexample{The example below shows how strings can be swapped with
23654 `swap()`.,swap__binary_t}
23655
23656 @since version 3.8.0
23657 */
23658 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
23659 {
23660 // swap only works for strings
23662 {
23663 std::swap(*(m_value.binary), other);
23664 }
23665 else
23666 {
23667 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23668 }
23669 }
23670
23671 /// @copydoc swap(binary_t&)
23672 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
23673 {
23674 // swap only works for strings
23676 {
23677 std::swap(*(m_value.binary), other);
23678 }
23679 else
23680 {
23681 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23682 }
23683 }
23684
23685 /// @}
23686
23687 public:
23688 //////////////////////////////////////////
23689 // lexicographical comparison operators //
23690 //////////////////////////////////////////
23691
23692 /// @name lexicographical comparison operators
23693 /// @{
23694
23695 /*!
23696 @brief comparison: equal
23697
23698 Compares two JSON values for equality according to the following rules:
23699 - Two JSON values are equal if (1) they are from the same type and (2)
23700 their stored values are the same according to their respective
23701 `operator==`.
23702 - Integer and floating-point numbers are automatically converted before
23703 comparison. Note that two NaN values are always treated as unequal.
23704 - Two JSON null values are equal.
23705
23706 @note Floating-point inside JSON values numbers are compared with
23707 `json::number_float_t::operator==` which is `double::operator==` by
23708 default. To compare floating-point while respecting an epsilon, an alternative
23709 [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39)
23710 could be used, for instance
23711 @code {.cpp}
23712 template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
23713 inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
23714 {
23715 return std::abs(a - b) <= epsilon;
23716 }
23717 @endcode
23718 Or you can self-defined operator equal function like this:
23719 @code {.cpp}
23720 bool my_equal(const_reference lhs, const_reference rhs) {
23721 const auto lhs_type lhs.type();
23722 const auto rhs_type rhs.type();
23723 if (lhs_type == rhs_type) {
23724 switch(lhs_type)
23725 // self_defined case
23726 case value_t::number_float:
23727 return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();
23728 // other cases remain the same with the original
23729 ...
23730 }
23731 ...
23732 }
23733 @endcode
23734
23735 @note NaN values never compare equal to themselves or to other NaN values.
23736
23737 @param[in] lhs first JSON value to consider
23738 @param[in] rhs second JSON value to consider
23739 @return whether the values @a lhs and @a rhs are equal
23740
23741 @exceptionsafety No-throw guarantee: this function never throws exceptions.
23742
23743 @complexity Linear.
23744
23745 @liveexample{The example demonstrates comparing several JSON
23746 types.,operator__equal}
23747
23748 @since version 1.0.0
23749 */
23750 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23751 {
23752#ifdef __GNUC__
23753#pragma GCC diagnostic push
23754#pragma GCC diagnostic ignored "-Wfloat-equal"
23755#endif
23756 const auto lhs_type = lhs.type();
23757 const auto rhs_type = rhs.type();
23758
23759 if (lhs_type == rhs_type)
23760 {
23761 switch (lhs_type)
23762 {
23763 case value_t::array:
23764 return *lhs.m_value.array == *rhs.m_value.array;
23765
23766 case value_t::object:
23767 return *lhs.m_value.object == *rhs.m_value.object;
23768
23769 case value_t::null:
23770 return true;
23771
23772 case value_t::string:
23773 return *lhs.m_value.string == *rhs.m_value.string;
23774
23775 case value_t::boolean:
23777
23778 case value_t::number_integer:
23780
23783
23784 case value_t::number_float:
23786
23787 case value_t::binary:
23788 return *lhs.m_value.binary == *rhs.m_value.binary;
23789
23790 case value_t::discarded:
23791 default:
23792 return false;
23793 }
23794 }
23796 {
23798 }
23800 {
23802 }
23804 {
23806 }
23808 {
23810 }
23812 {
23814 }
23816 {
23818 }
23819
23820 return false;
23821#ifdef __GNUC__
23822#pragma GCC diagnostic pop
23823#endif
23824 }
23825
23826 /*!
23827 @brief comparison: equal
23828 @copydoc operator==(const_reference, const_reference)
23829 */
23830 template<typename ScalarType, typename std::enable_if<
23831 std::is_scalar<ScalarType>::value, int>::type = 0>
23832 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23833 {
23834 return lhs == basic_json(rhs);
23835 }
23836
23837 /*!
23838 @brief comparison: equal
23839 @copydoc operator==(const_reference, const_reference)
23840 */
23841 template<typename ScalarType, typename std::enable_if<
23842 std::is_scalar<ScalarType>::value, int>::type = 0>
23843 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23844 {
23845 return basic_json(lhs) == rhs;
23846 }
23847
23848 /*!
23849 @brief comparison: not equal
23850
23851 Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
23852
23853 @param[in] lhs first JSON value to consider
23854 @param[in] rhs second JSON value to consider
23855 @return whether the values @a lhs and @a rhs are not equal
23856
23857 @complexity Linear.
23858
23859 @exceptionsafety No-throw guarantee: this function never throws exceptions.
23860
23861 @liveexample{The example demonstrates comparing several JSON
23862 types.,operator__notequal}
23863
23864 @since version 1.0.0
23865 */
23866 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23867 {
23868 return !(lhs == rhs);
23869 }
23870
23871 /*!
23872 @brief comparison: not equal
23873 @copydoc operator!=(const_reference, const_reference)
23874 */
23875 template<typename ScalarType, typename std::enable_if<
23876 std::is_scalar<ScalarType>::value, int>::type = 0>
23877 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23878 {
23879 return lhs != basic_json(rhs);
23880 }
23881
23882 /*!
23883 @brief comparison: not equal
23884 @copydoc operator!=(const_reference, const_reference)
23885 */
23886 template<typename ScalarType, typename std::enable_if<
23887 std::is_scalar<ScalarType>::value, int>::type = 0>
23888 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23889 {
23890 return basic_json(lhs) != rhs;
23891 }
23892
23893 /*!
23894 @brief comparison: less than
23895
23896 Compares whether one JSON value @a lhs is less than another JSON value @a
23897 rhs according to the following rules:
23898 - If @a lhs and @a rhs have the same type, the values are compared using
23899 the default `<` operator.
23900 - Integer and floating-point numbers are automatically converted before
23901 comparison
23902 - In case @a lhs and @a rhs have different types, the values are ignored
23903 and the order of the types is considered, see
23904 @ref operator<(const value_t, const value_t).
23905
23906 @param[in] lhs first JSON value to consider
23907 @param[in] rhs second JSON value to consider
23908 @return whether @a lhs is less than @a rhs
23909
23910 @complexity Linear.
23911
23912 @exceptionsafety No-throw guarantee: this function never throws exceptions.
23913
23914 @liveexample{The example demonstrates comparing several JSON
23915 types.,operator__less}
23916
23917 @since version 1.0.0
23918 */
23919 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23920 {
23921 const auto lhs_type = lhs.type();
23922 const auto rhs_type = rhs.type();
23923
23924 if (lhs_type == rhs_type)
23925 {
23926 switch (lhs_type)
23927 {
23928 case value_t::array:
23929 // note parentheses are necessary, see
23930 // https://github.com/nlohmann/json/issues/1530
23931 return (*lhs.m_value.array) < (*rhs.m_value.array);
23932
23933 case value_t::object:
23934 return (*lhs.m_value.object) < (*rhs.m_value.object);
23935
23936 case value_t::null:
23937 return false;
23938
23939 case value_t::string:
23940 return (*lhs.m_value.string) < (*rhs.m_value.string);
23941
23942 case value_t::boolean:
23943 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
23944
23945 case value_t::number_integer:
23947
23950
23951 case value_t::number_float:
23953
23954 case value_t::binary:
23955 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
23956
23957 case value_t::discarded:
23958 default:
23959 return false;
23960 }
23961 }
23963 {
23965 }
23967 {
23969 }
23971 {
23973 }
23975 {
23977 }
23979 {
23981 }
23983 {
23985 }
23986
23987 // We only reach this line if we cannot compare values. In that case,
23988 // we compare types. Note we have to call the operator explicitly,
23989 // because MSVC has problems otherwise.
23990 return operator<(lhs_type, rhs_type);
23991 }
23992
23993 /*!
23994 @brief comparison: less than
23995 @copydoc operator<(const_reference, const_reference)
23996 */
23997 template<typename ScalarType, typename std::enable_if<
23998 std::is_scalar<ScalarType>::value, int>::type = 0>
23999 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
24000 {
24001 return lhs < basic_json(rhs);
24002 }
24003
24004 /*!
24005 @brief comparison: less than
24006 @copydoc operator<(const_reference, const_reference)
24007 */
24008 template<typename ScalarType, typename std::enable_if<
24009 std::is_scalar<ScalarType>::value, int>::type = 0>
24010 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
24011 {
24012 return basic_json(lhs) < rhs;
24013 }
24014
24015 /*!
24016 @brief comparison: less than or equal
24017
24018 Compares whether one JSON value @a lhs is less than or equal to another
24019 JSON value by calculating `not (rhs < lhs)`.
24020
24021 @param[in] lhs first JSON value to consider
24022 @param[in] rhs second JSON value to consider
24023 @return whether @a lhs is less than or equal to @a rhs
24024
24025 @complexity Linear.
24026
24027 @exceptionsafety No-throw guarantee: this function never throws exceptions.
24028
24029 @liveexample{The example demonstrates comparing several JSON
24030 types.,operator__greater}
24031
24032 @since version 1.0.0
24033 */
24034 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
24035 {
24036 return !(rhs < lhs);
24037 }
24038
24039 /*!
24040 @brief comparison: less than or equal
24041 @copydoc operator<=(const_reference, const_reference)
24042 */
24043 template<typename ScalarType, typename std::enable_if<
24044 std::is_scalar<ScalarType>::value, int>::type = 0>
24045 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
24046 {
24047 return lhs <= basic_json(rhs);
24048 }
24049
24050 /*!
24051 @brief comparison: less than or equal
24052 @copydoc operator<=(const_reference, const_reference)
24053 */
24054 template<typename ScalarType, typename std::enable_if<
24055 std::is_scalar<ScalarType>::value, int>::type = 0>
24056 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
24057 {
24058 return basic_json(lhs) <= rhs;
24059 }
24060
24061 /*!
24062 @brief comparison: greater than
24063
24064 Compares whether one JSON value @a lhs is greater than another
24065 JSON value by calculating `not (lhs <= rhs)`.
24066
24067 @param[in] lhs first JSON value to consider
24068 @param[in] rhs second JSON value to consider
24069 @return whether @a lhs is greater than to @a rhs
24070
24071 @complexity Linear.
24072
24073 @exceptionsafety No-throw guarantee: this function never throws exceptions.
24074
24075 @liveexample{The example demonstrates comparing several JSON
24076 types.,operator__lessequal}
24077
24078 @since version 1.0.0
24079 */
24080 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
24081 {
24082 return !(lhs <= rhs);
24083 }
24084
24085 /*!
24086 @brief comparison: greater than
24087 @copydoc operator>(const_reference, const_reference)
24088 */
24089 template<typename ScalarType, typename std::enable_if<
24090 std::is_scalar<ScalarType>::value, int>::type = 0>
24091 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
24092 {
24093 return lhs > basic_json(rhs);
24094 }
24095
24096 /*!
24097 @brief comparison: greater than
24098 @copydoc operator>(const_reference, const_reference)
24099 */
24100 template<typename ScalarType, typename std::enable_if<
24101 std::is_scalar<ScalarType>::value, int>::type = 0>
24102 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
24103 {
24104 return basic_json(lhs) > rhs;
24105 }
24106
24107 /*!
24108 @brief comparison: greater than or equal
24109
24110 Compares whether one JSON value @a lhs is greater than or equal to another
24111 JSON value by calculating `not (lhs < rhs)`.
24112
24113 @param[in] lhs first JSON value to consider
24114 @param[in] rhs second JSON value to consider
24115 @return whether @a lhs is greater than or equal to @a rhs
24116
24117 @complexity Linear.
24118
24119 @exceptionsafety No-throw guarantee: this function never throws exceptions.
24120
24121 @liveexample{The example demonstrates comparing several JSON
24122 types.,operator__greaterequal}
24123
24124 @since version 1.0.0
24125 */
24126 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
24127 {
24128 return !(lhs < rhs);
24129 }
24130
24131 /*!
24132 @brief comparison: greater than or equal
24133 @copydoc operator>=(const_reference, const_reference)
24134 */
24135 template<typename ScalarType, typename std::enable_if<
24136 std::is_scalar<ScalarType>::value, int>::type = 0>
24137 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
24138 {
24139 return lhs >= basic_json(rhs);
24140 }
24141
24142 /*!
24143 @brief comparison: greater than or equal
24144 @copydoc operator>=(const_reference, const_reference)
24145 */
24146 template<typename ScalarType, typename std::enable_if<
24147 std::is_scalar<ScalarType>::value, int>::type = 0>
24148 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
24149 {
24150 return basic_json(lhs) >= rhs;
24151 }
24152
24153 /// @}
24154
24155 ///////////////////
24156 // serialization //
24157 ///////////////////
24158
24159 /// @name serialization
24160 /// @{
24161#ifndef JSON_NO_IO
24162 /*!
24163 @brief serialize to stream
24164
24165 Serialize the given JSON value @a j to the output stream @a o. The JSON
24166 value will be serialized using the @ref dump member function.
24167
24168 - The indentation of the output can be controlled with the member variable
24169 `width` of the output stream @a o. For instance, using the manipulator
24170 `std::setw(4)` on @a o sets the indentation level to `4` and the
24171 serialization result is the same as calling `dump(4)`.
24172
24173 - The indentation character can be controlled with the member variable
24174 `fill` of the output stream @a o. For instance, the manipulator
24175 `std::setfill('\\t')` sets indentation to use a tab character rather than
24176 the default space character.
24177
24178 @param[in,out] o stream to serialize to
24179 @param[in] j JSON value to serialize
24180
24181 @return the stream @a o
24182
24183 @throw type_error.316 if a string stored inside the JSON value is not
24184 UTF-8 encoded
24185
24186 @complexity Linear.
24187
24188 @liveexample{The example below shows the serialization with different
24189 parameters to `width` to adjust the indentation level.,operator_serialize}
24190
24191 @since version 1.0.0; indentation character added in version 3.0.0
24192 */
24193 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
24194 {
24195 // read width member and use it as indentation parameter if nonzero
24196 const bool pretty_print = o.width() > 0;
24197 const auto indentation = pretty_print ? o.width() : 0;
24198
24199 // reset width to 0 for subsequent calls to this stream
24200 o.width(0);
24201
24202 // do the actual serialization
24203 serializer s(detail::output_adapter<char>(o), o.fill());
24204 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
24205 return o;
24206 }
24207
24208 /*!
24209 @brief serialize to stream
24210 @deprecated This stream operator is deprecated and will be removed in
24211 future 4.0.0 of the library. Please use
24212 @ref operator<<(std::ostream&, const basic_json&)
24213 instead; that is, replace calls like `j >> o;` with `o << j;`.
24214 @since version 1.0.0; deprecated since version 3.0.0
24215 */
24216 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
24217 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
24218 {
24219 return o << j;
24220 }
24221#endif // JSON_NO_IO
24222 /// @}
24223
24224
24225 /////////////////////
24226 // deserialization //
24227 /////////////////////
24228
24229 /// @name deserialization
24230 /// @{
24231
24232 /*!
24233 @brief deserialize from a compatible input
24234
24235 @tparam InputType A compatible input, for instance
24236 - an std::istream object
24237 - a FILE pointer
24238 - a C-style array of characters
24239 - a pointer to a null-terminated string of single byte characters
24240 - an object obj for which begin(obj) and end(obj) produces a valid pair of
24241 iterators.
24242
24243 @param[in] i input to read from
24244 @param[in] cb a parser callback function of type @ref parser_callback_t
24245 which is used to control the deserialization by filtering unwanted values
24246 (optional)
24247 @param[in] allow_exceptions whether to throw exceptions in case of a
24248 parse error (optional, true by default)
24249 @param[in] ignore_comments whether comments should be ignored and treated
24250 like whitespace (true) or yield a parse error (true); (optional, false by
24251 default)
24252
24253 @return deserialized JSON value; in case of a parse error and
24254 @a allow_exceptions set to `false`, the return value will be
24255 value_t::discarded.
24256
24257 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24258 of input; expected string literal""`
24259 @throw parse_error.102 if to_unicode fails or surrogate error
24260 @throw parse_error.103 if to_unicode fails
24261
24262 @complexity Linear in the length of the input. The parser is a predictive
24263 LL(1) parser. The complexity can be higher if the parser callback function
24264 @a cb or reading from the input @a i has a super-linear complexity.
24265
24266 @note A UTF-8 byte order mark is silently ignored.
24267
24268 @liveexample{The example below demonstrates the `parse()` function reading
24269 from an array.,parse__array__parser_callback_t}
24270
24271 @liveexample{The example below demonstrates the `parse()` function with
24272 and without callback function.,parse__string__parser_callback_t}
24273
24274 @liveexample{The example below demonstrates the `parse()` function with
24275 and without callback function.,parse__istream__parser_callback_t}
24276
24277 @liveexample{The example below demonstrates the `parse()` function reading
24278 from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
24279
24280 @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to
24281 ignore comments.
24282 */
24283 template<typename InputType>
24285 static basic_json parse(InputType&& i,
24286 const parser_callback_t cb = nullptr,
24287 const bool allow_exceptions = true,
24288 const bool ignore_comments = false)
24289 {
24292 return result;
24293 }
24294
24295 /*!
24296 @brief deserialize from a pair of character iterators
24297
24298 The value_type of the iterator must be a integral type with size of 1, 2 or
24299 4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.
24300
24301 @param[in] first iterator to start of character range
24302 @param[in] last iterator to end of character range
24303 @param[in] cb a parser callback function of type @ref parser_callback_t
24304 which is used to control the deserialization by filtering unwanted values
24305 (optional)
24306 @param[in] allow_exceptions whether to throw exceptions in case of a
24307 parse error (optional, true by default)
24308 @param[in] ignore_comments whether comments should be ignored and treated
24309 like whitespace (true) or yield a parse error (true); (optional, false by
24310 default)
24311
24312 @return deserialized JSON value; in case of a parse error and
24313 @a allow_exceptions set to `false`, the return value will be
24314 value_t::discarded.
24315
24316 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24317 of input; expected string literal""`
24318 @throw parse_error.102 if to_unicode fails or surrogate error
24319 @throw parse_error.103 if to_unicode fails
24320 */
24321 template<typename IteratorType>
24323 static basic_json parse(IteratorType first,
24324 IteratorType last,
24325 const parser_callback_t cb = nullptr,
24326 const bool allow_exceptions = true,
24327 const bool ignore_comments = false)
24328 {
24331 return result;
24332 }
24333
24335 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
24336 static basic_json parse(detail::span_input_adapter&& i,
24337 const parser_callback_t cb = nullptr,
24338 const bool allow_exceptions = true,
24339 const bool ignore_comments = false)
24340 {
24343 return result;
24344 }
24345
24346 /*!
24347 @brief check if the input is valid JSON
24348
24349 Unlike the @ref parse(InputType&&, const parser_callback_t,const bool)
24350 function, this function neither throws an exception in case of invalid JSON
24351 input (i.e., a parse error) nor creates diagnostic information.
24352
24353 @tparam InputType A compatible input, for instance
24354 - an std::istream object
24355 - a FILE pointer
24356 - a C-style array of characters
24357 - a pointer to a null-terminated string of single byte characters
24358 - an object obj for which begin(obj) and end(obj) produces a valid pair of
24359 iterators.
24360
24361 @param[in] i input to read from
24362 @param[in] ignore_comments whether comments should be ignored and treated
24363 like whitespace (true) or yield a parse error (true); (optional, false by
24364 default)
24365
24366 @return Whether the input read from @a i is valid JSON.
24367
24368 @complexity Linear in the length of the input. The parser is a predictive
24369 LL(1) parser.
24370
24371 @note A UTF-8 byte order mark is silently ignored.
24372
24373 @liveexample{The example below demonstrates the `accept()` function reading
24374 from a string.,accept__string}
24375 */
24376 template<typename InputType>
24377 static bool accept(InputType&& i,
24378 const bool ignore_comments = false)
24379 {
24380 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
24381 }
24382
24383 template<typename IteratorType>
24384 static bool accept(IteratorType first, IteratorType last,
24385 const bool ignore_comments = false)
24386 {
24387 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
24388 }
24389
24391 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
24392 static bool accept(detail::span_input_adapter&& i,
24393 const bool ignore_comments = false)
24394 {
24395 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
24396 }
24397
24398 /*!
24399 @brief generate SAX events
24400
24401 The SAX event lister must follow the interface of @ref json_sax.
24402
24403 This function reads from a compatible input. Examples are:
24404 - an std::istream object
24405 - a FILE pointer
24406 - a C-style array of characters
24407 - a pointer to a null-terminated string of single byte characters
24408 - an object obj for which begin(obj) and end(obj) produces a valid pair of
24409 iterators.
24410
24411 @param[in] i input to read from
24412 @param[in,out] sax SAX event listener
24413 @param[in] format the format to parse (JSON, CBOR, MessagePack, or UBJSON)
24414 @param[in] strict whether the input has to be consumed completely
24415 @param[in] ignore_comments whether comments should be ignored and treated
24416 like whitespace (true) or yield a parse error (true); (optional, false by
24417 default); only applies to the JSON file format.
24418
24419 @return return value of the last processed SAX event
24420
24421 @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24422 of input; expected string literal""`
24423 @throw parse_error.102 if to_unicode fails or surrogate error
24424 @throw parse_error.103 if to_unicode fails
24425
24426 @complexity Linear in the length of the input. The parser is a predictive
24427 LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
24428 a super-linear complexity.
24429
24430 @note A UTF-8 byte order mark is silently ignored.
24431
24432 @liveexample{The example below demonstrates the `sax_parse()` function
24433 reading from string and processing the events with a user-defined SAX
24434 event consumer.,sax_parse}
24435
24436 @since version 3.2.0
24437 */
24438 template <typename InputType, typename SAX>
24440 static bool sax_parse(InputType&& i, SAX* sax,
24441 input_format_t format = input_format_t::json,
24442 const bool strict = true,
24443 const bool ignore_comments = false)
24444 {
24446 return format == input_format_t::json
24447 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24449 }
24450
24451 template<class IteratorType, class SAX>
24453 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
24454 input_format_t format = input_format_t::json,
24455 const bool strict = true,
24456 const bool ignore_comments = false)
24457 {
24459 return format == input_format_t::json
24460 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24462 }
24463
24464 template <typename SAX>
24465 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
24467 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
24468 input_format_t format = input_format_t::json,
24469 const bool strict = true,
24470 const bool ignore_comments = false)
24471 {
24472 auto ia = i.get();
24473 return format == input_format_t::json
24474 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24475 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24476 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24478 }
24479#ifndef JSON_NO_IO
24480 /*!
24481 @brief deserialize from stream
24482 @deprecated This stream operator is deprecated and will be removed in
24483 version 4.0.0 of the library. Please use
24484 @ref operator>>(std::istream&, basic_json&)
24485 instead; that is, replace calls like `j << i;` with `i >> j;`.
24486 @since version 1.0.0; deprecated since version 3.0.0
24487 */
24488 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
24489 friend std::istream& operator<<(basic_json& j, std::istream& i)
24490 {
24491 return operator>>(i, j);
24492 }
24493
24494 /*!
24495 @brief deserialize from stream
24496
24497 Deserializes an input stream to a JSON value.
24498
24499 @param[in,out] i input stream to read a serialized JSON value from
24500 @param[in,out] j JSON value to write the deserialized input to
24501
24502 @throw parse_error.101 in case of an unexpected token
24503 @throw parse_error.102 if to_unicode fails or surrogate error
24504 @throw parse_error.103 if to_unicode fails
24505
24506 @complexity Linear in the length of the input. The parser is a predictive
24507 LL(1) parser.
24508
24509 @note A UTF-8 byte order mark is silently ignored.
24510
24511 @liveexample{The example below shows how a JSON value is constructed by
24512 reading a serialization from a stream.,operator_deserialize}
24513
24514 @sa parse(std::istream&, const parser_callback_t) for a variant with a
24515 parser callback function to filter values while parsing
24516
24517 @since version 1.0.0
24518 */
24519 friend std::istream& operator>>(std::istream& i, basic_json& j)
24520 {
24521 parser(detail::input_adapter(i)).parse(false, j);
24522 return i;
24523 }
24524#endif // JSON_NO_IO
24525 /// @}
24526
24527 ///////////////////////////
24528 // convenience functions //
24529 ///////////////////////////
24530
24531 /*!
24532 @brief return the type as string
24533
24534 Returns the type name as string to be used in error messages - usually to
24535 indicate that a function was called on a wrong JSON type.
24536
24537 @return a string representation of a the @a m_type member:
24538 Value type | return value
24539 ----------- | -------------
24540 null | `"null"`
24541 boolean | `"boolean"`
24542 string | `"string"`
24543 number | `"number"` (for all number types)
24544 object | `"object"`
24545 array | `"array"`
24546 binary | `"binary"`
24547 discarded | `"discarded"`
24548
24549 @exceptionsafety No-throw guarantee: this function never throws exceptions.
24550
24551 @complexity Constant.
24552
24553 @liveexample{The following code exemplifies `type_name()` for all JSON
24554 types.,type_name}
24555
24556 @sa see @ref type() -- return the type of the JSON value
24557 @sa see @ref operator value_t() -- return the type of the JSON value (implicit)
24558
24559 @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
24560 since 3.0.0
24561 */
24563 const char* type_name() const noexcept
24564 {
24565 {
24566 switch (m_type)
24567 {
24568 case value_t::null:
24569 return "null";
24570 case value_t::object:
24571 return "object";
24572 case value_t::array:
24573 return "array";
24574 case value_t::string:
24575 return "string";
24576 case value_t::boolean:
24577 return "boolean";
24578 case value_t::binary:
24579 return "binary";
24580 case value_t::discarded:
24581 return "discarded";
24582 case value_t::number_integer:
24584 case value_t::number_float:
24585 default:
24586 return "number";
24587 }
24588 }
24589 }
24590
24591
24593 //////////////////////
24594 // member variables //
24595 //////////////////////
24596
24597 /// the type of the current element
24598 value_t m_type = value_t::null;
24599
24600 /// the value of the current element
24601 json_value m_value = {};
24602
24604 /// a pointer to a parent value (for debugging purposes)
24605 basic_json* m_parent = nullptr;
24606#endif
24607
24608 //////////////////////////////////////////
24609 // binary serialization/deserialization //
24610 //////////////////////////////////////////
24611
24612 /// @name binary serialization/deserialization support
24613 /// @{
24614
24615 public:
24616 /*!
24617 @brief create a CBOR serialization of a given JSON value
24618
24619 Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
24620 Binary Object Representation) serialization format. CBOR is a binary
24621 serialization format which aims to be more compact than JSON itself, yet
24622 more efficient to parse.
24623
24624 The library uses the following mapping from JSON values types to
24625 CBOR types according to the CBOR specification (RFC 7049):
24626
24627 JSON value type | value/range | CBOR type | first byte
24628 --------------- | ------------------------------------------ | ---------------------------------- | ---------------
24629 null | `null` | Null | 0xF6
24630 boolean | `true` | True | 0xF5
24631 boolean | `false` | False | 0xF4
24632 number_integer | -9223372036854775808..-2147483649 | Negative integer (8 bytes follow) | 0x3B
24633 number_integer | -2147483648..-32769 | Negative integer (4 bytes follow) | 0x3A
24634 number_integer | -32768..-129 | Negative integer (2 bytes follow) | 0x39
24635 number_integer | -128..-25 | Negative integer (1 byte follow) | 0x38
24636 number_integer | -24..-1 | Negative integer | 0x20..0x37
24637 number_integer | 0..23 | Integer | 0x00..0x17
24638 number_integer | 24..255 | Unsigned integer (1 byte follow) | 0x18
24639 number_integer | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
24640 number_integer | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
24641 number_integer | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
24642 number_unsigned | 0..23 | Integer | 0x00..0x17
24643 number_unsigned | 24..255 | Unsigned integer (1 byte follow) | 0x18
24644 number_unsigned | 256..65535 | Unsigned integer (2 bytes follow) | 0x19
24645 number_unsigned | 65536..4294967295 | Unsigned integer (4 bytes follow) | 0x1A
24646 number_unsigned | 4294967296..18446744073709551615 | Unsigned integer (8 bytes follow) | 0x1B
24647 number_float | *any value representable by a float* | Single-Precision Float | 0xFA
24648 number_float | *any value NOT representable by a float* | Double-Precision Float | 0xFB
24649 string | *length*: 0..23 | UTF-8 string | 0x60..0x77
24650 string | *length*: 23..255 | UTF-8 string (1 byte follow) | 0x78
24651 string | *length*: 256..65535 | UTF-8 string (2 bytes follow) | 0x79
24652 string | *length*: 65536..4294967295 | UTF-8 string (4 bytes follow) | 0x7A
24653 string | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow) | 0x7B
24654 array | *size*: 0..23 | array | 0x80..0x97
24655 array | *size*: 23..255 | array (1 byte follow) | 0x98
24656 array | *size*: 256..65535 | array (2 bytes follow) | 0x99
24657 array | *size*: 65536..4294967295 | array (4 bytes follow) | 0x9A
24658 array | *size*: 4294967296..18446744073709551615 | array (8 bytes follow) | 0x9B
24659 object | *size*: 0..23 | map | 0xA0..0xB7
24660 object | *size*: 23..255 | map (1 byte follow) | 0xB8
24661 object | *size*: 256..65535 | map (2 bytes follow) | 0xB9
24662 object | *size*: 65536..4294967295 | map (4 bytes follow) | 0xBA
24663 object | *size*: 4294967296..18446744073709551615 | map (8 bytes follow) | 0xBB
24664 binary | *size*: 0..23 | byte string | 0x40..0x57
24665 binary | *size*: 23..255 | byte string (1 byte follow) | 0x58
24666 binary | *size*: 256..65535 | byte string (2 bytes follow) | 0x59
24667 binary | *size*: 65536..4294967295 | byte string (4 bytes follow) | 0x5A
24668 binary | *size*: 4294967296..18446744073709551615 | byte string (8 bytes follow) | 0x5B
24669
24670 Binary values with subtype are mapped to tagged values (0xD8..0xDB)
24671 depending on the subtype, followed by a byte string, see "binary" cells
24672 in the table above.
24673
24674 @note The mapping is **complete** in the sense that any JSON value type
24675 can be converted to a CBOR value.
24676
24677 @note If NaN or Infinity are stored inside a JSON number, they are
24678 serialized properly. This behavior differs from the @ref dump()
24679 function which serializes NaN or Infinity to `null`.
24680
24681 @note The following CBOR types are not used in the conversion:
24682 - UTF-8 strings terminated by "break" (0x7F)
24683 - arrays terminated by "break" (0x9F)
24684 - maps terminated by "break" (0xBF)
24685 - byte strings terminated by "break" (0x5F)
24686 - date/time (0xC0..0xC1)
24687 - bignum (0xC2..0xC3)
24688 - decimal fraction (0xC4)
24689 - bigfloat (0xC5)
24690 - expected conversions (0xD5..0xD7)
24691 - simple values (0xE0..0xF3, 0xF8)
24692 - undefined (0xF7)
24693 - half-precision floats (0xF9)
24694 - break (0xFF)
24695
24696 @param[in] j JSON value to serialize
24697 @return CBOR serialization as byte vector
24698
24699 @complexity Linear in the size of the JSON value @a j.
24700
24701 @liveexample{The example shows the serialization of a JSON value to a byte
24702 vector in CBOR format.,to_cbor}
24703
24704 @sa http://cbor.io
24705 @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
24706 analogous deserialization
24707 @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
24708 @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
24709 related UBJSON format
24710
24711 @since version 2.0.9; compact representation of floating-point numbers
24712 since version 3.8.0
24713 */
24715 {
24717 to_cbor(j, result);
24718 return result;
24719 }
24720
24721 static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24722 {
24724 }
24725
24726 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
24727 {
24728 binary_writer<char>(o).write_cbor(j);
24729 }
24730
24731 /*!
24732 @brief create a MessagePack serialization of a given JSON value
24733
24734 Serializes a given JSON value @a j to a byte vector using the MessagePack
24735 serialization format. MessagePack is a binary serialization format which
24736 aims to be more compact than JSON itself, yet more efficient to parse.
24737
24738 The library uses the following mapping from JSON values types to
24739 MessagePack types according to the MessagePack specification:
24740
24741 JSON value type | value/range | MessagePack type | first byte
24742 --------------- | --------------------------------- | ---------------- | ----------
24743 null | `null` | nil | 0xC0
24744 boolean | `true` | true | 0xC3
24745 boolean | `false` | false | 0xC2
24746 number_integer | -9223372036854775808..-2147483649 | int64 | 0xD3
24747 number_integer | -2147483648..-32769 | int32 | 0xD2
24748 number_integer | -32768..-129 | int16 | 0xD1
24749 number_integer | -128..-33 | int8 | 0xD0
24750 number_integer | -32..-1 | negative fixint | 0xE0..0xFF
24751 number_integer | 0..127 | positive fixint | 0x00..0x7F
24752 number_integer | 128..255 | uint 8 | 0xCC
24753 number_integer | 256..65535 | uint 16 | 0xCD
24754 number_integer | 65536..4294967295 | uint 32 | 0xCE
24755 number_integer | 4294967296..18446744073709551615 | uint 64 | 0xCF
24756 number_unsigned | 0..127 | positive fixint | 0x00..0x7F
24757 number_unsigned | 128..255 | uint 8 | 0xCC
24758 number_unsigned | 256..65535 | uint 16 | 0xCD
24759 number_unsigned | 65536..4294967295 | uint 32 | 0xCE
24760 number_unsigned | 4294967296..18446744073709551615 | uint 64 | 0xCF
24761 number_float | *any value representable by a float* | float 32 | 0xCA
24762 number_float | *any value NOT representable by a float* | float 64 | 0xCB
24763 string | *length*: 0..31 | fixstr | 0xA0..0xBF
24764 string | *length*: 32..255 | str 8 | 0xD9
24765 string | *length*: 256..65535 | str 16 | 0xDA
24766 string | *length*: 65536..4294967295 | str 32 | 0xDB
24767 array | *size*: 0..15 | fixarray | 0x90..0x9F
24768 array | *size*: 16..65535 | array 16 | 0xDC
24769 array | *size*: 65536..4294967295 | array 32 | 0xDD
24770 object | *size*: 0..15 | fix map | 0x80..0x8F
24771 object | *size*: 16..65535 | map 16 | 0xDE
24772 object | *size*: 65536..4294967295 | map 32 | 0xDF
24773 binary | *size*: 0..255 | bin 8 | 0xC4
24774 binary | *size*: 256..65535 | bin 16 | 0xC5
24775 binary | *size*: 65536..4294967295 | bin 32 | 0xC6
24776
24777 @note The mapping is **complete** in the sense that any JSON value type
24778 can be converted to a MessagePack value.
24779
24780 @note The following values can **not** be converted to a MessagePack value:
24781 - strings with more than 4294967295 bytes
24782 - byte strings with more than 4294967295 bytes
24783 - arrays with more than 4294967295 elements
24784 - objects with more than 4294967295 elements
24785
24786 @note Any MessagePack output created @ref to_msgpack can be successfully
24787 parsed by @ref from_msgpack.
24788
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`.
24792
24793 @param[in] j JSON value to serialize
24794 @return MessagePack serialization as byte vector
24795
24796 @complexity Linear in the size of the JSON value @a j.
24797
24798 @liveexample{The example shows the serialization of a JSON value to a byte
24799 vector in MessagePack format.,to_msgpack}
24800
24801 @sa http://msgpack.org
24802 @sa see @ref from_msgpack for the analogous deserialization
24803 @sa see @ref to_cbor(const basic_json& for the related CBOR format
24804 @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
24805 related UBJSON format
24806
24807 @since version 2.0.9
24808 */
24810 {
24813 return result;
24814 }
24815
24816 static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24817 {
24819 }
24820
24821 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
24822 {
24824 }
24825
24826 /*!
24827 @brief create a UBJSON serialization of a given JSON value
24828
24829 Serializes a given JSON value @a j to a byte vector using the UBJSON
24830 (Universal Binary JSON) serialization format. UBJSON aims to be more compact
24831 than JSON itself, yet more efficient to parse.
24832
24833 The library uses the following mapping from JSON values types to
24834 UBJSON types according to the UBJSON specification:
24835
24836 JSON value type | value/range | UBJSON type | marker
24837 --------------- | --------------------------------- | ----------- | ------
24838 null | `null` | null | `Z`
24839 boolean | `true` | true | `T`
24840 boolean | `false` | false | `F`
24841 number_integer | -9223372036854775808..-2147483649 | int64 | `L`
24842 number_integer | -2147483648..-32769 | int32 | `l`
24843 number_integer | -32768..-129 | int16 | `I`
24844 number_integer | -128..127 | int8 | `i`
24845 number_integer | 128..255 | uint8 | `U`
24846 number_integer | 256..32767 | int16 | `I`
24847 number_integer | 32768..2147483647 | int32 | `l`
24848 number_integer | 2147483648..9223372036854775807 | int64 | `L`
24849 number_unsigned | 0..127 | int8 | `i`
24850 number_unsigned | 128..255 | uint8 | `U`
24851 number_unsigned | 256..32767 | int16 | `I`
24852 number_unsigned | 32768..2147483647 | int32 | `l`
24853 number_unsigned | 2147483648..9223372036854775807 | int64 | `L`
24854 number_unsigned | 2147483649..18446744073709551615 | high-precision | `H`
24855 number_float | *any value* | float64 | `D`
24856 string | *with shortest length indicator* | string | `S`
24857 array | *see notes on optimized format* | array | `[`
24858 object | *see notes on optimized format* | map | `{`
24859
24860 @note The mapping is **complete** in the sense that any JSON value type
24861 can be converted to a UBJSON value.
24862
24863 @note The following values can **not** be converted to a UBJSON value:
24864 - strings with more than 9223372036854775807 bytes (theoretical)
24865
24866 @note The following markers are not used in the conversion:
24867 - `Z`: no-op values are not created.
24868 - `C`: single-byte strings are serialized with `S` markers.
24869
24870 @note Any UBJSON output created @ref to_ubjson can be successfully parsed
24871 by @ref from_ubjson.
24872
24873 @note If NaN or Infinity are stored inside a JSON number, they are
24874 serialized properly. This behavior differs from the @ref dump()
24875 function which serializes NaN or Infinity to `null`.
24876
24877 @note The optimized formats for containers are supported: Parameter
24878 @a use_size adds size information to the beginning of a container and
24879 removes the closing marker. Parameter @a use_type further checks
24880 whether all elements of a container have the same type and adds the
24881 type marker to the beginning of the container. The @a use_type
24882 parameter must only be used together with @a use_size = true. Note
24883 that @a use_size = true alone may result in larger representations -
24884 the benefit of this parameter is that the receiving side is
24885 immediately informed on the number of elements of the container.
24886
24887 @note If the JSON data contains the binary type, the value stored is a list
24888 of integers, as suggested by the UBJSON documentation. In particular,
24889 this means that serialization and the deserialization of a JSON
24890 containing binary values into UBJSON and back will result in a
24891 different JSON object.
24892
24893 @param[in] j JSON value to serialize
24894 @param[in] use_size whether to add size annotations to container types
24895 @param[in] use_type whether to add type annotations to container types
24896 (must be combined with @a use_size = true)
24897 @return UBJSON serialization as byte vector
24898
24899 @complexity Linear in the size of the JSON value @a j.
24900
24901 @liveexample{The example shows the serialization of a JSON value to a byte
24902 vector in UBJSON format.,to_ubjson}
24903
24904 @sa http://ubjson.org
24905 @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
24906 analogous deserialization
24907 @sa see @ref to_cbor(const basic_json& for the related CBOR format
24908 @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
24909
24910 @since version 3.1.0
24911 */
24913 const bool use_size = false,
24914 const bool use_type = false)
24915 {
24918 return result;
24919 }
24920
24921 static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,
24922 const bool use_size = false, const bool use_type = false)
24923 {
24925 }
24926
24927 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
24928 const bool use_size = false, const bool use_type = false)
24929 {
24931 }
24932
24933
24934 /*!
24935 @brief Serializes the given JSON object `j` to BSON and returns a vector
24936 containing the corresponding BSON-representation.
24937
24938 BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
24939 stored as a single entity (a so-called document).
24940
24941 The library uses the following mapping from JSON values types to BSON types:
24942
24943 JSON value type | value/range | BSON type | marker
24944 --------------- | --------------------------------- | ----------- | ------
24945 null | `null` | null | 0x0A
24946 boolean | `true`, `false` | boolean | 0x08
24947 number_integer | -9223372036854775808..-2147483649 | int64 | 0x12
24948 number_integer | -2147483648..2147483647 | int32 | 0x10
24949 number_integer | 2147483648..9223372036854775807 | int64 | 0x12
24950 number_unsigned | 0..2147483647 | int32 | 0x10
24951 number_unsigned | 2147483648..9223372036854775807 | int64 | 0x12
24952 number_unsigned | 9223372036854775808..18446744073709551615| -- | --
24953 number_float | *any value* | double | 0x01
24954 string | *any value* | string | 0x02
24955 array | *any value* | document | 0x04
24956 object | *any value* | document | 0x03
24957 binary | *any value* | binary | 0x05
24958
24959 @warning The mapping is **incomplete**, since only JSON-objects (and things
24960 contained therein) can be serialized to BSON.
24961 Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
24962 and the keys may not contain U+0000, since they are serialized a
24963 zero-terminated c-strings.
24964
24965 @throw out_of_range.407 if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
24966 @throw out_of_range.409 if a key in `j` contains a NULL (U+0000)
24967 @throw type_error.317 if `!j.is_object()`
24968
24969 @pre The input `j` is required to be an object: `j.is_object() == true`.
24970
24971 @note Any BSON output created via @ref to_bson can be successfully parsed
24972 by @ref from_bson.
24973
24974 @param[in] j JSON value to serialize
24975 @return BSON serialization as byte vector
24976
24977 @complexity Linear in the size of the JSON value @a j.
24978
24979 @liveexample{The example shows the serialization of a JSON value to a byte
24980 vector in BSON format.,to_bson}
24981
24982 @sa http://bsonspec.org/spec.html
24983 @sa see @ref from_bson(detail::input_adapter&&, const bool strict) for the
24984 analogous deserialization
24985 @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
24986 related UBJSON format
24987 @sa see @ref to_cbor(const basic_json&) for the related CBOR format
24988 @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
24989 */
24991 {
24993 to_bson(j, result);
24994 return result;
24995 }
24996
24997 /*!
24998 @brief Serializes the given JSON object `j` to BSON and forwards the
24999 corresponding BSON-representation to the given output_adapter `o`.
25000 @param j The JSON object to convert to BSON.
25001 @param o The output adapter that receives the binary BSON representation.
25002 @pre The input `j` shall be an object: `j.is_object() == true`
25003 @sa see @ref to_bson(const basic_json&)
25004 */
25005 static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)
25006 {
25008 }
25009
25010 /*!
25011 @copydoc to_bson(const basic_json&, detail::output_adapter<std::uint8_t>)
25012 */
25013 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
25014 {
25015 binary_writer<char>(o).write_bson(j);
25016 }
25017
25018
25019 /*!
25020 @brief create a JSON value from an input in CBOR format
25021
25022 Deserializes a given input @a i to a JSON value using the CBOR (Concise
25023 Binary Object Representation) serialization format.
25024
25025 The library maps CBOR types to JSON value types as follows:
25026
25027 CBOR type | JSON value type | first byte
25028 ---------------------- | --------------- | ----------
25029 Integer | number_unsigned | 0x00..0x17
25030 Unsigned integer | number_unsigned | 0x18
25031 Unsigned integer | number_unsigned | 0x19
25032 Unsigned integer | number_unsigned | 0x1A
25033 Unsigned integer | number_unsigned | 0x1B
25034 Negative integer | number_integer | 0x20..0x37
25035 Negative integer | number_integer | 0x38
25036 Negative integer | number_integer | 0x39
25037 Negative integer | number_integer | 0x3A
25038 Negative integer | number_integer | 0x3B
25039 Byte string | binary | 0x40..0x57
25040 Byte string | binary | 0x58
25041 Byte string | binary | 0x59
25042 Byte string | binary | 0x5A
25043 Byte string | binary | 0x5B
25044 UTF-8 string | string | 0x60..0x77
25045 UTF-8 string | string | 0x78
25046 UTF-8 string | string | 0x79
25047 UTF-8 string | string | 0x7A
25048 UTF-8 string | string | 0x7B
25049 UTF-8 string | string | 0x7F
25050 array | array | 0x80..0x97
25051 array | array | 0x98
25052 array | array | 0x99
25053 array | array | 0x9A
25054 array | array | 0x9B
25055 array | array | 0x9F
25056 map | object | 0xA0..0xB7
25057 map | object | 0xB8
25058 map | object | 0xB9
25059 map | object | 0xBA
25060 map | object | 0xBB
25061 map | object | 0xBF
25062 False | `false` | 0xF4
25063 True | `true` | 0xF5
25064 Null | `null` | 0xF6
25065 Half-Precision Float | number_float | 0xF9
25066 Single-Precision Float | number_float | 0xFA
25067 Double-Precision Float | number_float | 0xFB
25068
25069 @warning The mapping is **incomplete** in the sense that not all CBOR
25070 types can be converted to a JSON value. The following CBOR types
25071 are not supported and will yield parse errors (parse_error.112):
25072 - date/time (0xC0..0xC1)
25073 - bignum (0xC2..0xC3)
25074 - decimal fraction (0xC4)
25075 - bigfloat (0xC5)
25076 - expected conversions (0xD5..0xD7)
25077 - simple values (0xE0..0xF3, 0xF8)
25078 - undefined (0xF7)
25079
25080 @warning CBOR allows map keys of any type, whereas JSON only allows
25081 strings as keys in object values. Therefore, CBOR maps with keys
25082 other than UTF-8 strings are rejected (parse_error.113).
25083
25084 @note Any CBOR output created @ref to_cbor can be successfully parsed by
25085 @ref from_cbor.
25086
25087 @param[in] i an input in CBOR format convertible to an input adapter
25088 @param[in] strict whether to expect the input to be consumed until EOF
25089 (true by default)
25090 @param[in] allow_exceptions whether to throw exceptions in case of a
25091 parse error (optional, true by default)
25092 @param[in] tag_handler how to treat CBOR tags (optional, error by default)
25093
25094 @return deserialized JSON value; in case of a parse error and
25095 @a allow_exceptions set to `false`, the return value will be
25096 value_t::discarded.
25097
25098 @throw parse_error.110 if the given input ends prematurely or the end of
25099 file was not reached when @a strict was set to true
25100 @throw parse_error.112 if unsupported features from CBOR were
25101 used in the given input @a v or if the input is not valid CBOR
25102 @throw parse_error.113 if a string was expected as map key, but not found
25103
25104 @complexity Linear in the size of the input @a i.
25105
25106 @liveexample{The example shows the deserialization of a byte vector in CBOR
25107 format to a JSON value.,from_cbor}
25108
25109 @sa http://cbor.io
25110 @sa see @ref to_cbor(const basic_json&) for the analogous serialization
25111 @sa see @ref from_msgpack(InputType&&, const bool, const bool) for the
25112 related MessagePack format
25113 @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
25114 related UBJSON format
25115
25116 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
25117 consume input adapters, removed start_index parameter, and added
25118 @a strict parameter since 3.0.0; added @a allow_exceptions parameter
25119 since 3.2.0; added @a tag_handler parameter since 3.9.0.
25120 */
25121 template<typename InputType>
25123 static basic_json from_cbor(InputType&& i,
25124 const bool strict = true,
25125 const bool allow_exceptions = true,
25126 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25127 {
25131 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25132 return res ? result : basic_json(value_t::discarded);
25133 }
25134
25135 /*!
25136 @copydoc from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t)
25137 */
25138 template<typename IteratorType>
25140 static basic_json from_cbor(IteratorType first, IteratorType last,
25141 const bool strict = true,
25142 const bool allow_exceptions = true,
25143 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25144 {
25148 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25149 return res ? result : basic_json(value_t::discarded);
25150 }
25151
25152 template<typename T>
25154 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25155 static basic_json from_cbor(const T* ptr, std::size_t len,
25156 const bool strict = true,
25157 const bool allow_exceptions = true,
25158 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25159 {
25161 }
25162
25163
25165 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25166 static basic_json from_cbor(detail::span_input_adapter&& i,
25167 const bool strict = true,
25168 const bool allow_exceptions = true,
25169 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25170 {
25173 auto ia = i.get();
25174 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25175 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25176 return res ? result : basic_json(value_t::discarded);
25177 }
25178
25179 /*!
25180 @brief create a JSON value from an input in MessagePack format
25181
25182 Deserializes a given input @a i to a JSON value using the MessagePack
25183 serialization format.
25184
25185 The library maps MessagePack types to JSON value types as follows:
25186
25187 MessagePack type | JSON value type | first byte
25188 ---------------- | --------------- | ----------
25189 positive fixint | number_unsigned | 0x00..0x7F
25190 fixmap | object | 0x80..0x8F
25191 fixarray | array | 0x90..0x9F
25192 fixstr | string | 0xA0..0xBF
25193 nil | `null` | 0xC0
25194 false | `false` | 0xC2
25195 true | `true` | 0xC3
25196 float 32 | number_float | 0xCA
25197 float 64 | number_float | 0xCB
25198 uint 8 | number_unsigned | 0xCC
25199 uint 16 | number_unsigned | 0xCD
25200 uint 32 | number_unsigned | 0xCE
25201 uint 64 | number_unsigned | 0xCF
25202 int 8 | number_integer | 0xD0
25203 int 16 | number_integer | 0xD1
25204 int 32 | number_integer | 0xD2
25205 int 64 | number_integer | 0xD3
25206 str 8 | string | 0xD9
25207 str 16 | string | 0xDA
25208 str 32 | string | 0xDB
25209 array 16 | array | 0xDC
25210 array 32 | array | 0xDD
25211 map 16 | object | 0xDE
25212 map 32 | object | 0xDF
25213 bin 8 | binary | 0xC4
25214 bin 16 | binary | 0xC5
25215 bin 32 | binary | 0xC6
25216 ext 8 | binary | 0xC7
25217 ext 16 | binary | 0xC8
25218 ext 32 | binary | 0xC9
25219 fixext 1 | binary | 0xD4
25220 fixext 2 | binary | 0xD5
25221 fixext 4 | binary | 0xD6
25222 fixext 8 | binary | 0xD7
25223 fixext 16 | binary | 0xD8
25224 negative fixint | number_integer | 0xE0-0xFF
25225
25226 @note Any MessagePack output created @ref to_msgpack can be successfully
25227 parsed by @ref from_msgpack.
25228
25229 @param[in] i an input in MessagePack format convertible to an input
25230 adapter
25231 @param[in] strict whether to expect the input to be consumed until EOF
25232 (true by default)
25233 @param[in] allow_exceptions whether to throw exceptions in case of a
25234 parse error (optional, true by default)
25235
25236 @return deserialized JSON value; in case of a parse error and
25237 @a allow_exceptions set to `false`, the return value will be
25238 value_t::discarded.
25239
25240 @throw parse_error.110 if the given input ends prematurely or the end of
25241 file was not reached when @a strict was set to true
25242 @throw parse_error.112 if unsupported features from MessagePack were
25243 used in the given input @a i or if the input is not valid MessagePack
25244 @throw parse_error.113 if a string was expected as map key, but not found
25245
25246 @complexity Linear in the size of the input @a i.
25247
25248 @liveexample{The example shows the deserialization of a byte vector in
25249 MessagePack format to a JSON value.,from_msgpack}
25250
25251 @sa http://msgpack.org
25252 @sa see @ref to_msgpack(const basic_json&) for the analogous serialization
25253 @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25254 related CBOR format
25255 @sa see @ref from_ubjson(InputType&&, const bool, const bool) for
25256 the related UBJSON format
25257 @sa see @ref from_bson(InputType&&, const bool, const bool) for
25258 the related BSON format
25259
25260 @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
25261 consume input adapters, removed start_index parameter, and added
25262 @a strict parameter since 3.0.0; added @a allow_exceptions parameter
25263 since 3.2.0
25264 */
25265 template<typename InputType>
25267 static basic_json from_msgpack(InputType&& i,
25268 const bool strict = true,
25269 const bool allow_exceptions = true)
25270 {
25274 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25275 return res ? result : basic_json(value_t::discarded);
25276 }
25277
25278 /*!
25279 @copydoc from_msgpack(InputType&&, const bool, const bool)
25280 */
25281 template<typename IteratorType>
25283 static basic_json from_msgpack(IteratorType first, IteratorType last,
25284 const bool strict = true,
25285 const bool allow_exceptions = true)
25286 {
25290 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25291 return res ? result : basic_json(value_t::discarded);
25292 }
25293
25294
25295 template<typename T>
25297 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25298 static basic_json from_msgpack(const T* ptr, std::size_t len,
25299 const bool strict = true,
25300 const bool allow_exceptions = true)
25301 {
25303 }
25304
25306 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25307 static basic_json from_msgpack(detail::span_input_adapter&& i,
25308 const bool strict = true,
25309 const bool allow_exceptions = true)
25310 {
25313 auto ia = i.get();
25314 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25315 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25316 return res ? result : basic_json(value_t::discarded);
25317 }
25318
25319
25320 /*!
25321 @brief create a JSON value from an input in UBJSON format
25322
25323 Deserializes a given input @a i to a JSON value using the UBJSON (Universal
25324 Binary JSON) serialization format.
25325
25326 The library maps UBJSON types to JSON value types as follows:
25327
25328 UBJSON type | JSON value type | marker
25329 ----------- | --------------------------------------- | ------
25330 no-op | *no value, next value is read* | `N`
25331 null | `null` | `Z`
25332 false | `false` | `F`
25333 true | `true` | `T`
25334 float32 | number_float | `d`
25335 float64 | number_float | `D`
25336 uint8 | number_unsigned | `U`
25337 int8 | number_integer | `i`
25338 int16 | number_integer | `I`
25339 int32 | number_integer | `l`
25340 int64 | number_integer | `L`
25341 high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H'
25342 string | string | `S`
25343 char | string | `C`
25344 array | array (optimized values are supported) | `[`
25345 object | object (optimized values are supported) | `{`
25346
25347 @note The mapping is **complete** in the sense that any UBJSON value can
25348 be converted to a JSON value.
25349
25350 @param[in] i an input in UBJSON format convertible to an input adapter
25351 @param[in] strict whether to expect the input to be consumed until EOF
25352 (true by default)
25353 @param[in] allow_exceptions whether to throw exceptions in case of a
25354 parse error (optional, true by default)
25355
25356 @return deserialized JSON value; in case of a parse error and
25357 @a allow_exceptions set to `false`, the return value will be
25358 value_t::discarded.
25359
25360 @throw parse_error.110 if the given input ends prematurely or the end of
25361 file was not reached when @a strict was set to true
25362 @throw parse_error.112 if a parse error occurs
25363 @throw parse_error.113 if a string could not be parsed successfully
25364
25365 @complexity Linear in the size of the input @a i.
25366
25367 @liveexample{The example shows the deserialization of a byte vector in
25368 UBJSON format to a JSON value.,from_ubjson}
25369
25370 @sa http://ubjson.org
25371 @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
25372 analogous serialization
25373 @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25374 related CBOR format
25375 @sa see @ref from_msgpack(InputType&&, const bool, const bool) for
25376 the related MessagePack format
25377 @sa see @ref from_bson(InputType&&, const bool, const bool) for
25378 the related BSON format
25379
25380 @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
25381 */
25382 template<typename InputType>
25384 static basic_json from_ubjson(InputType&& i,
25385 const bool strict = true,
25386 const bool allow_exceptions = true)
25387 {
25391 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25392 return res ? result : basic_json(value_t::discarded);
25393 }
25394
25395 /*!
25396 @copydoc from_ubjson(InputType&&, const bool, const bool)
25397 */
25398 template<typename IteratorType>
25400 static basic_json from_ubjson(IteratorType first, IteratorType last,
25401 const bool strict = true,
25402 const bool allow_exceptions = true)
25403 {
25407 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25408 return res ? result : basic_json(value_t::discarded);
25409 }
25410
25411 template<typename T>
25413 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25414 static basic_json from_ubjson(const T* ptr, std::size_t len,
25415 const bool strict = true,
25416 const bool allow_exceptions = true)
25417 {
25419 }
25420
25422 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25423 static basic_json from_ubjson(detail::span_input_adapter&& i,
25424 const bool strict = true,
25425 const bool allow_exceptions = true)
25426 {
25429 auto ia = i.get();
25430 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25431 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25432 return res ? result : basic_json(value_t::discarded);
25433 }
25434
25435
25436 /*!
25437 @brief Create a JSON value from an input in BSON format
25438
25439 Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
25440 serialization format.
25441
25442 The library maps BSON record types to JSON value types as follows:
25443
25444 BSON type | BSON marker byte | JSON value type
25445 --------------- | ---------------- | ---------------------------
25446 double | 0x01 | number_float
25447 string | 0x02 | string
25448 document | 0x03 | object
25449 array | 0x04 | array
25450 binary | 0x05 | binary
25451 undefined | 0x06 | still unsupported
25452 ObjectId | 0x07 | still unsupported
25453 boolean | 0x08 | boolean
25454 UTC Date-Time | 0x09 | still unsupported
25455 null | 0x0A | null
25456 Regular Expr. | 0x0B | still unsupported
25457 DB Pointer | 0x0C | still unsupported
25458 JavaScript Code | 0x0D | still unsupported
25459 Symbol | 0x0E | still unsupported
25460 JavaScript Code | 0x0F | still unsupported
25461 int32 | 0x10 | number_integer
25462 Timestamp | 0x11 | still unsupported
25463 128-bit decimal float | 0x13 | still unsupported
25464 Max Key | 0x7F | still unsupported
25465 Min Key | 0xFF | still unsupported
25466
25467 @warning The mapping is **incomplete**. The unsupported mappings
25468 are indicated in the table above.
25469
25470 @param[in] i an input in BSON format convertible to an input adapter
25471 @param[in] strict whether to expect the input to be consumed until EOF
25472 (true by default)
25473 @param[in] allow_exceptions whether to throw exceptions in case of a
25474 parse error (optional, true by default)
25475
25476 @return deserialized JSON value; in case of a parse error and
25477 @a allow_exceptions set to `false`, the return value will be
25478 value_t::discarded.
25479
25480 @throw parse_error.114 if an unsupported BSON record type is encountered
25481
25482 @complexity Linear in the size of the input @a i.
25483
25484 @liveexample{The example shows the deserialization of a byte vector in
25485 BSON format to a JSON value.,from_bson}
25486
25487 @sa http://bsonspec.org/spec.html
25488 @sa see @ref to_bson(const basic_json&) for the analogous serialization
25489 @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25490 related CBOR format
25491 @sa see @ref from_msgpack(InputType&&, const bool, const bool) for
25492 the related MessagePack format
25493 @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
25494 related UBJSON format
25495 */
25496 template<typename InputType>
25498 static basic_json from_bson(InputType&& i,
25499 const bool strict = true,
25500 const bool allow_exceptions = true)
25501 {
25505 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25506 return res ? result : basic_json(value_t::discarded);
25507 }
25508
25509 /*!
25510 @copydoc from_bson(InputType&&, const bool, const bool)
25511 */
25512 template<typename IteratorType>
25514 static basic_json from_bson(IteratorType first, IteratorType last,
25515 const bool strict = true,
25516 const bool allow_exceptions = true)
25517 {
25521 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25522 return res ? result : basic_json(value_t::discarded);
25523 }
25524
25525 template<typename T>
25527 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25528 static basic_json from_bson(const T* ptr, std::size_t len,
25529 const bool strict = true,
25530 const bool allow_exceptions = true)
25531 {
25533 }
25534
25536 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25537 static basic_json from_bson(detail::span_input_adapter&& i,
25538 const bool strict = true,
25539 const bool allow_exceptions = true)
25540 {
25543 auto ia = i.get();
25544 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25545 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25546 return res ? result : basic_json(value_t::discarded);
25547 }
25548 /// @}
25549
25550 //////////////////////////
25551 // JSON Pointer support //
25552 //////////////////////////
25553
25554 /// @name JSON Pointer functions
25555 /// @{
25556
25557 /*!
25558 @brief access specified element via JSON Pointer
25559
25560 Uses a JSON pointer to retrieve a reference to the respective JSON value.
25561 No bound checking is performed. Similar to @ref operator[](const typename
25562 object_t::key_type&), `null` values are created in arrays and objects if
25563 necessary.
25564
25565 In particular:
25566 - If the JSON pointer points to an object key that does not exist, it
25567 is created an filled with a `null` value before a reference to it
25568 is returned.
25569 - If the JSON pointer points to an array index that does not exist, it
25570 is created an filled with a `null` value before a reference to it
25571 is returned. All indices between the current maximum and the given
25572 index are also filled with `null`.
25573 - The special value `-` is treated as a synonym for the index past the
25574 end.
25575
25576 @param[in] ptr a JSON pointer
25577
25578 @return reference to the element pointed to by @a ptr
25579
25580 @complexity Constant.
25581
25582 @throw parse_error.106 if an array index begins with '0'
25583 @throw parse_error.109 if an array index was not a number
25584 @throw out_of_range.404 if the JSON pointer can not be resolved
25585
25586 @liveexample{The behavior is shown in the example.,operatorjson_pointer}
25587
25588 @since version 2.0.0
25589 */
25590 reference operator[](const json_pointer& ptr)
25591 {
25592 return ptr.get_unchecked(this);
25593 }
25594
25595 /*!
25596 @brief access specified element via JSON Pointer
25597
25598 Uses a JSON pointer to retrieve a reference to the respective JSON value.
25599 No bound checking is performed. The function does not change the JSON
25600 value; no `null` values are created. In particular, the special value
25601 `-` yields an exception.
25602
25603 @param[in] ptr JSON pointer to the desired element
25604
25605 @return const reference to the element pointed to by @a ptr
25606
25607 @complexity Constant.
25608
25609 @throw parse_error.106 if an array index begins with '0'
25610 @throw parse_error.109 if an array index was not a number
25611 @throw out_of_range.402 if the array index '-' is used
25612 @throw out_of_range.404 if the JSON pointer can not be resolved
25613
25614 @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
25615
25616 @since version 2.0.0
25617 */
25618 const_reference operator[](const json_pointer& ptr) const
25619 {
25620 return ptr.get_unchecked(this);
25621 }
25622
25623 /*!
25624 @brief access specified element via JSON Pointer
25625
25626 Returns a reference to the element at with specified JSON pointer @a ptr,
25627 with bounds checking.
25628
25629 @param[in] ptr JSON pointer to the desired element
25630
25631 @return reference to the element pointed to by @a ptr
25632
25633 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
25634 begins with '0'. See example below.
25635
25636 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
25637 is not a number. See example below.
25638
25639 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
25640 is out of range. See example below.
25641
25642 @throw out_of_range.402 if the array index '-' is used in the passed JSON
25643 pointer @a ptr. As `at` provides checked access (and no elements are
25644 implicitly inserted), the index '-' is always invalid. See example below.
25645
25646 @throw out_of_range.403 if the JSON pointer describes a key of an object
25647 which cannot be found. See example below.
25648
25649 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
25650 See example below.
25651
25652 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
25653 changes in the JSON value.
25654
25655 @complexity Constant.
25656
25657 @since version 2.0.0
25658
25659 @liveexample{The behavior is shown in the example.,at_json_pointer}
25660 */
25661 reference at(const json_pointer& ptr)
25662 {
25663 return ptr.get_checked(this);
25664 }
25665
25666 /*!
25667 @brief access specified element via JSON Pointer
25668
25669 Returns a const reference to the element at with specified JSON pointer @a
25670 ptr, with bounds checking.
25671
25672 @param[in] ptr JSON pointer to the desired element
25673
25674 @return reference to the element pointed to by @a ptr
25675
25676 @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
25677 begins with '0'. See example below.
25678
25679 @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
25680 is not a number. See example below.
25681
25682 @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
25683 is out of range. See example below.
25684
25685 @throw out_of_range.402 if the array index '-' is used in the passed JSON
25686 pointer @a ptr. As `at` provides checked access (and no elements are
25687 implicitly inserted), the index '-' is always invalid. See example below.
25688
25689 @throw out_of_range.403 if the JSON pointer describes a key of an object
25690 which cannot be found. See example below.
25691
25692 @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
25693 See example below.
25694
25695 @exceptionsafety Strong guarantee: if an exception is thrown, there are no
25696 changes in the JSON value.
25697
25698 @complexity Constant.
25699
25700 @since version 2.0.0
25701
25702 @liveexample{The behavior is shown in the example.,at_json_pointer_const}
25703 */
25704 const_reference at(const json_pointer& ptr) const
25705 {
25706 return ptr.get_checked(this);
25707 }
25708
25709 /*!
25710 @brief return flattened JSON value
25711
25712 The function creates a JSON object whose keys are JSON pointers (see [RFC
25713 6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
25714 primitive. The original JSON value can be restored using the @ref
25715 unflatten() function.
25716
25717 @return an object that maps JSON pointers to primitive values
25718
25719 @note Empty objects and arrays are flattened to `null` and will not be
25720 reconstructed correctly by the @ref unflatten() function.
25721
25722 @complexity Linear in the size the JSON value.
25723
25724 @liveexample{The following code shows how a JSON object is flattened to an
25725 object whose keys consist of JSON pointers.,flatten}
25726
25727 @sa see @ref unflatten() for the reverse function
25728
25729 @since version 2.0.0
25730 */
25732 {
25734 json_pointer::flatten("", *this, result);
25735 return result;
25736 }
25737
25738 /*!
25739 @brief unflatten a previously flattened JSON value
25740
25741 The function restores the arbitrary nesting of a JSON value that has been
25742 flattened before using the @ref flatten() function. The JSON value must
25743 meet certain constraints:
25744 1. The value must be an object.
25745 2. The keys must be JSON pointers (see
25746 [RFC 6901](https://tools.ietf.org/html/rfc6901))
25747 3. The mapped values must be primitive JSON types.
25748
25749 @return the original JSON from a flattened version
25750
25751 @note Empty objects and arrays are flattened by @ref flatten() to `null`
25752 values and can not unflattened to their original type. Apart from
25753 this example, for a JSON value `j`, the following is always true:
25754 `j == j.flatten().unflatten()`.
25755
25756 @complexity Linear in the size the JSON value.
25757
25758 @throw type_error.314 if value is not an object
25759 @throw type_error.315 if object values are not primitive
25760
25761 @liveexample{The following code shows how a flattened JSON object is
25762 unflattened into the original nested JSON object.,unflatten}
25763
25764 @sa see @ref flatten() for the reverse function
25765
25766 @since version 2.0.0
25767 */
25769 {
25770 return json_pointer::unflatten(*this);
25771 }
25772
25773 /// @}
25774
25775 //////////////////////////
25776 // JSON Patch functions //
25777 //////////////////////////
25778
25779 /// @name JSON Patch functions
25780 /// @{
25781
25782 /*!
25783 @brief applies a JSON patch
25784
25785 [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
25786 expressing a sequence of operations to apply to a JSON) document. With
25787 this function, a JSON Patch is applied to the current JSON value by
25788 executing all operations from the patch.
25789
25790 @param[in] json_patch JSON patch document
25791 @return patched document
25792
25793 @note The application of a patch is atomic: Either all operations succeed
25794 and the patched document is returned or an exception is thrown. In
25795 any case, the original value is not changed: the patch is applied
25796 to a copy of the value.
25797
25798 @throw parse_error.104 if the JSON patch does not consist of an array of
25799 objects
25800
25801 @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
25802 attributes are missing); example: `"operation add must have member path"`
25803
25804 @throw out_of_range.401 if an array index is out of range.
25805
25806 @throw out_of_range.403 if a JSON pointer inside the patch could not be
25807 resolved successfully in the current JSON value; example: `"key baz not
25808 found"`
25809
25810 @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
25811 "move")
25812
25813 @throw other_error.501 if "test" operation was unsuccessful
25814
25815 @complexity Linear in the size of the JSON value and the length of the
25816 JSON patch. As usually only a fraction of the JSON value is affected by
25817 the patch, the complexity can usually be neglected.
25818
25819 @liveexample{The following code shows how a JSON patch is applied to a
25820 value.,patch}
25821
25822 @sa see @ref diff -- create a JSON patch by comparing two JSON values
25823
25824 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
25825 @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
25826
25827 @since version 2.0.0
25828 */
25829 basic_json patch(const basic_json& json_patch) const
25830 {
25831 // make a working copy to apply the patch to
25832 basic_json result = *this;
25833
25834 // the valid JSON Patch operations
25835 enum class patch_operations { add, remove, replace, move, copy, test, invalid };
25836
25837 const auto get_op = [](const std::string& op)
25838 {
25839 if (op == "add")
25840 {
25841 return patch_operations::add;
25842 }
25843 if (op == "remove")
25844 {
25845 return patch_operations::remove;
25846 }
25847 if (op == "replace")
25848 {
25849 return patch_operations::replace;
25850 }
25851 if (op == "move")
25852 {
25853 return patch_operations::move;
25854 }
25855 if (op == "copy")
25856 {
25857 return patch_operations::copy;
25858 }
25859 if (op == "test")
25860 {
25861 return patch_operations::test;
25862 }
25863
25864 return patch_operations::invalid;
25865 };
25866
25867 // wrapper for "add" operation; add value at ptr
25869 {
25870 // adding to the root of the target document means replacing it
25871 if (ptr.empty())
25872 {
25873 result = val;
25874 return;
25875 }
25876
25877 // make sure the top element of the pointer exists
25879 if (top_pointer != ptr)
25880 {
25882 }
25883
25884 // get reference to parent of JSON pointer ptr
25885 const auto last_path = ptr.back();
25886 ptr.pop_back();
25888
25889 switch (parent.m_type)
25890 {
25891 case value_t::null:
25892 case value_t::object:
25893 {
25894 // use operator[] to add value
25895 parent[last_path] = val;
25896 break;
25897 }
25898
25899 case value_t::array:
25900 {
25901 if (last_path == "-")
25902 {
25903 // special case: append to back
25905 }
25906 else
25907 {
25908 const auto idx = json_pointer::array_index(last_path);
25910 {
25911 // avoid undefined behavior
25912 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
25913 }
25914
25915 // default case: insert add offset
25916 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
25917 }
25918 break;
25919 }
25920
25921 // if there exists a parent it cannot be primitive
25922 case value_t::string: // LCOV_EXCL_LINE
25923 case value_t::boolean: // LCOV_EXCL_LINE
25924 case value_t::number_integer: // LCOV_EXCL_LINE
25925 case value_t::number_unsigned: // LCOV_EXCL_LINE
25926 case value_t::number_float: // LCOV_EXCL_LINE
25927 case value_t::binary: // LCOV_EXCL_LINE
25928 case value_t::discarded: // LCOV_EXCL_LINE
25929 default: // LCOV_EXCL_LINE
25930 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
25931 }
25932 };
25933
25934 // wrapper for "remove" operation; remove value at ptr
25935 const auto operation_remove = [this, &result](json_pointer& ptr)
25936 {
25937 // get reference to parent of JSON pointer ptr
25938 const auto last_path = ptr.back();
25939 ptr.pop_back();
25941
25942 // remove child
25943 if (parent.is_object())
25944 {
25945 // perform range check
25946 auto it = parent.find(last_path);
25947 if (JSON_HEDLEY_LIKELY(it != parent.end()))
25948 {
25949 parent.erase(it);
25950 }
25951 else
25952 {
25953 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
25954 }
25955 }
25956 else if (parent.is_array())
25957 {
25958 // note erase performs range check
25960 }
25961 };
25962
25963 // type check: top level value must be an array
25965 {
25966 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
25967 }
25968
25969 // iterate and apply the operations
25970 for (const auto& val : json_patch)
25971 {
25972 // wrapper to get a value for an operation
25973 const auto get_value = [&val](const std::string& op,
25974 const std::string& member,
25975 bool string_type) -> basic_json&
25976 {
25977 // find value
25978 auto it = val.m_value.object->find(member);
25979
25980 // context-sensitive error message
25981 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
25982
25983 // check if desired value is present
25985 {
25986 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25987 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
25988 }
25989
25990 // check if result is of type string
25992 {
25993 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25994 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
25995 }
25996
25997 // no error: return value
25998 return it->second;
25999 };
26000
26001 // type check: every element of the array must be an object
26003 {
26004 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
26005 }
26006
26007 // collect mandatory members
26008 const auto op = get_value("op", "op", true).template get<std::string>();
26009 const auto path = get_value(op, "path", true).template get<std::string>();
26011
26012 switch (get_op(op))
26013 {
26014 case patch_operations::add:
26015 {
26016 operation_add(ptr, get_value("add", "value", false));
26017 break;
26018 }
26019
26021 {
26023 break;
26024 }
26025
26027 {
26028 // the "path" location must exist - use at()
26029 result.at(ptr) = get_value("replace", "value", false);
26030 break;
26031 }
26032
26033 case patch_operations::move:
26034 {
26035 const auto from_path = get_value("move", "from", true).template get<std::string>();
26037
26038 // the "from" location must exist - use at()
26040
26041 // The move operation is functionally identical to a
26042 // "remove" operation on the "from" location, followed
26043 // immediately by an "add" operation at the target
26044 // location with the value that was just removed.
26047 break;
26048 }
26049
26050 case patch_operations::copy:
26051 {
26052 const auto from_path = get_value("copy", "from", true).template get<std::string>();
26054
26055 // the "from" location must exist - use at()
26057
26058 // The copy is functionally identical to an "add"
26059 // operation at the target location using the value
26060 // specified in the "from" member.
26062 break;
26063 }
26064
26065 case patch_operations::test:
26066 {
26067 bool success = false;
26068 JSON_TRY
26069 {
26070 // check if "value" matches the one at "path"
26071 // the "path" location must exist - use at()
26072 success = (result.at(ptr) == get_value("test", "value", false));
26073 }
26075 {
26076 // ignore out of range errors: success remains false
26077 }
26078
26079 // throw an exception if test fails
26081 {
26082 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
26083 }
26084
26085 break;
26086 }
26087
26089 default:
26090 {
26091 // op must be "add", "remove", "replace", "move", "copy", or
26092 // "test"
26093 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
26094 }
26095 }
26096 }
26097
26098 return result;
26099 }
26100
26101 /*!
26102 @brief creates a diff as a JSON patch
26103
26104 Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
26105 be changed into the value @a target by calling @ref patch function.
26106
26107 @invariant For two JSON values @a source and @a target, the following code
26108 yields always `true`:
26109 @code {.cpp}
26110 source.patch(diff(source, target)) == target;
26111 @endcode
26112
26113 @note Currently, only `remove`, `add`, and `replace` operations are
26114 generated.
26115
26116 @param[in] source JSON value to compare from
26117 @param[in] target JSON value to compare against
26118 @param[in] path helper value to create JSON pointers
26119
26120 @return a JSON patch to convert the @a source to @a target
26121
26122 @complexity Linear in the lengths of @a source and @a target.
26123
26124 @liveexample{The following code shows how a JSON patch is created as a
26125 diff for two JSON values.,diff}
26126
26127 @sa see @ref patch -- apply a JSON patch
26128 @sa see @ref merge_patch -- apply a JSON Merge Patch
26129
26130 @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
26131
26132 @since version 2.0.0
26133 */
26135 static basic_json diff(const basic_json& source, const basic_json& target,
26136 const std::string& path = "")
26137 {
26138 // the patch
26140
26141 // if the values are the same, return empty patch
26142 if (source == target)
26143 {
26144 return result;
26145 }
26146
26147 if (source.type() != target.type())
26148 {
26149 // different types: replace value
26151 {
26152 {"op", "replace"}, {"path", path}, {"value", target}
26153 });
26154 return result;
26155 }
26156
26157 switch (source.type())
26158 {
26159 case value_t::array:
26160 {
26161 // first pass: traverse common elements
26162 std::size_t i = 0;
26163 while (i < source.size() && i < target.size())
26164 {
26165 // recursive call to compare array values at index i
26166 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
26168 ++i;
26169 }
26170
26171 // i now reached the end of at least one array
26172 // in a second pass, traverse the remaining elements
26173
26174 // remove my remaining elements
26175 const auto end_index = static_cast<difference_type>(result.size());
26176 while (i < source.size())
26177 {
26178 // add operations in reverse order to avoid invalid
26179 // indices
26181 {
26182 {"op", "remove"},
26183 {"path", path + "/" + std::to_string(i)}
26184 }));
26185 ++i;
26186 }
26187
26188 // add other remaining elements
26189 while (i < target.size())
26190 {
26192 {
26193 {"op", "add"},
26194 {"path", path + "/-"},
26195 {"value", target[i]}
26196 });
26197 ++i;
26198 }
26199
26200 break;
26201 }
26202
26203 case value_t::object:
26204 {
26205 // first pass: traverse this object's elements
26206 for (auto it = source.cbegin(); it != source.cend(); ++it)
26207 {
26208 // escape the key name to be used in a JSON patch
26209 const auto path_key = path + "/" + detail::escape(it.key());
26210
26211 if (target.find(it.key()) != target.end())
26212 {
26213 // recursive call to compare object values at key it
26214 auto temp_diff = diff(it.value(), target[it.key()], path_key);
26216 }
26217 else
26218 {
26219 // found a key that is not in o -> remove it
26221 {
26222 {"op", "remove"}, {"path", path_key}
26223 }));
26224 }
26225 }
26226
26227 // second pass: traverse other object's elements
26228 for (auto it = target.cbegin(); it != target.cend(); ++it)
26229 {
26230 if (source.find(it.key()) == source.end())
26231 {
26232 // found a key that is not in this -> add it
26233 const auto path_key = path + "/" + detail::escape(it.key());
26235 {
26236 {"op", "add"}, {"path", path_key},
26237 {"value", it.value()}
26238 });
26239 }
26240 }
26241
26242 break;
26243 }
26244
26245 case value_t::null:
26246 case value_t::string:
26247 case value_t::boolean:
26248 case value_t::number_integer:
26250 case value_t::number_float:
26251 case value_t::binary:
26252 case value_t::discarded:
26253 default:
26254 {
26255 // both primitive type: replace value
26257 {
26258 {"op", "replace"}, {"path", path}, {"value", target}
26259 });
26260 break;
26261 }
26262 }
26263
26264 return result;
26265 }
26266
26267 /// @}
26268
26269 ////////////////////////////////
26270 // JSON Merge Patch functions //
26271 ////////////////////////////////
26272
26273 /// @name JSON Merge Patch functions
26274 /// @{
26275
26276 /*!
26277 @brief applies a JSON Merge Patch
26278
26279 The merge patch format is primarily intended for use with the HTTP PATCH
26280 method as a means of describing a set of modifications to a target
26281 resource's content. This function applies a merge patch to the current
26282 JSON value.
26283
26284 The function implements the following algorithm from Section 2 of
26285 [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
26286
26287 ```
26288 define MergePatch(Target, Patch):
26289 if Patch is an Object:
26290 if Target is not an Object:
26291 Target = {} // Ignore the contents and set it to an empty Object
26292 for each Name/Value pair in Patch:
26293 if Value is null:
26294 if Name exists in Target:
26295 remove the Name/Value pair from Target
26296 else:
26297 Target[Name] = MergePatch(Target[Name], Value)
26298 return Target
26299 else:
26300 return Patch
26301 ```
26302
26303 Thereby, `Target` is the current object; that is, the patch is applied to
26304 the current value.
26305
26306 @param[in] apply_patch the patch to apply
26307
26308 @complexity Linear in the lengths of @a patch.
26309
26310 @liveexample{The following code shows how a JSON Merge Patch is applied to
26311 a JSON document.,merge_patch}
26312
26313 @sa see @ref patch -- apply a JSON patch
26314 @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
26315
26316 @since version 3.0.0
26317 */
26318 void merge_patch(const basic_json& apply_patch)
26319 {
26320 if (apply_patch.is_object())
26321 {
26322 if (!is_object())
26323 {
26324 *this = object();
26325 }
26326 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
26327 {
26328 if (it.value().is_null())
26329 {
26330 erase(it.key());
26331 }
26332 else
26333 {
26335 }
26336 }
26337 }
26338 else
26339 {
26340 *this = apply_patch;
26341 }
26342 }
26343
26344 /// @}
26345 };
26346
26347 /*!
26348 @brief user-defined to_string function for JSON values
26349
26350 This function implements a user-defined to_string for JSON objects.
26351
26352 @param[in] j a JSON object
26353 @return a std::string object
26354 */
26355
26357 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
26358 {
26359 return j.dump();
26360 }
26361} // namespace nlohmann
26362
26363///////////////////////
26364// nonmember support //
26365///////////////////////
26366
26367// specialization of std::swap, and std::hash
26368namespace std
26369{
26370
26371 /// hash value for JSON objects
26372 template<>
26374 {
26375 /*!
26376 @brief return a hash value for a JSON object
26377
26378 @since version 1.0.0
26379 */
26380 std::size_t operator()(const nlohmann::json& j) const
26381 {
26382 return nlohmann::detail::hash(j);
26383 }
26384 };
26385
26386 /// specialization for std::less<value_t>
26387 /// @note: do not remove the space after '<',
26388 /// see https://github.com/nlohmann/json/pull/679
26389 template<>
26390 struct less<::nlohmann::detail::value_t>
26391 {
26392 /*!
26393 @brief compare two value_t enum values
26394 @since version 3.0.0
26395 */
26396 bool operator()(nlohmann::detail::value_t lhs,
26397 nlohmann::detail::value_t rhs) const noexcept
26398 {
26399 return nlohmann::detail::operator<(lhs, rhs);
26400 }
26401 };
26402
26403 // C++20 prohibit function specialization in the std namespace.
26404#ifndef JSON_HAS_CPP_20
26405
26406/*!
26407@brief exchanges the values of two JSON objects
26408
26409@since version 1.0.0
26410*/
26411 template<>
26412 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
26413 is_nothrow_move_constructible<nlohmann::json>::value&& // NOLINT(misc-redundant-expression)
26415 )
26416 {
26417 j1.swap(j2);
26418 }
26419
26420#endif
26421
26422} // namespace std
26423
26424/*!
26425@brief user-defined string literal for JSON values
26426
26427This operator implements a user-defined string literal for JSON objects. It
26428can be used by adding `"_json"` to a string literal and returns a JSON object
26429if no parse error occurred.
26430
26431@param[in] s a string representation of a JSON object
26432@param[in] n the length of string @a s
26433@return a JSON object
26434
26435@since version 1.0.0
26436*/
26438inline nlohmann::json operator "" _json(const char* s, std::size_t n)
26439{
26440 return nlohmann::json::parse(s, s + n);
26441}
26442
26443/*!
26444@brief user-defined string literal for JSON pointer
26445
26446This operator implements a user-defined string literal for JSON Pointers. It
26447can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
26448object if no parse error occurred.
26449
26450@param[in] s a string representation of a JSON Pointer
26451@param[in] n the length of string @a s
26452@return a JSON pointer object
26453
26454@since version 2.0.0
26455*/
26458{
26459 return nlohmann::json::json_pointer(std::string(s, n));
26460}
26461
26462// #include <nlohmann/detail/macro_unscope.hpp>
26463
26464
26465// restore clang diagnostic settings
26466#if defined(__clang__)
26467#pragma clang diagnostic pop
26468#endif
26469
26470// clean up
26471#undef JSON_ASSERT
26472#undef JSON_INTERNAL_CATCH
26473#undef JSON_CATCH
26474#undef JSON_THROW
26475#undef JSON_TRY
26476#undef JSON_PRIVATE_UNLESS_TESTED
26477#undef JSON_HAS_CPP_11
26478#undef JSON_HAS_CPP_14
26479#undef JSON_HAS_CPP_17
26480#undef JSON_HAS_CPP_20
26481#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
26482#undef NLOHMANN_BASIC_JSON_TPL
26483#undef JSON_EXPLICIT
26484
26485// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
26486
26487
26488#undef JSON_HEDLEY_ALWAYS_INLINE
26489#undef JSON_HEDLEY_ARM_VERSION
26490#undef JSON_HEDLEY_ARM_VERSION_CHECK
26491#undef JSON_HEDLEY_ARRAY_PARAM
26492#undef JSON_HEDLEY_ASSUME
26493#undef JSON_HEDLEY_BEGIN_C_DECLS
26494#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
26495#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
26496#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
26497#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
26498#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
26499#undef JSON_HEDLEY_CLANG_HAS_FEATURE
26500#undef JSON_HEDLEY_CLANG_HAS_WARNING
26501#undef JSON_HEDLEY_COMPCERT_VERSION
26502#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
26503#undef JSON_HEDLEY_CONCAT
26504#undef JSON_HEDLEY_CONCAT3
26505#undef JSON_HEDLEY_CONCAT3_EX
26506#undef JSON_HEDLEY_CONCAT_EX
26507#undef JSON_HEDLEY_CONST
26508#undef JSON_HEDLEY_CONSTEXPR
26509#undef JSON_HEDLEY_CONST_CAST
26510#undef JSON_HEDLEY_CPP_CAST
26511#undef JSON_HEDLEY_CRAY_VERSION
26512#undef JSON_HEDLEY_CRAY_VERSION_CHECK
26513#undef JSON_HEDLEY_C_DECL
26514#undef JSON_HEDLEY_DEPRECATED
26515#undef JSON_HEDLEY_DEPRECATED_FOR
26516#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
26517#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
26518#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
26519#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
26520#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
26521#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
26522#undef JSON_HEDLEY_DIAGNOSTIC_POP
26523#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
26524#undef JSON_HEDLEY_DMC_VERSION
26525#undef JSON_HEDLEY_DMC_VERSION_CHECK
26526#undef JSON_HEDLEY_EMPTY_BASES
26527#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
26528#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
26529#undef JSON_HEDLEY_END_C_DECLS
26530#undef JSON_HEDLEY_FLAGS
26531#undef JSON_HEDLEY_FLAGS_CAST
26532#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
26533#undef JSON_HEDLEY_GCC_HAS_BUILTIN
26534#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
26535#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
26536#undef JSON_HEDLEY_GCC_HAS_EXTENSION
26537#undef JSON_HEDLEY_GCC_HAS_FEATURE
26538#undef JSON_HEDLEY_GCC_HAS_WARNING
26539#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
26540#undef JSON_HEDLEY_GCC_VERSION
26541#undef JSON_HEDLEY_GCC_VERSION_CHECK
26542#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
26543#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
26544#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
26545#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
26546#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
26547#undef JSON_HEDLEY_GNUC_HAS_FEATURE
26548#undef JSON_HEDLEY_GNUC_HAS_WARNING
26549#undef JSON_HEDLEY_GNUC_VERSION
26550#undef JSON_HEDLEY_GNUC_VERSION_CHECK
26551#undef JSON_HEDLEY_HAS_ATTRIBUTE
26552#undef JSON_HEDLEY_HAS_BUILTIN
26553#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
26554#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
26555#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
26556#undef JSON_HEDLEY_HAS_EXTENSION
26557#undef JSON_HEDLEY_HAS_FEATURE
26558#undef JSON_HEDLEY_HAS_WARNING
26559#undef JSON_HEDLEY_IAR_VERSION
26560#undef JSON_HEDLEY_IAR_VERSION_CHECK
26561#undef JSON_HEDLEY_IBM_VERSION
26562#undef JSON_HEDLEY_IBM_VERSION_CHECK
26563#undef JSON_HEDLEY_IMPORT
26564#undef JSON_HEDLEY_INLINE
26565#undef JSON_HEDLEY_INTEL_CL_VERSION
26566#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
26567#undef JSON_HEDLEY_INTEL_VERSION
26568#undef JSON_HEDLEY_INTEL_VERSION_CHECK
26569#undef JSON_HEDLEY_IS_CONSTANT
26570#undef JSON_HEDLEY_IS_CONSTEXPR_
26571#undef JSON_HEDLEY_LIKELY
26572#undef JSON_HEDLEY_MALLOC
26573#undef JSON_HEDLEY_MCST_LCC_VERSION
26574#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
26575#undef JSON_HEDLEY_MESSAGE
26576#undef JSON_HEDLEY_MSVC_VERSION
26577#undef JSON_HEDLEY_MSVC_VERSION_CHECK
26578#undef JSON_HEDLEY_NEVER_INLINE
26579#undef JSON_HEDLEY_NON_NULL
26580#undef JSON_HEDLEY_NO_ESCAPE
26581#undef JSON_HEDLEY_NO_RETURN
26582#undef JSON_HEDLEY_NO_THROW
26583#undef JSON_HEDLEY_NULL
26584#undef JSON_HEDLEY_PELLES_VERSION
26585#undef JSON_HEDLEY_PELLES_VERSION_CHECK
26586#undef JSON_HEDLEY_PGI_VERSION
26587#undef JSON_HEDLEY_PGI_VERSION_CHECK
26588#undef JSON_HEDLEY_PREDICT
26589#undef JSON_HEDLEY_PRINTF_FORMAT
26590#undef JSON_HEDLEY_PRIVATE
26591#undef JSON_HEDLEY_PUBLIC
26592#undef JSON_HEDLEY_PURE
26593#undef JSON_HEDLEY_REINTERPRET_CAST
26594#undef JSON_HEDLEY_REQUIRE
26595#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
26596#undef JSON_HEDLEY_REQUIRE_MSG
26597#undef JSON_HEDLEY_RESTRICT
26598#undef JSON_HEDLEY_RETURNS_NON_NULL
26599#undef JSON_HEDLEY_SENTINEL
26600#undef JSON_HEDLEY_STATIC_ASSERT
26601#undef JSON_HEDLEY_STATIC_CAST
26602#undef JSON_HEDLEY_STRINGIFY
26603#undef JSON_HEDLEY_STRINGIFY_EX
26604#undef JSON_HEDLEY_SUNPRO_VERSION
26605#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
26606#undef JSON_HEDLEY_TINYC_VERSION
26607#undef JSON_HEDLEY_TINYC_VERSION_CHECK
26608#undef JSON_HEDLEY_TI_ARMCL_VERSION
26609#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
26610#undef JSON_HEDLEY_TI_CL2000_VERSION
26611#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
26612#undef JSON_HEDLEY_TI_CL430_VERSION
26613#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
26614#undef JSON_HEDLEY_TI_CL6X_VERSION
26615#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
26616#undef JSON_HEDLEY_TI_CL7X_VERSION
26617#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
26618#undef JSON_HEDLEY_TI_CLPRU_VERSION
26619#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
26620#undef JSON_HEDLEY_TI_VERSION
26621#undef JSON_HEDLEY_TI_VERSION_CHECK
26622#undef JSON_HEDLEY_UNAVAILABLE
26623#undef JSON_HEDLEY_UNLIKELY
26624#undef JSON_HEDLEY_UNPREDICTABLE
26625#undef JSON_HEDLEY_UNREACHABLE
26626#undef JSON_HEDLEY_UNREACHABLE_RETURN
26627#undef JSON_HEDLEY_VERSION
26628#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
26629#undef JSON_HEDLEY_VERSION_DECODE_MINOR
26630#undef JSON_HEDLEY_VERSION_DECODE_REVISION
26631#undef JSON_HEDLEY_VERSION_ENCODE
26632#undef JSON_HEDLEY_WARNING
26633#undef JSON_HEDLEY_WARN_UNUSED_RESULT
26634#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
26635#undef JSON_HEDLEY_FALL_THROUGH
26636
26637
26638
26639#endif // INCLUDE_NLOHMANN_JSON_HPP_
std::string GetApiName() override
std::unique_ptr< ArkApi::IApiUtils > & GetApiUtils() override
static void LoadPluginCmd(APlayerController *, FString *, bool)
std::unique_ptr< ArkApi::IHooks > & GetHooks() override
std::unique_ptr< ArkApi::IApiUtils > api_utils_
Definition ArkBaseApi.h:39
void RegisterCommands() override
float GetVersion() override
std::unique_ptr< ArkApi::ICommands > & GetCommands() override
~ArkBaseApi() override=default
static FString LoadPlugin(FString *cmd)
static void UnloadPluginRcon(RCONClientConnection *, RCONPacket *, UWorld *)
std::unique_ptr< ArkApi::ICommands > commands_
Definition ArkBaseApi.h:37
bool Init() override
static void UnloadPluginCmd(APlayerController *, FString *, bool)
static void LoadPluginRcon(RCONClientConnection *, RCONPacket *, UWorld *)
std::unique_ptr< ArkApi::IHooks > hooks_
Definition ArkBaseApi.h:38
static FString UnloadPlugin(FString *cmd)
BitField GetBitField(const void *base, const std::string &name)
Definition Offsets.cpp:65
DWORD64 module_base_
Definition Offsets.h:36
DWORD64 GetAddress(const void *base, const std::string &name)
Definition Offsets.cpp:50
Offsets & operator=(const Offsets &)=delete
DWORD64 data_base_
Definition Offsets.h:37
LPVOID GetDataAddress(const std::string &name)
Definition Offsets.cpp:60
std::unordered_map< std::string, BitField > bitfields_dump_
Definition Offsets.h:40
Offsets(const Offsets &)=delete
void Init(std::unordered_map< std::string, intptr_t > &&offsets_dump, std::unordered_map< std::string, BitField > &&bitfields_dump)
Definition Offsets.cpp:43
static Offsets & Get()
Definition Offsets.cpp:37
~Offsets()=default
Offsets(Offsets &&)=delete
BitField GetBitFieldInternal(const void *base, const std::string &name)
Definition Offsets.cpp:75
LPVOID GetAddress(const std::string &name)
Definition Offsets.cpp:55
BitField GetBitField(LPVOID base, const std::string &name)
Definition Offsets.cpp:70
std::unordered_map< std::string, intptr_t > offsets_dump_
Definition Offsets.h:39
Offsets & operator=(Offsets &&)=delete
PdbReader()=default
void DumpType(IDiaSymbol *, const std::string &, int) const
std::unordered_set< uint32_t > visited_
Definition PDBReader.h:38
std::unordered_map< std::string, BitField > * bitfields_dump_
Definition PDBReader.h:36
void DumpFunctions(IDiaSymbol *)
static void LoadDataFromPdb(const std::wstring &, IDiaDataSource **, IDiaSession **, IDiaSymbol **)
Definition PDBReader.cpp:82
std::unordered_map< std::string, intptr_t > * offsets_dump_
Definition PDBReader.h:35
static uint32_t GetSymbolId(IDiaSymbol *)
void DumpData(IDiaSymbol *, const std::string &) const
void DumpGlobalVariables(IDiaSymbol *)
void Read(const std::wstring &path, std::unordered_map< std::string, intptr_t > *offsets_dump, std::unordered_map< std::string, BitField > *bitfields_dump)
Definition PDBReader.cpp:44
void DumpStructs(IDiaSymbol *)
~PdbReader()=default
static void Cleanup(IDiaSymbol *, IDiaSession *, IDiaDataSource *)
static std::string GetSymbolNameString(IDiaSymbol *)
static PluginManager & Get()
std::shared_ptr< Plugin > & LoadPlugin(const std::string &plugin_name) noexcept(false)
Load plugin by it's name.
void UnloadPlugin(const std::string &plugin_name) noexcept(false)
Unload plugin by it's name. Plugin must free all used resources.
virtual void AddRconCommand(const FString &command, const std::function< void(RCONClientConnection *, RCONPacket *, UWorld *)> &callback)=0
Adds a rcon command.
virtual void AddConsoleCommand(const FString &command, const std::function< void(APlayerController *, FString *, bool)> &callback)=0
Adds a console command.
static const FColor Green
Definition ColorList.h:13
FORCEINLINE const TCHAR * operator*() const
Definition FString.h:282
number_unsigned_t number_unsigned
number (unsigned integer)
Definition json.hpp:18393
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition json.hpp:25618
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition json.hpp:25590
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(const T *ptr, std::size_t len, const bool strict=true, const bool allow_exceptions=true)
Definition json.hpp:25298
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(const T *ptr, std::size_t len, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition json.hpp:25155
basic_json(const value_t v)
create an empty value with a given type
Definition json.hpp:18878
static std::vector< std::uint8_t > to_bson(const basic_json &j)
Serializes the given JSON object j to BSON and returns a vector containing the corresponding BSON-rep...
Definition json.hpp:24990
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition json.hpp:24809
json_value(object_t &&value)
constructor for rvalue objects
Definition json.hpp:18498
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition json.hpp:24714
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition json.hpp:18406
void assert_invariant(bool check_parents=true) const noexcept
checks the class invariants
Definition json.hpp:18657
json_value(string_t &&value)
constructor for rvalue strings
Definition json.hpp:18486
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition json.hpp:18402
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition json.hpp:17758
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition json.hpp:18404
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition json.hpp:25514
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition json.hpp:25123
static void to_bson(const basic_json &j, detail::output_adapter< std::uint8_t > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition json.hpp:25005
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition json.hpp:25498
json_value(value_t t)
constructor for empty values of a given type
Definition json.hpp:18408
friend struct detail::external_constructor
Definition json.hpp:17583
static std::vector< std::uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition json.hpp:24912
json_value m_value
the value of the current element
Definition json.hpp:24601
boolean_t boolean
boolean
Definition json.hpp:18389
json_value(const string_t &value)
constructor for strings
Definition json.hpp:18480
json_value(const binary_t &value)
constructor for binary arrays (internal type)
Definition json.hpp:18528
json_value(const array_t &value)
constructor for arrays
Definition json.hpp:18504
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition json.hpp:25704
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition json.hpp:26318
void destroy(value_t t)
Definition json.hpp:18539
json_value(const object_t &value)
constructor for objects
Definition json.hpp:18492
json_value(typename binary_t::container_type &&value)
constructor for rvalue binary arrays
Definition json.hpp:18522
json_value(boolean_t v) noexcept
constructor for booleans
Definition json.hpp:18400
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition json.hpp:25283
static JSON_HEDLEY_RETURNS_NON_NULL T * create(Args &&... args)
helper for exception-safe object creation
Definition json.hpp:18333
binary_t * binary
binary (stored with pointer to save storage)
Definition json.hpp:18387
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition json.hpp:25400
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition json.hpp:25661
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition json.hpp:25384
static void to_ubjson(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
Definition json.hpp:24921
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(const T *ptr, std::size_t len, const bool strict=true, const bool allow_exceptions=true)
Definition json.hpp:25414
basic_json flatten() const
return flattened JSON value
Definition json.hpp:25731
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition json.hpp:25140
json_value(const typename binary_t::container_type &value)
constructor for binary arrays
Definition json.hpp:18516
json_value()=default
default constructor (for null values)
number_float_t number_float
number (floating-point)
Definition json.hpp:18395
string_t * string
string (stored with pointer to save storage)
Definition json.hpp:18385
static void to_cbor(const basic_json &j, detail::output_adapter< std::uint8_t > o)
Definition json.hpp:24721
json_value(binary_t &&value)
constructor for rvalue binary arrays (internal type)
Definition json.hpp:18534
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition json.hpp:18902
array_t * array
array (stored with pointer to save storage)
Definition json.hpp:18383
number_integer_t number_integer
number (integer)
Definition json.hpp:18391
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition json.hpp:25267
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition json.hpp:25829
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
Definition json.hpp:18974
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition json.hpp:25768
reference set_parent(reference j, std::size_t old_capacity=std::size_t(-1))
Definition json.hpp:18728
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(const T *ptr, std::size_t len, const bool strict=true, const bool allow_exceptions=true)
Definition json.hpp:25528
json_value(array_t &&value)
constructor for rvalue arrays
Definition json.hpp:18510
static void to_msgpack(const basic_json &j, detail::output_adapter< std::uint8_t > o)
Definition json.hpp:24816
static allocator_type get_allocator()
returns the allocator associated with the container
Definition json.hpp:17726
an internal type for a backed binary type
Definition json.hpp:5034
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition json.hpp:5053
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition json.hpp:5045
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition json.hpp:5049
bool operator!=(const byte_container_with_subtype &rhs) const
Definition json.hpp:5071
void clear_subtype() noexcept
clears the binary subtype
Definition json.hpp:5167
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition json.hpp:5041
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition json.hpp:5059
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition json.hpp:5143
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition json.hpp:5094
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition json.hpp:5122
bool operator==(const byte_container_with_subtype &rhs) const
Definition json.hpp:5065
deserialization of CBOR, MessagePack, and UBJSON values
Definition json.hpp:8354
bool get_msgpack_array(const std::size_t len)
Definition json.hpp:10045
binary_reader & operator=(const binary_reader &)=delete
bool get_bson_string(const NumberType len, string_t &result)
Parses a zero-terminated string of length len from the BSON input.
Definition json.hpp:8508
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
Definition json.hpp:8671
char_int_type get_ignore_noop()
Definition json.hpp:10618
binary_reader(InputAdapterType &&adapter) noexcept
create a binary reader
Definition json.hpp:8370
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
Definition json.hpp:8478
bool get_cbor_array(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition json.hpp:9378
bool get_msgpack_binary(binary_t &result)
reads a MessagePack byte array
Definition json.hpp:9934
bool get_cbor_object(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition json.hpp:9416
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
Definition json.hpp:10123
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
Definition json.hpp:8633
bool parse_cbor_internal(const bool get_char, const cbor_tag_handler_t tag_handler)
Definition json.hpp:8701
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
Definition json.hpp:10685
bool get_cbor_string(string_t &result)
reads a CBOR string
Definition json.hpp:9189
InputAdapterType ia
input adapter
Definition json.hpp:10802
bool get_binary(const input_format_t format, const NumberType len, binary_t &result)
create a byte array by reading bytes from the input
Definition json.hpp:10718
bool parse_ubjson_internal(const bool get_char=true)
Definition json.hpp:10104
bool unexpect_eof(const input_format_t format, const char *context) const
Definition json.hpp:10742
binary_reader & operator=(binary_reader &&)=default
std::string get_token_string() const
Definition json.hpp:10755
bool get_msgpack_object(const std::size_t len)
Definition json.hpp:10067
bool get_bson_binary(const NumberType len, binary_t &result)
Parses a byte array input of length len from the BSON input.
Definition json.hpp:8529
std::size_t chars_read
the number of characters read
Definition json.hpp:10808
binary_reader(const binary_reader &)=delete
char_int_type current
the current character
Definition json.hpp:10805
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition json.hpp:8391
json_sax_t * sax
the SAX parser
Definition json.hpp:10814
bool get_ubjson_size_value(std::size_t &result)
Definition json.hpp:10177
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
Definition json.hpp:8453
bool get_number(const input_format_t format, NumberType &result)
Definition json.hpp:10642
bool get_cbor_binary(binary_t &result)
reads a CBOR byte array
Definition json.hpp:9284
binary_reader(binary_reader &&)=default
char_int_type get()
get next character from the input
Definition json.hpp:10609
const bool is_little_endian
whether we can assume little endianess
Definition json.hpp:10811
bool get_msgpack_string(string_t &result)
reads a MessagePack string
Definition json.hpp:9852
serialization to CBOR and MessagePack values
Definition json.hpp:13600
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
Definition json.hpp:14676
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition json.hpp:14298
static std::size_t calc_bson_entry_header_size(const string_t &name, const BasicJsonType &j)
Definition json.hpp:14506
void write_bson_entry_header(const string_t &name, const std::uint8_t element_type)
Writes the given element_type and name to the output adapter.
Definition json.hpp:14521
static std::size_t calc_bson_element_size(const string_t &name, const BasicJsonType &j)
Calculates the size necessary to serialize the JSON value j with its name.
Definition json.hpp:14710
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
Definition json.hpp:14543
void write_bson_object(const typename BasicJsonType::object_t &value)
Definition json.hpp:14820
static constexpr CharType get_cbor_float_prefix(float)
Definition json.hpp:14836
static constexpr CharType get_msgpack_float_prefix(double)
Definition json.hpp:14855
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
Definition json.hpp:14593
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
Definition json.hpp:14561
void write_bson_object_entry(const string_t &name, const typename BasicJsonType::object_t &value)
Writes a BSON element with key name and object value.
Definition json.hpp:14643
output_adapter_t< CharType > oa
the output
Definition json.hpp:15203
void write_bson_element(const string_t &name, const BasicJsonType &j)
Serializes the JSON value j to BSON and associates it with the key name.
Definition json.hpp:14758
void write_bson_binary(const string_t &name, const binary_t &value)
Writes a BSON element with key name and binary value value.
Definition json.hpp:14695
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
Definition json.hpp:14575
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t &value)
Definition json.hpp:14668
void write_bson(const BasicJsonType &j)
Definition json.hpp:13620
void write_cbor(const BasicJsonType &j)
Definition json.hpp:13649
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
Definition json.hpp:14611
void write_bson_unsigned(const string_t &name, const BasicJsonType &j)
Writes a BSON element with key name and unsigned value.
Definition json.hpp:14621
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
Calculates the size of the BSON serialization of the given JSON-object j.
Definition json.hpp:14805
static constexpr CharType get_msgpack_float_prefix(float)
Definition json.hpp:14850
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
Definition json.hpp:14533
void write_msgpack(const BasicJsonType &j)
Definition json.hpp:13973
static std::size_t calc_bson_string_size(const string_t &value)
Definition json.hpp:14553
static std::size_t calc_bson_integer_size(const std::int64_t value)
Definition json.hpp:14583
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
Definition json.hpp:14653
static constexpr CharType get_cbor_float_prefix(double)
Definition json.hpp:14841
general exception of the basic_json class
Definition json.hpp:2651
const int id
the id of the exception
Definition json.hpp:2660
std::runtime_error m
an exception object as storage for error messages
Definition json.hpp:2737
const char * what() const noexcept override
returns the explanatory string
Definition json.hpp:2654
exception(int id_, const char *what_arg)
Definition json.hpp:2664
file_input_adapter(const file_input_adapter &)=delete
file_input_adapter & operator=(file_input_adapter &&)=delete
file_input_adapter(file_input_adapter &&) noexcept=default
file_input_adapter & operator=(const file_input_adapter &)=delete
file_input_adapter(std::FILE *f) noexcept
Definition json.hpp:5375
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition json.hpp:5430
input_stream_adapter & operator=(input_stream_adapter &)=delete
input_stream_adapter(const input_stream_adapter &)=delete
input_stream_adapter & operator=(input_stream_adapter &&)=delete
exception indicating errors with iterators
Definition json.hpp:2874
invalid_iterator(int id_, const char *what_arg)
Definition json.hpp:2885
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition json.hpp:11530
bool operator<(const iter_impl &other) const
comparison: smaller
Definition json.hpp:11993
iter_impl operator-(difference_type i) const
subtract from iterator
Definition json.hpp:12123
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition json.hpp:11984
iter_impl const operator--(int)
post-decrement (it–)
Definition json.hpp:11896
void set_end() noexcept
set the iterator past the last value
Definition json.hpp:11720
iter_impl & operator=(iter_impl &&) noexcept=default
iter_impl & operator--()
pre-decrement (–it)
Definition json.hpp:11907
difference_type operator-(const iter_impl &other) const
return difference
Definition json.hpp:12134
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition json.hpp:11639
reference operator*() const
return a reference to the value pointed to by the iterator
Definition json.hpp:11759
iter_impl(iter_impl &&) noexcept=default
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition json.hpp:12046
pointer operator->() const
dereference the iterator
Definition json.hpp:11803
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition json.hpp:11629
iter_impl const operator++(int)
post-increment (it++)
Definition json.hpp:11845
iter_impl operator+(difference_type i) const
add to iterator
Definition json.hpp:12101
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition json.hpp:12112
const object_t::key_type & key() const
return the key of an object iterator
Definition json.hpp:12201
bool operator==(const IterImpl &other) const
comparison: equal
Definition json.hpp:11948
bool operator>(const iter_impl &other) const
comparison: greater than
Definition json.hpp:12037
reference value() const
return the value of an iterator
Definition json.hpp:12217
iter_impl & operator++()
pre-increment (++it)
Definition json.hpp:11856
reference operator[](difference_type n) const
access to successor
Definition json.hpp:12163
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition json.hpp:12028
iter_impl & operator+=(difference_type i)
add to iterator
Definition json.hpp:12055
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition json.hpp:12092
IteratorType anchor
the iterator
Definition json.hpp:4385
const string_type empty_str
an empty string (to return a reference for primitive values)
Definition json.hpp:4393
iteration_proxy_value(IteratorType it) noexcept
Definition json.hpp:4396
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition json.hpp:4422
std::size_t array_index_last
last stringified array index
Definition json.hpp:4389
string_type array_index_str
a string representation of the array index
Definition json.hpp:4391
IteratorType::reference value() const
return value of the iterator
Definition json.hpp:4464
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition json.hpp:4407
std::size_t array_index
an index for arrays (used to create key names)
Definition json.hpp:4387
iteration_proxy_value & operator*()
dereference operator (needed for range-based for)
Definition json.hpp:4401
const string_type & key() const
return key of the iterator
Definition json.hpp:4428
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition json.hpp:4416
proxy class for the items() function
Definition json.hpp:4472
iteration_proxy_value< IteratorType > begin() noexcept
return iterator begin (needed for range-based for)
Definition json.hpp:4483
iteration_proxy_value< IteratorType > end() noexcept
return iterator end (needed for range-based for)
Definition json.hpp:4489
IteratorType::reference container
the container to iterate
Definition json.hpp:4475
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition json.hpp:4479
iterator_input_adapter(IteratorType first, IteratorType last)
Definition json.hpp:5466
json_ref & operator=(const json_ref &)=delete
value_type const * value_ref
Definition json.hpp:13417
json_ref(const json_ref &)=delete
value_type const & operator*() const
Definition json.hpp:13405
json_ref(Args &&... args)
Definition json.hpp:13385
json_ref(const value_type &value)
Definition json.hpp:13374
value_type const * operator->() const
Definition json.hpp:13410
json_ref & operator=(json_ref &&)=delete
json_ref(value_type &&value)
Definition json.hpp:13370
value_type moved_or_copied() const
Definition json.hpp:13396
a template for a reverse iterator class
Definition json.hpp:12268
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition json.hpp:12296
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition json.hpp:12320
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition json.hpp:12308
reference operator[](difference_type n) const
access to successor
Definition json.hpp:12332
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition json.hpp:12326
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition json.hpp:12314
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition json.hpp:12284
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition json.hpp:12338
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition json.hpp:12302
reference value() const
return the value of an iterator
Definition json.hpp:12345
json_reverse_iterator & operator++()
pre-increment (++it)
Definition json.hpp:12290
bool start_object(std::size_t=std::size_t(-1))
Definition json.hpp:6498
bool start_array(std::size_t=std::size_t(-1))
Definition json.hpp:6513
bool number_integer(number_integer_t)
Definition json.hpp:6473
bool number_unsigned(number_unsigned_t)
Definition json.hpp:6478
bool number_float(number_float_t, const string_t &)
Definition json.hpp:6483
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition json.hpp:6448
BasicJsonType * object_element
helper to hold the reference for the next object element
Definition json.hpp:6442
const parser_callback_t callback
callback function
Definition json.hpp:6446
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
bool number_integer(number_integer_t val)
Definition json.hpp:6185
BasicJsonType & root
the parsed JSON value
Definition json.hpp:6434
std::vector< BasicJsonType * > ref_stack
stack to model hierarchy of values
Definition json.hpp:6436
BasicJsonType discarded
a discarded value for the callback
Definition json.hpp:6450
std::vector< bool > key_keep_stack
stack to manage which object keys to keep
Definition json.hpp:6440
bool errored
whether a syntax error occurred
Definition json.hpp:6444
std::vector< bool > keep_stack
stack to manage which values to keep
Definition json.hpp:6438
bool number_unsigned(number_unsigned_t val)
Definition json.hpp:6191
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
bool number_float(number_float_t val, const string_t &)
Definition json.hpp:6197
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition json.hpp:6158
SAX implementation to create a JSON value from SAX events.
Definition json.hpp:5974
bool start_array(std::size_t len)
Definition json.hpp:6066
json_sax_dom_parser(const json_sax_dom_parser &)=delete
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
bool number_unsigned(number_unsigned_t val)
Definition json.hpp:6016
bool errored
whether a syntax error occurred
Definition json.hpp:6141
JSON_HEDLEY_RETURNS_NON_NULL BasicJsonType * handle_value(Value &&v)
Definition json.hpp:6112
bool start_object(std::size_t len)
Definition json.hpp:6040
BasicJsonType * object_element
helper to hold the reference for the next object element
Definition json.hpp:6139
std::vector< BasicJsonType * > ref_stack
stack to model hierarchy of values
Definition json.hpp:6137
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition json.hpp:6143
constexpr bool is_errored() const
Definition json.hpp:6098
json_sax_dom_parser(json_sax_dom_parser &&)=default
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
BasicJsonType & root
the parsed JSON value
Definition json.hpp:6135
bool number_float(number_float_t val, const string_t &)
Definition json.hpp:6022
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition json.hpp:5987
bool number_integer(number_integer_t val)
Definition json.hpp:6010
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition json.hpp:6589
token_type
token types for the parser
Definition json.hpp:6566
@ value_float
an floating point number – use get_number_float() for actual value
@ begin_array
the character for array begin [
@ value_string
a string – use get_string() for actual value
@ end_array
the character for array end ]
@ uninitialized
indicating the scanner is uninitialized
@ parse_error
indicating a parse error
@ value_integer
a signed integer – use get_number_integer() for actual value
@ value_separator
the value separator ,
@ end_object
the character for object end }
@ begin_object
the character for object begin {
@ value_unsigned
an unsigned integer – use get_number_unsigned() for actual value
@ end_of_input
indicating the end of the input buffer
@ literal_or_value
a literal or the begin of a value (only for diagnostics)
lexical analysis
Definition json.hpp:6639
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition json.hpp:7957
number_float_t value_float
Definition json.hpp:8151
const bool ignore_comments
whether comments should be ignored (true) or signaled as errors (false)
Definition json.hpp:8128
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition json.hpp:7847
token_type scan()
Definition json.hpp:8035
bool next_unget
whether the next get() call should just return current
Definition json.hpp:8134
char_int_type current
the current character
Definition json.hpp:8131
static JSON_HEDLEY_PURE char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition json.hpp:6670
number_integer_t value_integer
Definition json.hpp:8149
InputAdapterType ia
input adapter
Definition json.hpp:8125
lexer & operator=(lexer &&)=default
static void strtof(float &f, const char *str, char **endptr) noexcept
Definition json.hpp:7439
const char_int_type decimal_point_char
the decimal point
Definition json.hpp:8154
bool skip_bom()
skip the UTF-8 byte order mark
Definition json.hpp:8013
const char * error_message
a description of occurred lexer errors
Definition json.hpp:8146
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition json.hpp:6650
position_t position
the start position of the current token
Definition json.hpp:8137
constexpr position_t get_position() const noexcept
return position of last read token
Definition json.hpp:7967
std::vector< char_type > token_string
raw input token string (for error messages)
Definition json.hpp:8140
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition json.hpp:7939
char_int_type get()
Definition json.hpp:7864
token_type scan_number()
scan a number literal
Definition json.hpp:7496
lexer & operator=(lexer &)=delete
void unget()
unget current character (read it again on next get)
Definition json.hpp:7901
token_type scan_string()
scan a string literal
Definition json.hpp:6781
lexer(const lexer &)=delete
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition json.hpp:7945
string_t token_buffer
buffer for variable-length tokens (numbers, strings)
Definition json.hpp:8143
static void strtof(double &f, const char *str, char **endptr) noexcept
Definition json.hpp:7445
token_type scan_literal(const char_type *literal_text, const std::size_t length, token_type return_type)
Definition json.hpp:7827
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition json.hpp:7951
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition json.hpp:6696
std::string get_token_string() const
Definition json.hpp:7975
static void strtof(long double &f, const char *str, char **endptr) noexcept
Definition json.hpp:7451
number_unsigned_t value_unsigned
Definition json.hpp:8150
lexer(lexer &&)=default
bool scan_comment()
scan a comment
Definition json.hpp:7371
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition json.hpp:8000
exception indicating other library errors
Definition json.hpp:3016
other_error(int id_, const char *what_arg)
Definition json.hpp:3027
exception indicating access out of the defined range
Definition json.hpp:2977
out_of_range(int id_, const char *what_arg)
Definition json.hpp:2988
output_adapter(std::basic_ostream< CharType > &s)
Definition json.hpp:13568
output adapter for output streams
Definition json.hpp:13514
void write_character(CharType c) override
Definition json.hpp:13520
std::basic_ostream< CharType > & stream
Definition json.hpp:13532
void write_characters(const CharType *s, std::size_t length) override
Definition json.hpp:13526
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition json.hpp:13516
output adapter for basic_string
Definition json.hpp:13539
void write_character(CharType c) override
Definition json.hpp:13545
void write_characters(const CharType *s, std::size_t length) override
Definition json.hpp:13551
output_string_adapter(StringType &s) noexcept
Definition json.hpp:13541
output adapter for byte vectors
Definition json.hpp:13489
std::vector< CharType > & v
Definition json.hpp:13507
void write_characters(const CharType *s, std::size_t length) override
Definition json.hpp:13501
void write_character(CharType c) override
Definition json.hpp:13495
exception indicating a parse error
Definition json.hpp:2786
parse_error(int id_, std::size_t byte_, const char *what_arg)
Definition json.hpp:2826
const std::size_t byte
byte index of the parse error
Definition json.hpp:2823
static std::string position_string(const position_t &pos)
Definition json.hpp:2829
syntax analysis
Definition json.hpp:10883
lexer_t m_lexer
the lexer
Definition json.hpp:11323
bool sax_parse(SAX *sax, const bool strict=true)
Definition json.hpp:10983
token_type get_token()
get next token from lexer
Definition json.hpp:11283
token_type last_token
the type of the last read token
Definition json.hpp:11321
bool accept(const bool strict=true)
public accept interface
Definition json.hpp:10975
bool sax_parse_internal(SAX *sax)
Definition json.hpp:11002
const parser_callback_t< BasicJsonType > callback
callback function
Definition json.hpp:11319
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition json.hpp:10915
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition json.hpp:11325
primitive_iterator_t operator+(difference_type n) noexcept
Definition json.hpp:11407
primitive_iterator_t & operator++() noexcept
Definition json.hpp:11419
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition json.hpp:11392
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition json.hpp:11451
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition json.hpp:11386
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition json.hpp:11402
void set_begin() noexcept
set iterator to a defined beginning
Definition json.hpp:11374
primitive_iterator_t const operator++(int) noexcept
Definition json.hpp:11425
static constexpr difference_type end_value
Definition json.hpp:11361
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition json.hpp:11397
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition json.hpp:11414
primitive_iterator_t & operator--() noexcept
Definition json.hpp:11432
void set_end() noexcept
set iterator to a defined past the end
Definition json.hpp:11380
constexpr difference_type get_value() const noexcept
Definition json.hpp:11368
primitive_iterator_t const operator--(int) noexcept
Definition json.hpp:11438
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition json.hpp:11445
static constexpr difference_type begin_value
Definition json.hpp:11360
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition json.hpp:17280
const std::lconv * loc
the locale
Definition json.hpp:17265
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition json.hpp:17262
static constexpr std::uint8_t UTF8_ACCEPT
Definition json.hpp:16375
serializer(serializer &&)=delete
serializer & operator=(serializer &&)=delete
const char decimal_point
the locale's decimal point character
Definition json.hpp:17269
const char thousands_sep
the locale's thousand separator character
Definition json.hpp:17267
serializer & operator=(const serializer &)=delete
static constexpr std::uint8_t UTF8_REJECT
Definition json.hpp:16376
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition json.hpp:16424
const char indent_char
the indentation character
Definition json.hpp:17275
std::array< char, 512 > string_buffer
string buffer
Definition json.hpp:17272
JSON_PRIVATE_UNLESS_TESTED const bool ensure_ascii
Definition json.hpp:16709
serializer(const serializer &)=delete
string_t indent_string
the indentation string
Definition json.hpp:17277
exception indicating executing a member function with a wrong type
Definition json.hpp:2929
type_error(int id_, const char *what_arg)
Definition json.hpp:2940
std::size_t utf8_bytes_index
index to the utf8_codes array for the next valid byte
Definition json.hpp:5659
std::size_t utf8_bytes_filled
number of valid bytes in the utf8_codes array
Definition json.hpp:5661
wide_string_input_adapter(BaseInputAdapter base)
Definition json.hpp:5626
std::string to_string() const
return a string representation of the JSON pointer
Definition json.hpp:12425
friend class basic_json
Definition json.hpp:12383
json_pointer result
Definition json.hpp:12745
#define JSON_HEDLEY_PGI_VERSION_CHECK(major, minor, patch)
Definition json.hpp:331
#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)
Definition json.hpp:2470
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition json.hpp:2339
#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)
Definition json.hpp:2457
#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)
Definition json.hpp:2464
#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major, minor, patch)
Definition json.hpp:463
#define JSON_HEDLEY_CONST
Definition json.hpp:1670
#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major, minor, patch)
Definition json.hpp:495
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition json.hpp:954
#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)
Definition json.hpp:2461
#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major, minor, patch)
Definition json.hpp:447
#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)
Definition json.hpp:2482
#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)
Definition json.hpp:2483
#define JSON_USE_IMPLICIT_CONVERSIONS
Definition json.hpp:2508
#define JSON_HEDLEY_UNPREDICTABLE(expr)
Definition json.hpp:1569
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition json.hpp:1300
#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)
Definition json.hpp:2466
#define JSON_PRIVATE_UNLESS_TESTED
Definition json.hpp:2302
#define JSON_HEDLEY_UNREACHABLE()
Definition json.hpp:1431
#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
Definition json.hpp:2440
#define NLOHMANN_JSON_VERSION_PATCH
Definition json.hpp:35
#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)
Definition json.hpp:2442
#define NLOHMANN_JSON_TO(v1)
Definition json.hpp:2486
#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)
Definition json.hpp:2445
#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)
Definition json.hpp:2456
#define JSON_HEDLEY_LIKELY(expr)
Definition json.hpp:1565
#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)
Definition json.hpp:2454
#define JSON_HEDLEY_IS_CONSTANT(expr)
Definition json.hpp:2001
#define JSON_HEDLEY_TINYC_VERSION_CHECK(major, minor, patch)
Definition json.hpp:583
#define JSON_HEDLEY_TI_VERSION_CHECK(major, minor, patch)
Definition json.hpp:431
nlohmann::json::json_pointer operator""_json_pointer(const char *s, std::size_t n)
user-defined string literal for JSON pointer
Definition json.hpp:26457
#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)
Definition json.hpp:2449
#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)
Definition json.hpp:2478
#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
Definition json.hpp:2437
#define JSON_HEDLEY_HAS_WARNING(warning)
Definition json.hpp:871
#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)
Definition json.hpp:2476
#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4)
Definition json.hpp:2425
#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major, minor, patch)
Definition json.hpp:353
#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)
Definition json.hpp:2471
#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)
Definition json.hpp:2450
#define JSON_HEDLEY_NON_NULL(...)
Definition json.hpp:1458
#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3)
Definition json.hpp:2424
#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x)
Definition json.hpp:992
#define JSON_INTERNAL_CATCH(exception)
Definition json.hpp:2269
#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
Definition json.hpp:2432
#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)
Definition json.hpp:2448
#define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major, minor, patch)
Definition json.hpp:315
#define JSON_HEDLEY_CRAY_VERSION_CHECK(major, minor, patch)
Definition json.hpp:547
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition json.hpp:1899
#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major, minor, patch)
Definition json.hpp:511
#define JSON_HEDLEY_IBM_VERSION_CHECK(major, minor, patch)
Definition json.hpp:407
#define NLOHMANN_JSON_PASTE2(func, v1)
Definition json.hpp:2422
#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)
Definition json.hpp:2465
#define JSON_CATCH(exception)
Definition json.hpp:2268
#define JSON_ASSERT(x)
Definition json.hpp:2295
#define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major, minor, patch)
Definition json.hpp:647
#define JSON_THROW(exception)
Definition json.hpp:2266
#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5)
Definition json.hpp:2426
#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)
Definition json.hpp:2472
#define JSON_HEDLEY_ASSUME(expr)
Definition json.hpp:1416
#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)
Definition json.hpp:2479
#define JSON_HEDLEY_HAS_FEATURE(feature)
Definition json.hpp:790
#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)
Definition json.hpp:2477
#define NLOHMANN_JSON_VERSION_MAJOR
Definition json.hpp:33
#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
Definition json.hpp:2439
#define NLOHMANN_BASIC_JSON_TPL
Definition json.hpp:2348
#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)
Definition json.hpp:2473
#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)
Definition json.hpp:2446
#define JSON_HEDLEY_IAR_VERSION_CHECK(major, minor, patch)
Definition json.hpp:567
#define NLOHMANN_JSON_FROM(v1)
Definition json.hpp:2487
#define JSON_HEDLEY_UNLIKELY(expr)
Definition json.hpp:1566
#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
Definition json.hpp:2434
#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)
Definition json.hpp:2484
#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
Definition json.hpp:2435
#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)
Definition json.hpp:2463
#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7)
Definition json.hpp:2428
#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)
Definition json.hpp:2460
#define NLOHMANN_JSON_PASTE(...)
Definition json.hpp:2357
#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)
Definition json.hpp:2447
#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)
Definition json.hpp:2462
#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)
Definition json.hpp:2458
#define JSON_TRY
Definition json.hpp:2267
#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)
Definition json.hpp:2431
#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
Definition json.hpp:2433
#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)
Definition json.hpp:2480
#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major, minor, patch)
Definition json.hpp:527
#define NLOHMANN_JSON_PASTE3(func, v1, v2)
Definition json.hpp:2423
#define JSON_HEDLEY_GCC_VERSION_CHECK(major, minor, patch)
Definition json.hpp:678
#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6)
Definition json.hpp:2427
#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)
Definition json.hpp:2453
#define JSON_HEDLEY_GCC_HAS_WARNING(warning, major, minor, patch)
Definition json.hpp:889
#define NLOHMANN_JSON_VERSION_MINOR
Definition json.hpp:34
#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)
Definition json.hpp:2468
#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major, minor, patch)
Definition json.hpp:479
#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)
Definition json.hpp:2475
#define JSON_HEDLEY_CONSTEXPR
Definition json.hpp:1503
#define JSON_HEDLEY_MSVC_VERSION_CHECK(major, minor, patch)
Definition json.hpp:275
#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)
Definition json.hpp:2474
#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)
Definition json.hpp:2443
#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)
Definition json.hpp:2467
#define JSON_HEDLEY_HAS_BUILTIN(builtin)
Definition json.hpp:763
#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)
Definition json.hpp:2481
#define JSON_DIAGNOSTICS
Definition json.hpp:2518
#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9)
Definition json.hpp:2430
#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)
Definition json.hpp:2444
#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)
Definition json.hpp:2469
#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)
Definition json.hpp:2451
#define JSON_HEDLEY_INTEL_VERSION_CHECK(major, minor, patch)
Definition json.hpp:299
#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)
Definition json.hpp:2441
nlohmann::json operator""_json(const char *s, std::size_t n)
user-defined string literal for JSON values
Definition json.hpp:26438
#define JSON_HEDLEY_PRAGMA(value)
Definition json.hpp:915
#define JSON_HEDLEY_ARM_VERSION_CHECK(major, minor, patch)
Definition json.hpp:387
#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
Definition json.hpp:2436
#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8)
Definition json.hpp:2429
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition json.hpp:955
#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)
Definition json.hpp:2455
#define JSON_EXPLICIT
Definition json.hpp:2512
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition json.hpp:1248
#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)
Definition json.hpp:2452
#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)
Definition json.hpp:2459
#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute, major, minor, patch)
Definition json.hpp:709
#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
Definition json.hpp:2438
#define JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
Definition json.hpp:691
#define JSON_HEDLEY_PURE
Definition json.hpp:1639
#define NLOHMANN_JSON_EXPAND(x)
Definition json.hpp:2355
#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,...)
Definition json.hpp:2356
Definition IBaseApi.h:9
constexpr float api_version
ARK_API std::string GetCurrentDir()
Definition Tools.cpp:7
ARK_API std::wstring Utf8Decode(const std::string &str)
Converts an UTF8 string to a wide Unicode String.
Definition Tools.cpp:56
IApiUtils & GetApiUtils()
Definition ApiUtils.cpp:99
void InitHooks()
Definition HooksImpl.cpp:31
constexpr const auto & to_json
Definition json.hpp:4936
constexpr const auto & from_json
Definition json.hpp:4332
implements the Grisu2 algorithm for binary to decimal floating-point conversion.
Definition json.hpp:15263
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition json.hpp:16046
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition json.hpp:16198
Target reinterpret_bits(const Source source)
Definition json.hpp:15266
boundaries compute_boundaries(FloatType value)
Definition json.hpp:15407
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition json.hpp:15710
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition json.hpp:15764
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition json.hpp:16146
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition json.hpp:15805
void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value)
Definition json.hpp:16106
cached_power get_cached_power_for_binary_exponent(int e)
Definition json.hpp:15546
detail namespace with internal helper functions
Definition json.hpp:91
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition json.hpp:147
value_t
the JSON type enumeration
Definition json.hpp:121
@ number_integer
number value (signed integer)
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition json.hpp:3895
void int_to_string(string_type &target, std::size_t value)
Definition json.hpp:4367
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition json.hpp:16283
file_input_adapter input_adapter(std::FILE *file)
Definition json.hpp:5745
cbor_tag_handler_t
how to treat CBOR tags
Definition json.hpp:8326
@ store
store tags as binary type
@ error
throw a parse_error exception in case of a tag
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
error_handler_t
how to treat decoding errors
Definition json.hpp:16361
@ strict
throw a type_error exception in case of invalid UTF-8
@ ignore
ignore invalid UTF-8 sequences
@ replace
replace invalid UTF-8 sequences with U+FFFD
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition json.hpp:5204
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition json.hpp:5222
input_format_t
the supported input formats
Definition json.hpp:5358
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition json.hpp:4498
static bool little_endianess(int num=1) noexcept
determine system byte order
Definition json.hpp:8339
namespace for Niels Lohmann
Definition json.hpp:89
Definition json.hpp:4518
#define __has_feature(x)
Definition os.h:53
void SendMessageW(int Id, int Type, FString *OutGoingMessage)
Definition Other.h:122
int Id
Definition Other.h:129
FString Body
Definition Other.h:131
static auto from_json(BasicJsonType &&j, TargetType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition json.hpp:4963
static auto from_json(BasicJsonType &&j) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))
convert a JSON value to any value type
Definition json.hpp:4983
static auto to_json(BasicJsonType &j, TargetType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< TargetType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< TargetType >(val)), void())
convert any value type to a JSON value
Definition json.hpp:5000
static constexpr int kPrecision
Definition json.hpp:15277
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition json.hpp:15365
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition json.hpp:15382
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition json.hpp:15300
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition json.hpp:15282
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition json.hpp:15288
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition json.hpp:4686
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition json.hpp:4676
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition json.hpp:4615
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition json.hpp:4624
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition json.hpp:4569
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition json.hpp:4637
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition json.hpp:4663
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition json.hpp:4650
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition json.hpp:4756
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition json.hpp:4746
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition json.hpp:4591
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition json.hpp:4582
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition json.hpp:11478
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition json.hpp:11476
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition json.hpp:11474
static constexpr bool value
Definition json.hpp:3519
static one test(decltype(&C::capacity))
static constexpr bool value
Definition json.hpp:8242
static adapter_type create(IteratorType first, IteratorType last)
Definition json.hpp:5672
nonesuch(nonesuch const &)=delete
void operator=(nonesuch &&)=delete
nonesuch(nonesuch const &&)=delete
void operator=(nonesuch const &)=delete
abstract output adapter interface
Definition json.hpp:13470
virtual void write_characters(const CharType *s, std::size_t length)=0
virtual void write_character(CharType c)=0
output_adapter_protocol & operator=(output_adapter_protocol &&) noexcept=default
output_adapter_protocol(output_adapter_protocol &&) noexcept=default
output_adapter_protocol & operator=(const output_adapter_protocol &)=default
output_adapter_protocol(const output_adapter_protocol &)=default
struct to capture the start position of the current token
Definition json.hpp:2593
std::size_t lines_read
the number of lines read
Definition json.hpp:2599
std::size_t chars_read_current_line
the number of characters read in the current line
Definition json.hpp:2597
std::size_t chars_read_total
the total number of characters read
Definition json.hpp:2595
constexpr operator size_t() const
conversion to size_t to preserve SAX interface
Definition json.hpp:2602
static constexpr T value
Definition json.hpp:3182
SAX interface.
Definition json.hpp:5843
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
virtual bool string(string_t &val)=0
a string was read
virtual bool null()=0
a null value was read
json_sax & operator=(json_sax &&) noexcept=default
virtual bool end_array()=0
the end of an array was read
virtual bool key(string_t &val)=0
an object key was read
virtual bool binary(binary_t &val)=0
a binary string was read
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
json_sax(json_sax &&) noexcept=default
virtual bool boolean(bool val)=0
a boolean value was read
json_sax(const json_sax &)=default
json_sax & operator=(const json_sax &)=default
virtual bool end_object()=0
the end of an object was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
virtual bool number_float(number_float_t val, const string_t &s)=0
an floating-point number was read
virtual ~json_sax()=default
virtual bool number_integer(number_integer_t val)=0
an integer number was read