1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++
4 |  |  |__   |  |  | | | |  version 3.10.2
5 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby  granted, free of charge, to any  person obtaining a copy
12 of this software and associated  documentation files (the "Software"), to deal
13 in the Software  without restriction, including without  limitation the rights
14 to  use, copy,  modify, merge,  publish, distribute,  sublicense, and/or  sell
15 copies  of  the Software,  and  to  permit persons  to  whom  the Software  is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE  IS PROVIDED "AS  IS", WITHOUT WARRANTY  OF ANY KIND,  EXPRESS OR
22 IMPLIED,  INCLUDING BUT  NOT  LIMITED TO  THE  WARRANTIES OF  MERCHANTABILITY,
23 FITNESS FOR  A PARTICULAR PURPOSE AND  NONINFRINGEMENT. IN NO EVENT  SHALL THE
24 AUTHORS  OR COPYRIGHT  HOLDERS  BE  LIABLE FOR  ANY  CLAIM,  DAMAGES OR  OTHER
25 LIABILITY, WHETHER IN AN ACTION OF  CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE  OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 #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 
88 namespace 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 */
operator <(const value_t lhs,const value_t rhs)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__) || \
895     JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
896     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
897     JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
898     JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
899     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
900     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
901     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
902     JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
903     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
904     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
905     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
906     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
907     JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
908     JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
909     JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
910     (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
911     #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
912 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
913     #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
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
991 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
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 \
1196     JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1197     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1198     #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1199     #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
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) || \
1256     JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1257     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1258     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1259     #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
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) || \
1272     JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1273     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1274     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1275     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1276     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1277     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1278     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1279     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1280     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1281     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1282     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1283     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1284     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1285     (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1286     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1287     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1288     #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1289     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1290 #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1291     #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1292     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1293 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1294     #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1295     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1296 #elif defined(_Check_return_) /* SAL */
1297     #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1298     #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
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) || \
1309     JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1310     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1311     JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1312     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1313     #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
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
1321 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1322     #define JSON_HEDLEY_NO_RETURN __noreturn
1323 #elif \
1324     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1325     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1326     #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1327 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1328     #define JSON_HEDLEY_NO_RETURN _Noreturn
1329 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1330     #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
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 \
1385     JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1386     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1387     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1388     #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1389 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1390     #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
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))) || \
1402     JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1403     JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1404     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1405     JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1406     JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1407     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1408     #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1409 #elif defined(JSON_HEDLEY_ASSUME)
1410     #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
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  \
1421         JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1422         JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1423         #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
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 
1434 JSON_HEDLEY_DIAGNOSTIC_PUSH
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) || \
1453     JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1454     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1455     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1456     #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1457 #else
1458     #define JSON_HEDLEY_NON_NULL(...)
1459 #endif
1460 JSON_HEDLEY_DIAGNOSTIC_POP
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) || \
1471     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1472     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1473     JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1474     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1475     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1476     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1477     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1478     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1479     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1480     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1481     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1482     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1483     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1484     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1485     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1486     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1487     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1488 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1489     #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
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)) || \
1523   JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1524   JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1525 #  define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(  (expr), (value), (probability))
1526 #  define JSON_HEDLEY_PREDICT_TRUE(expr, probability)   __builtin_expect_with_probability(!!(expr),    1   , (probability))
1527 #  define JSON_HEDLEY_PREDICT_FALSE(expr, probability)  __builtin_expect_with_probability(!!(expr),    0   , (probability))
1528 #  define JSON_HEDLEY_LIKELY(expr)                      __builtin_expect                 (!!(expr),    1                  )
1529 #  define JSON_HEDLEY_UNLIKELY(expr)                    __builtin_expect                 (!!(expr),    0                  )
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) || \
1577     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1578     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1579     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1580     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1581     JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1582     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1583     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1584     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1585     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1586     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1587     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1588     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1589     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1590     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1591     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1592     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1593     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1594     #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1595 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1596     #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
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 \
1609   JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1610   JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1611   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1612   JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1613   JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1614   JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1615   JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1616   (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1617   JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1618   (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1619   JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1620   (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1621   JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1622   (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1623   JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1624   JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1625   JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1626   JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1627   JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1628 #  define JSON_HEDLEY_PURE __attribute__((__pure__))
1629 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1630 #  define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1631 #elif defined(__cplusplus) && \
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 \
1646     JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1647     JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1648     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1649     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1650     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1651     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1652     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1653     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1654     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1655     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1656     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1657     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1658     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1659     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1660     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1661     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1662     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1663     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1664     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1665     #define JSON_HEDLEY_CONST __attribute__((__const__))
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 \
1679     JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1680     JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1681     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1682     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1683     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1684     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1685     JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1686     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1687     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1688     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1689     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1690     (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1691     JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1692     defined(__clang__) || \
1693     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1694     #define JSON_HEDLEY_RESTRICT __restrict
1695 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1696     #define JSON_HEDLEY_RESTRICT _Restrict
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) || \
1733   JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1734   JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1735   JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1736   JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1737   JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1738   JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1739   (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1740   JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1741   (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1742   JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1743   (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1744   JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1745   (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1746   JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1747   JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1748   JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1749   JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1750   JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1751 #  define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
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) || \
1777     JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1778     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1779     JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1780     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1781     JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1782     JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1783     (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1784     JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1785     (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1786     JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1787     (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1788     JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1789     (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1790     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1791     JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1792     JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1793     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1794     JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1795     #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
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) || \
1857     JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1858     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1859     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1860     #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
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) || \
1875     JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
1876     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1877     #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1878 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1879     #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1880 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1881     #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1882 #elif defined(__fallthrough) /* SAL */
1883     #define JSON_HEDLEY_FALL_THROUGH __fallthrough
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) || \
1893     JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1894     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1895     #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1896 #elif defined(_Ret_notnull_) /* SAL */
1897     #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
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) || \
1929     JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1930     JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1931     JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1932     JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1933     JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1934     JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1935     (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1936     JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1937     JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1938     #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
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)) || \
2032       JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2033       JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2034       defined(_Static_assert) \
2035     )
2036 #  define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2037 #elif \
2038   (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2039   JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2040   JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2041 #  define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
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
2147 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2148 #  define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2149         JSON_HEDLEY_DIAGNOSTIC_PUSH \
2150         _Pragma("warning(disable:188)") \
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 \
2162     (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2163     JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2164     #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
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__, \
2358         NLOHMANN_JSON_PASTE64, \
2359         NLOHMANN_JSON_PASTE63, \
2360         NLOHMANN_JSON_PASTE62, \
2361         NLOHMANN_JSON_PASTE61, \
2362         NLOHMANN_JSON_PASTE60, \
2363         NLOHMANN_JSON_PASTE59, \
2364         NLOHMANN_JSON_PASTE58, \
2365         NLOHMANN_JSON_PASTE57, \
2366         NLOHMANN_JSON_PASTE56, \
2367         NLOHMANN_JSON_PASTE55, \
2368         NLOHMANN_JSON_PASTE54, \
2369         NLOHMANN_JSON_PASTE53, \
2370         NLOHMANN_JSON_PASTE52, \
2371         NLOHMANN_JSON_PASTE51, \
2372         NLOHMANN_JSON_PASTE50, \
2373         NLOHMANN_JSON_PASTE49, \
2374         NLOHMANN_JSON_PASTE48, \
2375         NLOHMANN_JSON_PASTE47, \
2376         NLOHMANN_JSON_PASTE46, \
2377         NLOHMANN_JSON_PASTE45, \
2378         NLOHMANN_JSON_PASTE44, \
2379         NLOHMANN_JSON_PASTE43, \
2380         NLOHMANN_JSON_PASTE42, \
2381         NLOHMANN_JSON_PASTE41, \
2382         NLOHMANN_JSON_PASTE40, \
2383         NLOHMANN_JSON_PASTE39, \
2384         NLOHMANN_JSON_PASTE38, \
2385         NLOHMANN_JSON_PASTE37, \
2386         NLOHMANN_JSON_PASTE36, \
2387         NLOHMANN_JSON_PASTE35, \
2388         NLOHMANN_JSON_PASTE34, \
2389         NLOHMANN_JSON_PASTE33, \
2390         NLOHMANN_JSON_PASTE32, \
2391         NLOHMANN_JSON_PASTE31, \
2392         NLOHMANN_JSON_PASTE30, \
2393         NLOHMANN_JSON_PASTE29, \
2394         NLOHMANN_JSON_PASTE28, \
2395         NLOHMANN_JSON_PASTE27, \
2396         NLOHMANN_JSON_PASTE26, \
2397         NLOHMANN_JSON_PASTE25, \
2398         NLOHMANN_JSON_PASTE24, \
2399         NLOHMANN_JSON_PASTE23, \
2400         NLOHMANN_JSON_PASTE22, \
2401         NLOHMANN_JSON_PASTE21, \
2402         NLOHMANN_JSON_PASTE20, \
2403         NLOHMANN_JSON_PASTE19, \
2404         NLOHMANN_JSON_PASTE18, \
2405         NLOHMANN_JSON_PASTE17, \
2406         NLOHMANN_JSON_PASTE16, \
2407         NLOHMANN_JSON_PASTE15, \
2408         NLOHMANN_JSON_PASTE14, \
2409         NLOHMANN_JSON_PASTE13, \
2410         NLOHMANN_JSON_PASTE12, \
2411         NLOHMANN_JSON_PASTE11, \
2412         NLOHMANN_JSON_PASTE10, \
2413         NLOHMANN_JSON_PASTE9, \
2414         NLOHMANN_JSON_PASTE8, \
2415         NLOHMANN_JSON_PASTE7, \
2416         NLOHMANN_JSON_PASTE6, \
2417         NLOHMANN_JSON_PASTE5, \
2418         NLOHMANN_JSON_PASTE4, \
2419         NLOHMANN_JSON_PASTE3, \
2420         NLOHMANN_JSON_PASTE2, \
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 
2511 #if JSON_USE_IMPLICIT_CONVERSIONS
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 
2522 namespace 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 */
replace_substring(std::string & s,const std::string & f,const std::string & t)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  * @brief string escaping as described in RFC 6901 (Sect. 4)
2553  * @param[in] s string to escape
2554  * @return    escaped string
2555  *
2556  * Note the order of escaping "~" to "~0" and "/" to "~1" is important.
2557  */
escape(std::string s)2558 inline std::string escape(std::string s)
2559 {
2560     replace_substring(s, "~", "~0");
2561     replace_substring(s, "/", "~1");
2562     return s;
2563 }
2564 
2565 /*!
2566  * @brief string unescaping as described in RFC 6901 (Sect. 4)
2567  * @param[in] s string to unescape
2568  * @return    unescaped string
2569  *
2570  * Note the order of escaping "~1" to "/" and "~0" to "~" is important.
2571  */
unescape(std::string & s)2572 static void unescape(std::string& s)
2573 {
2574     replace_substring(s, "~1", "/");
2575     replace_substring(s, "~0", "~");
2576 }
2577 
2578 } // namespace detail
2579 } // namespace nlohmann
2580 
2581 // #include <nlohmann/detail/input/position_t.hpp>
2582 
2583 
2584 #include <cstddef> // size_t
2585 
2586 namespace nlohmann
2587 {
2588 namespace detail
2589 {
2590 /// struct to capture the start position of the current token
2591 struct position_t
2592 {
2593     /// the total number of characters read
2594     std::size_t chars_read_total = 0;
2595     /// the number of characters read in the current line
2596     std::size_t chars_read_current_line = 0;
2597     /// the number of lines read
2598     std::size_t lines_read = 0;
2599 
2600     /// conversion to size_t to preserve SAX interface
operator size_tnlohmann::detail::position_t2601     constexpr operator size_t() const
2602     {
2603         return chars_read_total;
2604     }
2605 };
2606 
2607 } // namespace detail
2608 } // namespace nlohmann
2609 
2610 // #include <nlohmann/detail/macro_scope.hpp>
2611 
2612 
2613 namespace nlohmann
2614 {
2615 namespace detail
2616 {
2617 ////////////////
2618 // exceptions //
2619 ////////////////
2620 
2621 /*!
2622 @brief general exception of the @ref basic_json class
2623 
2624 This class is an extension of `std::exception` objects with a member @a id for
2625 exception ids. It is used as the base class for all exceptions thrown by the
2626 @ref basic_json class. This class can hence be used as "wildcard" to catch
2627 exceptions.
2628 
2629 Subclasses:
2630 - @ref parse_error for exceptions indicating a parse error
2631 - @ref invalid_iterator for exceptions indicating errors with iterators
2632 - @ref type_error for exceptions indicating executing a member function with
2633                   a wrong type
2634 - @ref out_of_range for exceptions indicating access out of the defined range
2635 - @ref other_error for exceptions indicating other library errors
2636 
2637 @internal
2638 @note To have nothrow-copy-constructible exceptions, we internally use
2639       `std::runtime_error` which can cope with arbitrary-length error messages.
2640       Intermediate strings are built with static functions and then passed to
2641       the actual constructor.
2642 @endinternal
2643 
2644 @liveexample{The following code shows how arbitrary library exceptions can be
2645 caught.,exception}
2646 
2647 @since version 3.0.0
2648 */
2649 class exception : public std::exception
2650 {
2651   public:
2652     /// returns the explanatory string
what() const2653     const char* what() const noexcept override
2654     {
2655         return m.what();
2656     }
2657 
2658     /// the id of the exception
2659     const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
2660 
2661   protected:
2662     JSON_HEDLEY_NON_NULL(3)
exception(int id_,const char * what_arg)2663     exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2664 
name(const std::string & ename,int id_)2665     static std::string name(const std::string& ename, int id_)
2666     {
2667         return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2668     }
2669 
2670     template<typename BasicJsonType>
diagnostics(const BasicJsonType & leaf_element)2671     static std::string diagnostics(const BasicJsonType& leaf_element)
2672     {
2673 #if JSON_DIAGNOSTICS
2674         std::vector<std::string> tokens;
2675         for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
2676         {
2677             switch (current->m_parent->type())
2678             {
2679                 case value_t::array:
2680                 {
2681                     for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
2682                     {
2683                         if (&current->m_parent->m_value.array->operator[](i) == current)
2684                         {
2685                             tokens.emplace_back(std::to_string(i));
2686                             break;
2687                         }
2688                     }
2689                     break;
2690                 }
2691 
2692                 case value_t::object:
2693                 {
2694                     for (const auto& element : *current->m_parent->m_value.object)
2695                     {
2696                         if (&element.second == current)
2697                         {
2698                             tokens.emplace_back(element.first.c_str());
2699                             break;
2700                         }
2701                     }
2702                     break;
2703                 }
2704 
2705                 case value_t::null: // LCOV_EXCL_LINE
2706                 case value_t::string: // LCOV_EXCL_LINE
2707                 case value_t::boolean: // LCOV_EXCL_LINE
2708                 case value_t::number_integer: // LCOV_EXCL_LINE
2709                 case value_t::number_unsigned: // LCOV_EXCL_LINE
2710                 case value_t::number_float: // LCOV_EXCL_LINE
2711                 case value_t::binary: // LCOV_EXCL_LINE
2712                 case value_t::discarded: // LCOV_EXCL_LINE
2713                 default:   // LCOV_EXCL_LINE
2714                     break; // LCOV_EXCL_LINE
2715             }
2716         }
2717 
2718         if (tokens.empty())
2719         {
2720             return "";
2721         }
2722 
2723         return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
2724                                      [](const std::string & a, const std::string & b)
2725         {
2726             return a + "/" + detail::escape(b);
2727         }) + ") ";
2728 #else
2729         static_cast<void>(leaf_element);
2730         return "";
2731 #endif
2732     }
2733 
2734   private:
2735     /// an exception object as storage for error messages
2736     std::runtime_error m;
2737 };
2738 
2739 /*!
2740 @brief exception indicating a parse error
2741 
2742 This exception is thrown by the library when a parse error occurs. Parse errors
2743 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
2744 as when using JSON Patch.
2745 
2746 Member @a byte holds the byte index of the last read character in the input
2747 file.
2748 
2749 Exceptions have ids 1xx.
2750 
2751 name / id                      | example message | description
2752 ------------------------------ | --------------- | -------------------------
2753 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.
2754 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.
2755 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.
2756 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.
2757 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.
2758 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`.
2759 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.
2760 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.
2761 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
2762 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.
2763 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.
2764 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.
2765 json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
2766 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.
2767 
2768 @note For an input with n bytes, 1 is the index of the first character and n+1
2769       is the index of the terminating null byte or the end of file. This also
2770       holds true when reading a byte vector (CBOR or MessagePack).
2771 
2772 @liveexample{The following code shows how a `parse_error` exception can be
2773 caught.,parse_error}
2774 
2775 @sa - @ref exception for the base class of the library exceptions
2776 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2777 @sa - @ref type_error for exceptions indicating executing a member function with
2778                     a wrong type
2779 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2780 @sa - @ref other_error for exceptions indicating other library errors
2781 
2782 @since version 3.0.0
2783 */
2784 class parse_error : public exception
2785 {
2786   public:
2787     /*!
2788     @brief create a parse error exception
2789     @param[in] id_       the id of the exception
2790     @param[in] pos       the position where the error occurred (or with
2791                          chars_read_total=0 if the position cannot be
2792                          determined)
2793     @param[in] what_arg  the explanatory string
2794     @return parse_error object
2795     */
2796     template<typename BasicJsonType>
create(int id_,const position_t & pos,const std::string & what_arg,const BasicJsonType & context)2797     static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
2798     {
2799         std::string w = exception::name("parse_error", id_) + "parse error" +
2800                         position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
2801         return parse_error(id_, pos.chars_read_total, w.c_str());
2802     }
2803 
2804     template<typename BasicJsonType>
create(int id_,std::size_t byte_,const std::string & what_arg,const BasicJsonType & context)2805     static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
2806     {
2807         std::string w = exception::name("parse_error", id_) + "parse error" +
2808                         (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2809                         ": " + exception::diagnostics(context) + what_arg;
2810         return parse_error(id_, byte_, w.c_str());
2811     }
2812 
2813     /*!
2814     @brief byte index of the parse error
2815 
2816     The byte index of the last read character in the input file.
2817 
2818     @note For an input with n bytes, 1 is the index of the first character and
2819           n+1 is the index of the terminating null byte or the end of file.
2820           This also holds true when reading a byte vector (CBOR or MessagePack).
2821     */
2822     const std::size_t byte;
2823 
2824   private:
parse_error(int id_,std::size_t byte_,const char * what_arg)2825     parse_error(int id_, std::size_t byte_, const char* what_arg)
2826         : exception(id_, what_arg), byte(byte_) {}
2827 
position_string(const position_t & pos)2828     static std::string position_string(const position_t& pos)
2829     {
2830         return " at line " + std::to_string(pos.lines_read + 1) +
2831                ", column " + std::to_string(pos.chars_read_current_line);
2832     }
2833 };
2834 
2835 /*!
2836 @brief exception indicating errors with iterators
2837 
2838 This exception is thrown if iterators passed to a library function do not match
2839 the expected semantics.
2840 
2841 Exceptions have ids 2xx.
2842 
2843 name / id                           | example message | description
2844 ----------------------------------- | --------------- | -------------------------
2845 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.
2846 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.
2847 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.
2848 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.
2849 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.
2850 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.
2851 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.
2852 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.
2853 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.
2854 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.
2855 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.
2856 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
2857 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
2858 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().
2859 
2860 @liveexample{The following code shows how an `invalid_iterator` exception can be
2861 caught.,invalid_iterator}
2862 
2863 @sa - @ref exception for the base class of the library exceptions
2864 @sa - @ref parse_error for exceptions indicating a parse error
2865 @sa - @ref type_error for exceptions indicating executing a member function with
2866                     a wrong type
2867 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2868 @sa - @ref other_error for exceptions indicating other library errors
2869 
2870 @since version 3.0.0
2871 */
2872 class invalid_iterator : public exception
2873 {
2874   public:
2875     template<typename BasicJsonType>
create(int id_,const std::string & what_arg,const BasicJsonType & context)2876     static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
2877     {
2878         std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
2879         return invalid_iterator(id_, w.c_str());
2880     }
2881 
2882   private:
2883     JSON_HEDLEY_NON_NULL(3)
invalid_iterator(int id_,const char * what_arg)2884     invalid_iterator(int id_, const char* what_arg)
2885         : exception(id_, what_arg) {}
2886 };
2887 
2888 /*!
2889 @brief exception indicating executing a member function with a wrong type
2890 
2891 This exception is thrown in case of a type error; that is, a library function is
2892 executed on a JSON value whose type does not match the expected semantics.
2893 
2894 Exceptions have ids 3xx.
2895 
2896 name / id                     | example message | description
2897 ----------------------------- | --------------- | -------------------------
2898 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.
2899 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.
2900 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 &.
2901 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
2902 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
2903 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
2904 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
2905 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.
2906 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
2907 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
2908 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.
2909 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
2910 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.
2911 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
2912 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.
2913 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. |
2914 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) |
2915 
2916 @liveexample{The following code shows how a `type_error` exception can be
2917 caught.,type_error}
2918 
2919 @sa - @ref exception for the base class of the library exceptions
2920 @sa - @ref parse_error for exceptions indicating a parse error
2921 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2922 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2923 @sa - @ref other_error for exceptions indicating other library errors
2924 
2925 @since version 3.0.0
2926 */
2927 class type_error : public exception
2928 {
2929   public:
2930     template<typename BasicJsonType>
create(int id_,const std::string & what_arg,const BasicJsonType & context)2931     static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
2932     {
2933         std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
2934         return type_error(id_, w.c_str());
2935     }
2936 
2937   private:
2938     JSON_HEDLEY_NON_NULL(3)
type_error(int id_,const char * what_arg)2939     type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2940 };
2941 
2942 /*!
2943 @brief exception indicating access out of the defined range
2944 
2945 This exception is thrown in case a library function is called on an input
2946 parameter that exceeds the expected range, for instance in case of array
2947 indices or nonexisting object keys.
2948 
2949 Exceptions have ids 4xx.
2950 
2951 name / id                       | example message | description
2952 ------------------------------- | --------------- | -------------------------
2953 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.
2954 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.
2955 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
2956 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
2957 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.
2958 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.
2959 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) |
2960 json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
2961 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 |
2962 
2963 @liveexample{The following code shows how an `out_of_range` exception can be
2964 caught.,out_of_range}
2965 
2966 @sa - @ref exception for the base class of the library exceptions
2967 @sa - @ref parse_error for exceptions indicating a parse error
2968 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2969 @sa - @ref type_error for exceptions indicating executing a member function with
2970                     a wrong type
2971 @sa - @ref other_error for exceptions indicating other library errors
2972 
2973 @since version 3.0.0
2974 */
2975 class out_of_range : public exception
2976 {
2977   public:
2978     template<typename BasicJsonType>
create(int id_,const std::string & what_arg,const BasicJsonType & context)2979     static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
2980     {
2981         std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
2982         return out_of_range(id_, w.c_str());
2983     }
2984 
2985   private:
2986     JSON_HEDLEY_NON_NULL(3)
out_of_range(int id_,const char * what_arg)2987     out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2988 };
2989 
2990 /*!
2991 @brief exception indicating other library errors
2992 
2993 This exception is thrown in case of errors that cannot be classified with the
2994 other exception types.
2995 
2996 Exceptions have ids 5xx.
2997 
2998 name / id                      | example message | description
2999 ------------------------------ | --------------- | -------------------------
3000 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
3001 
3002 @sa - @ref exception for the base class of the library exceptions
3003 @sa - @ref parse_error for exceptions indicating a parse error
3004 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
3005 @sa - @ref type_error for exceptions indicating executing a member function with
3006                     a wrong type
3007 @sa - @ref out_of_range for exceptions indicating access out of the defined range
3008 
3009 @liveexample{The following code shows how an `other_error` exception can be
3010 caught.,other_error}
3011 
3012 @since version 3.0.0
3013 */
3014 class other_error : public exception
3015 {
3016   public:
3017     template<typename BasicJsonType>
create(int id_,const std::string & what_arg,const BasicJsonType & context)3018     static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3019     {
3020         std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
3021         return other_error(id_, w.c_str());
3022     }
3023 
3024   private:
3025     JSON_HEDLEY_NON_NULL(3)
other_error(int id_,const char * what_arg)3026     other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3027 };
3028 }  // namespace detail
3029 }  // namespace nlohmann
3030 
3031 // #include <nlohmann/detail/macro_scope.hpp>
3032 
3033 // #include <nlohmann/detail/meta/cpp_future.hpp>
3034 
3035 
3036 #include <cstddef> // size_t
3037 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3038 #include <utility> // index_sequence, make_index_sequence, index_sequence_for
3039 
3040 // #include <nlohmann/detail/macro_scope.hpp>
3041 
3042 
3043 namespace nlohmann
3044 {
3045 namespace detail
3046 {
3047 
3048 template<typename T>
3049 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3050 
3051 #ifdef JSON_HAS_CPP_14
3052 
3053 // the following utilities are natively available in C++14
3054 using std::enable_if_t;
3055 using std::index_sequence;
3056 using std::make_index_sequence;
3057 using std::index_sequence_for;
3058 
3059 #else
3060 
3061 // alias templates to reduce boilerplate
3062 template<bool B, typename T = void>
3063 using enable_if_t = typename std::enable_if<B, T>::type;
3064 
3065 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3066 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3067 
3068 //// START OF CODE FROM GOOGLE ABSEIL
3069 
3070 // integer_sequence
3071 //
3072 // Class template representing a compile-time integer sequence. An instantiation
3073 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3074 // type through its template arguments (which is a common need when
3075 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3076 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3077 //
3078 // Example:
3079 //
3080 //   template< class T, T... Ints >
3081 //   void user_function(integer_sequence<T, Ints...>);
3082 //
3083 //   int main()
3084 //   {
3085 //     // user_function's `T` will be deduced to `int` and `Ints...`
3086 //     // will be deduced to `0, 1, 2, 3, 4`.
3087 //     user_function(make_integer_sequence<int, 5>());
3088 //   }
3089 template <typename T, T... Ints>
3090 struct integer_sequence
3091 {
3092     using value_type = T;
sizenlohmann::detail::integer_sequence3093     static constexpr std::size_t size() noexcept
3094     {
3095         return sizeof...(Ints);
3096     }
3097 };
3098 
3099 // index_sequence
3100 //
3101 // A helper template for an `integer_sequence` of `size_t`,
3102 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3103 // `std::index_sequence`.
3104 template <size_t... Ints>
3105 using index_sequence = integer_sequence<size_t, Ints...>;
3106 
3107 namespace utility_internal
3108 {
3109 
3110 template <typename Seq, size_t SeqSize, size_t Rem>
3111 struct Extend;
3112 
3113 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3114 template <typename T, T... Ints, size_t SeqSize>
3115 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3116 {
3117     using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3118 };
3119 
3120 template <typename T, T... Ints, size_t SeqSize>
3121 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3122 {
3123     using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3124 };
3125 
3126 // Recursion helper for 'make_integer_sequence<T, N>'.
3127 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3128 template <typename T, size_t N>
3129 struct Gen
3130 {
3131     using type =
3132         typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3133 };
3134 
3135 template <typename T>
3136 struct Gen<T, 0>
3137 {
3138     using type = integer_sequence<T>;
3139 };
3140 
3141 }  // namespace utility_internal
3142 
3143 // Compile-time sequences of integers
3144 
3145 // make_integer_sequence
3146 //
3147 // This template alias is equivalent to
3148 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3149 // replacement for C++14's `std::make_integer_sequence`.
3150 template <typename T, T N>
3151 using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
3152 
3153 // make_index_sequence
3154 //
3155 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3156 // and is designed to be a drop-in replacement for C++14's
3157 // `std::make_index_sequence`.
3158 template <size_t N>
3159 using make_index_sequence = make_integer_sequence<size_t, N>;
3160 
3161 // index_sequence_for
3162 //
3163 // Converts a typename pack into an index sequence of the same length, and
3164 // is designed to be a drop-in replacement for C++14's
3165 // `std::index_sequence_for()`
3166 template <typename... Ts>
3167 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
3168 
3169 //// END OF CODE FROM GOOGLE ABSEIL
3170 
3171 #endif
3172 
3173 // dispatch utility (taken from ranges-v3)
3174 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3175 template<> struct priority_tag<0> {};
3176 
3177 // taken from ranges-v3
3178 template<typename T>
3179 struct static_const
3180 {
3181     static constexpr T value{};
3182 };
3183 
3184 template<typename T>
3185 constexpr T static_const<T>::value;
3186 
3187 }  // namespace detail
3188 }  // namespace nlohmann
3189 
3190 // #include <nlohmann/detail/meta/identity_tag.hpp>
3191 
3192 
3193 namespace nlohmann
3194 {
3195 namespace detail
3196 {
3197 // dispatching helper struct
3198 template <class T> struct identity_tag {};
3199 }  // namespace detail
3200 }  // namespace nlohmann
3201 
3202 // #include <nlohmann/detail/meta/type_traits.hpp>
3203 
3204 
3205 #include <limits> // numeric_limits
3206 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3207 #include <utility> // declval
3208 #include <tuple> // tuple
3209 
3210 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3211 
3212 
3213 #include <iterator> // random_access_iterator_tag
3214 
3215 // #include <nlohmann/detail/meta/void_t.hpp>
3216 
3217 
3218 namespace nlohmann
3219 {
3220 namespace detail
3221 {
3222 template<typename ...Ts> struct make_void
3223 {
3224     using type = void;
3225 };
3226 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
3227 } // namespace detail
3228 }  // namespace nlohmann
3229 
3230 // #include <nlohmann/detail/meta/cpp_future.hpp>
3231 
3232 
3233 namespace nlohmann
3234 {
3235 namespace detail
3236 {
3237 template<typename It, typename = void>
3238 struct iterator_types {};
3239 
3240 template<typename It>
3241 struct iterator_types <
3242     It,
3243     void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3244     typename It::reference, typename It::iterator_category >>
3245 {
3246     using difference_type = typename It::difference_type;
3247     using value_type = typename It::value_type;
3248     using pointer = typename It::pointer;
3249     using reference = typename It::reference;
3250     using iterator_category = typename It::iterator_category;
3251 };
3252 
3253 // This is required as some compilers implement std::iterator_traits in a way that
3254 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3255 template<typename T, typename = void>
3256 struct iterator_traits
3257 {
3258 };
3259 
3260 template<typename T>
3261 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3262             : iterator_types<T>
3263 {
3264 };
3265 
3266 template<typename T>
3267 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
3268 {
3269     using iterator_category = std::random_access_iterator_tag;
3270     using value_type = T;
3271     using difference_type = ptrdiff_t;
3272     using pointer = T*;
3273     using reference = T&;
3274 };
3275 } // namespace detail
3276 } // namespace nlohmann
3277 
3278 // #include <nlohmann/detail/macro_scope.hpp>
3279 
3280 // #include <nlohmann/detail/meta/cpp_future.hpp>
3281 
3282 // #include <nlohmann/detail/meta/detected.hpp>
3283 
3284 
3285 #include <type_traits>
3286 
3287 // #include <nlohmann/detail/meta/void_t.hpp>
3288 
3289 
3290 // https://en.cppreference.com/w/cpp/experimental/is_detected
3291 namespace nlohmann
3292 {
3293 namespace detail
3294 {
3295 struct nonesuch
3296 {
3297     nonesuch() = delete;
3298     ~nonesuch() = delete;
3299     nonesuch(nonesuch const&) = delete;
3300     nonesuch(nonesuch const&&) = delete;
3301     void operator=(nonesuch const&) = delete;
3302     void operator=(nonesuch&&) = delete;
3303 };
3304 
3305 template<class Default,
3306          class AlwaysVoid,
3307          template<class...> class Op,
3308          class... Args>
3309 struct detector
3310 {
3311     using value_t = std::false_type;
3312     using type = Default;
3313 };
3314 
3315 template<class Default, template<class...> class Op, class... Args>
3316 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
3317 {
3318     using value_t = std::true_type;
3319     using type = Op<Args...>;
3320 };
3321 
3322 template<template<class...> class Op, class... Args>
3323 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
3324 
3325 template<template<class...> class Op, class... Args>
3326 struct is_detected_lazy : is_detected<Op, Args...> { };
3327 
3328 template<template<class...> class Op, class... Args>
3329 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
3330 
3331 template<class Default, template<class...> class Op, class... Args>
3332 using detected_or = detector<Default, void, Op, Args...>;
3333 
3334 template<class Default, template<class...> class Op, class... Args>
3335 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
3336 
3337 template<class Expected, template<class...> class Op, class... Args>
3338 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
3339 
3340 template<class To, template<class...> class Op, class... Args>
3341 using is_detected_convertible =
3342     std::is_convertible<detected_t<Op, Args...>, To>;
3343 }  // namespace detail
3344 }  // namespace nlohmann
3345 
3346 // #include <nlohmann/json_fwd.hpp>
3347 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3348 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3349 
3350 #include <cstdint> // int64_t, uint64_t
3351 #include <map> // map
3352 #include <memory> // allocator
3353 #include <string> // string
3354 #include <vector> // vector
3355 
3356 /*!
3357 @brief namespace for Niels Lohmann
3358 @see https://github.com/nlohmann
3359 @since version 1.0.0
3360 */
3361 namespace nlohmann
3362 {
3363 /*!
3364 @brief default JSONSerializer template argument
3365 
3366 This serializer ignores the template arguments and uses ADL
3367 ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
3368 for serialization.
3369 */
3370 template<typename T = void, typename SFINAE = void>
3371 struct adl_serializer;
3372 
3373 template<template<typename U, typename V, typename... Args> class ObjectType =
3374          std::map,
3375          template<typename U, typename... Args> class ArrayType = std::vector,
3376          class StringType = std::string, class BooleanType = bool,
3377          class NumberIntegerType = std::int64_t,
3378          class NumberUnsignedType = std::uint64_t,
3379          class NumberFloatType = double,
3380          template<typename U> class AllocatorType = std::allocator,
3381          template<typename T, typename SFINAE = void> class JSONSerializer =
3382          adl_serializer,
3383          class BinaryType = std::vector<std::uint8_t>>
3384 class basic_json;
3385 
3386 /*!
3387 @brief JSON Pointer
3388 
3389 A JSON pointer defines a string syntax for identifying a specific value
3390 within a JSON document. It can be used with functions `at` and
3391 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
3392 
3393 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
3394 
3395 @since version 2.0.0
3396 */
3397 template<typename BasicJsonType>
3398 class json_pointer;
3399 
3400 /*!
3401 @brief default JSON class
3402 
3403 This type is the default specialization of the @ref basic_json class which
3404 uses the standard template types.
3405 
3406 @since version 1.0.0
3407 */
3408 using json = basic_json<>;
3409 
3410 template<class Key, class T, class IgnoredLess, class Allocator>
3411 struct ordered_map;
3412 
3413 /*!
3414 @brief ordered JSON class
3415 
3416 This type preserves the insertion order of object keys.
3417 
3418 @since version 3.9.0
3419 */
3420 using ordered_json = basic_json<nlohmann::ordered_map>;
3421 
3422 }  // namespace nlohmann
3423 
3424 #endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3425 
3426 
3427 namespace nlohmann
3428 {
3429 /*!
3430 @brief detail namespace with internal helper functions
3431 
3432 This namespace collects functions that should not be exposed,
3433 implementations of some @ref basic_json methods, and meta-programming helpers.
3434 
3435 @since version 2.1.0
3436 */
3437 namespace detail
3438 {
3439 /////////////
3440 // helpers //
3441 /////////////
3442 
3443 // Note to maintainers:
3444 //
3445 // Every trait in this file expects a non CV-qualified type.
3446 // The only exceptions are in the 'aliases for detected' section
3447 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3448 //
3449 // In this case, T has to be properly CV-qualified to constraint the function arguments
3450 // (e.g. to_json(BasicJsonType&, const T&))
3451 
3452 template<typename> struct is_basic_json : std::false_type {};
3453 
3454 NLOHMANN_BASIC_JSON_TPL_DECLARATION
3455 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3456 
3457 //////////////////////
3458 // json_ref helpers //
3459 //////////////////////
3460 
3461 template<typename>
3462 class json_ref;
3463 
3464 template<typename>
3465 struct is_json_ref : std::false_type {};
3466 
3467 template<typename T>
3468 struct is_json_ref<json_ref<T>> : std::true_type {};
3469 
3470 //////////////////////////
3471 // aliases for detected //
3472 //////////////////////////
3473 
3474 template<typename T>
3475 using mapped_type_t = typename T::mapped_type;
3476 
3477 template<typename T>
3478 using key_type_t = typename T::key_type;
3479 
3480 template<typename T>
3481 using value_type_t = typename T::value_type;
3482 
3483 template<typename T>
3484 using difference_type_t = typename T::difference_type;
3485 
3486 template<typename T>
3487 using pointer_t = typename T::pointer;
3488 
3489 template<typename T>
3490 using reference_t = typename T::reference;
3491 
3492 template<typename T>
3493 using iterator_category_t = typename T::iterator_category;
3494 
3495 template<typename T>
3496 using iterator_t = typename T::iterator;
3497 
3498 template<typename T, typename... Args>
3499 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3500 
3501 template<typename T, typename... Args>
3502 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3503 
3504 template<typename T, typename U>
3505 using get_template_function = decltype(std::declval<T>().template get<U>());
3506 
3507 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3508 template<typename BasicJsonType, typename T, typename = void>
3509 struct has_from_json : std::false_type {};
3510 
3511 // trait checking if j.get<T> is valid
3512 // use this trait instead of std::is_constructible or std::is_convertible,
3513 // both rely on, or make use of implicit conversions, and thus fail when T
3514 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3515 template <typename BasicJsonType, typename T>
3516 struct is_getable
3517 {
3518     static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3519 };
3520 
3521 template<typename BasicJsonType, typename T>
3522 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3523 {
3524     using serializer = typename BasicJsonType::template json_serializer<T, void>;
3525 
3526     static constexpr bool value =
3527         is_detected_exact<void, from_json_function, serializer,
3528         const BasicJsonType&, T&>::value;
3529 };
3530 
3531 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3532 // this overload is used for non-default-constructible user-defined-types
3533 template<typename BasicJsonType, typename T, typename = void>
3534 struct has_non_default_from_json : std::false_type {};
3535 
3536 template<typename BasicJsonType, typename T>
3537 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3538 {
3539     using serializer = typename BasicJsonType::template json_serializer<T, void>;
3540 
3541     static constexpr bool value =
3542         is_detected_exact<T, from_json_function, serializer,
3543         const BasicJsonType&>::value;
3544 };
3545 
3546 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3547 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3548 template<typename BasicJsonType, typename T, typename = void>
3549 struct has_to_json : std::false_type {};
3550 
3551 template<typename BasicJsonType, typename T>
3552 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3553 {
3554     using serializer = typename BasicJsonType::template json_serializer<T, void>;
3555 
3556     static constexpr bool value =
3557         is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3558         T>::value;
3559 };
3560 
3561 
3562 ///////////////////
3563 // is_ functions //
3564 ///////////////////
3565 
3566 // https://en.cppreference.com/w/cpp/types/conjunction
3567 template<class...> struct conjunction : std::true_type { };
3568 template<class B1> struct conjunction<B1> : B1 { };
3569 template<class B1, class... Bn>
3570 struct conjunction<B1, Bn...>
3571 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3572 
3573 // https://en.cppreference.com/w/cpp/types/negation
3574 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3575 
3576 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3577 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3578 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3579 template <typename T>
3580 struct is_default_constructible : std::is_default_constructible<T> {};
3581 
3582 template <typename T1, typename T2>
3583 struct is_default_constructible<std::pair<T1, T2>>
3584             : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3585 
3586 template <typename T1, typename T2>
3587 struct is_default_constructible<const std::pair<T1, T2>>
3588             : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3589 
3590 template <typename... Ts>
3591 struct is_default_constructible<std::tuple<Ts...>>
3592             : conjunction<is_default_constructible<Ts>...> {};
3593 
3594 template <typename... Ts>
3595 struct is_default_constructible<const std::tuple<Ts...>>
3596             : conjunction<is_default_constructible<Ts>...> {};
3597 
3598 
3599 template <typename T, typename... Args>
3600 struct is_constructible : std::is_constructible<T, Args...> {};
3601 
3602 template <typename T1, typename T2>
3603 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3604 
3605 template <typename T1, typename T2>
3606 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3607 
3608 template <typename... Ts>
3609 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3610 
3611 template <typename... Ts>
3612 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3613 
3614 
3615 template<typename T, typename = void>
3616 struct is_iterator_traits : std::false_type {};
3617 
3618 template<typename T>
3619 struct is_iterator_traits<iterator_traits<T>>
3620 {
3621   private:
3622     using traits = iterator_traits<T>;
3623 
3624   public:
3625     static constexpr auto value =
3626         is_detected<value_type_t, traits>::value &&
3627         is_detected<difference_type_t, traits>::value &&
3628         is_detected<pointer_t, traits>::value &&
3629         is_detected<iterator_category_t, traits>::value &&
3630         is_detected<reference_t, traits>::value;
3631 };
3632 
3633 // The following implementation of is_complete_type is taken from
3634 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3635 // and is written by Xiang Fan who agreed to using it in this library.
3636 
3637 template<typename T, typename = void>
3638 struct is_complete_type : std::false_type {};
3639 
3640 template<typename T>
3641 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3642 
3643 template<typename BasicJsonType, typename CompatibleObjectType,
3644          typename = void>
3645 struct is_compatible_object_type_impl : std::false_type {};
3646 
3647 template<typename BasicJsonType, typename CompatibleObjectType>
3648 struct is_compatible_object_type_impl <
3649     BasicJsonType, CompatibleObjectType,
3650     enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3651     is_detected<key_type_t, CompatibleObjectType>::value >>
3652 {
3653     using object_t = typename BasicJsonType::object_t;
3654 
3655     // macOS's is_constructible does not play well with nonesuch...
3656     static constexpr bool value =
3657         is_constructible<typename object_t::key_type,
3658         typename CompatibleObjectType::key_type>::value &&
3659         is_constructible<typename object_t::mapped_type,
3660         typename CompatibleObjectType::mapped_type>::value;
3661 };
3662 
3663 template<typename BasicJsonType, typename CompatibleObjectType>
3664 struct is_compatible_object_type
3665     : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3666 
3667 template<typename BasicJsonType, typename ConstructibleObjectType,
3668          typename = void>
3669 struct is_constructible_object_type_impl : std::false_type {};
3670 
3671 template<typename BasicJsonType, typename ConstructibleObjectType>
3672 struct is_constructible_object_type_impl <
3673     BasicJsonType, ConstructibleObjectType,
3674     enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3675     is_detected<key_type_t, ConstructibleObjectType>::value >>
3676 {
3677     using object_t = typename BasicJsonType::object_t;
3678 
3679     static constexpr bool value =
3680         (is_default_constructible<ConstructibleObjectType>::value &&
3681          (std::is_move_assignable<ConstructibleObjectType>::value ||
3682           std::is_copy_assignable<ConstructibleObjectType>::value) &&
3683          (is_constructible<typename ConstructibleObjectType::key_type,
3684           typename object_t::key_type>::value &&
3685           std::is_same <
3686           typename object_t::mapped_type,
3687           typename ConstructibleObjectType::mapped_type >::value)) ||
3688         (has_from_json<BasicJsonType,
3689          typename ConstructibleObjectType::mapped_type>::value ||
3690          has_non_default_from_json <
3691          BasicJsonType,
3692          typename ConstructibleObjectType::mapped_type >::value);
3693 };
3694 
3695 template<typename BasicJsonType, typename ConstructibleObjectType>
3696 struct is_constructible_object_type
3697     : is_constructible_object_type_impl<BasicJsonType,
3698       ConstructibleObjectType> {};
3699 
3700 template<typename BasicJsonType, typename CompatibleStringType,
3701          typename = void>
3702 struct is_compatible_string_type_impl : std::false_type {};
3703 
3704 template<typename BasicJsonType, typename CompatibleStringType>
3705 struct is_compatible_string_type_impl <
3706     BasicJsonType, CompatibleStringType,
3707     enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3708     value_type_t, CompatibleStringType>::value >>
3709 {
3710     static constexpr auto value =
3711         is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3712 };
3713 
3714 template<typename BasicJsonType, typename ConstructibleStringType>
3715 struct is_compatible_string_type
3716     : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3717 
3718 template<typename BasicJsonType, typename ConstructibleStringType,
3719          typename = void>
3720 struct is_constructible_string_type_impl : std::false_type {};
3721 
3722 template<typename BasicJsonType, typename ConstructibleStringType>
3723 struct is_constructible_string_type_impl <
3724     BasicJsonType, ConstructibleStringType,
3725     enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3726     value_type_t, ConstructibleStringType>::value >>
3727 {
3728     static constexpr auto value =
3729         is_constructible<ConstructibleStringType,
3730         typename BasicJsonType::string_t>::value;
3731 };
3732 
3733 template<typename BasicJsonType, typename ConstructibleStringType>
3734 struct is_constructible_string_type
3735     : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3736 
3737 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3738 struct is_compatible_array_type_impl : std::false_type {};
3739 
3740 template<typename BasicJsonType, typename CompatibleArrayType>
3741 struct is_compatible_array_type_impl <
3742     BasicJsonType, CompatibleArrayType,
3743     enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
3744     is_detected<iterator_t, CompatibleArrayType>::value&&
3745 // This is needed because json_reverse_iterator has a ::iterator type...
3746 // Therefore it is detected as a CompatibleArrayType.
3747 // The real fix would be to have an Iterable concept.
3748     !is_iterator_traits <
3749     iterator_traits<CompatibleArrayType >>::value >>
3750 {
3751     static constexpr bool value =
3752         is_constructible<BasicJsonType,
3753         typename CompatibleArrayType::value_type>::value;
3754 };
3755 
3756 template<typename BasicJsonType, typename CompatibleArrayType>
3757 struct is_compatible_array_type
3758     : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3759 
3760 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3761 struct is_constructible_array_type_impl : std::false_type {};
3762 
3763 template<typename BasicJsonType, typename ConstructibleArrayType>
3764 struct is_constructible_array_type_impl <
3765     BasicJsonType, ConstructibleArrayType,
3766     enable_if_t<std::is_same<ConstructibleArrayType,
3767     typename BasicJsonType::value_type>::value >>
3768             : std::true_type {};
3769 
3770 template<typename BasicJsonType, typename ConstructibleArrayType>
3771 struct is_constructible_array_type_impl <
3772     BasicJsonType, ConstructibleArrayType,
3773     enable_if_t < !std::is_same<ConstructibleArrayType,
3774     typename BasicJsonType::value_type>::value&&
3775     is_default_constructible<ConstructibleArrayType>::value&&
3776 (std::is_move_assignable<ConstructibleArrayType>::value ||
3777  std::is_copy_assignable<ConstructibleArrayType>::value)&&
3778 is_detected<value_type_t, ConstructibleArrayType>::value&&
3779 is_detected<iterator_t, ConstructibleArrayType>::value&&
3780 is_complete_type <
3781 detected_t<value_type_t, ConstructibleArrayType >>::value >>
3782 {
3783     static constexpr bool value =
3784         // This is needed because json_reverse_iterator has a ::iterator type,
3785         // furthermore, std::back_insert_iterator (and other iterators) have a
3786         // base class `iterator`... Therefore it is detected as a
3787         // ConstructibleArrayType. The real fix would be to have an Iterable
3788         // concept.
3789         !is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value &&
3790 
3791         (std::is_same<typename ConstructibleArrayType::value_type,
3792          typename BasicJsonType::array_t::value_type>::value ||
3793          has_from_json<BasicJsonType,
3794          typename ConstructibleArrayType::value_type>::value ||
3795          has_non_default_from_json <
3796          BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3797 };
3798 
3799 template<typename BasicJsonType, typename ConstructibleArrayType>
3800 struct is_constructible_array_type
3801     : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3802 
3803 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3804          typename = void>
3805 struct is_compatible_integer_type_impl : std::false_type {};
3806 
3807 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3808 struct is_compatible_integer_type_impl <
3809     RealIntegerType, CompatibleNumberIntegerType,
3810     enable_if_t < std::is_integral<RealIntegerType>::value&&
3811     std::is_integral<CompatibleNumberIntegerType>::value&&
3812     !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3813 {
3814     // is there an assert somewhere on overflows?
3815     using RealLimits = std::numeric_limits<RealIntegerType>;
3816     using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3817 
3818     static constexpr auto value =
3819         is_constructible<RealIntegerType,
3820         CompatibleNumberIntegerType>::value &&
3821         CompatibleLimits::is_integer &&
3822         RealLimits::is_signed == CompatibleLimits::is_signed;
3823 };
3824 
3825 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3826 struct is_compatible_integer_type
3827     : is_compatible_integer_type_impl<RealIntegerType,
3828       CompatibleNumberIntegerType> {};
3829 
3830 template<typename BasicJsonType, typename CompatibleType, typename = void>
3831 struct is_compatible_type_impl: std::false_type {};
3832 
3833 template<typename BasicJsonType, typename CompatibleType>
3834 struct is_compatible_type_impl <
3835     BasicJsonType, CompatibleType,
3836     enable_if_t<is_complete_type<CompatibleType>::value >>
3837 {
3838     static constexpr bool value =
3839         has_to_json<BasicJsonType, CompatibleType>::value;
3840 };
3841 
3842 template<typename BasicJsonType, typename CompatibleType>
3843 struct is_compatible_type
3844     : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3845 
3846 template<typename T1, typename T2>
3847 struct is_constructible_tuple : std::false_type {};
3848 
3849 template<typename T1, typename... Args>
3850 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3851 
3852 // a naive helper to check if a type is an ordered_map (exploits the fact that
3853 // ordered_map inherits capacity() from std::vector)
3854 template <typename T>
3855 struct is_ordered_map
3856 {
3857     using one = char;
3858 
3859     struct two
3860     {
3861         char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3862     };
3863 
3864     template <typename C> static one test( decltype(&C::capacity) ) ;
3865     template <typename C> static two test(...);
3866 
3867     enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3868 };
3869 
3870 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3871 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3872 T conditional_static_cast(U value)
3873 {
3874     return static_cast<T>(value);
3875 }
3876 
3877 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3878 T conditional_static_cast(U value)
3879 {
3880     return value;
3881 }
3882 
3883 }  // namespace detail
3884 }  // namespace nlohmann
3885 
3886 // #include <nlohmann/detail/value_t.hpp>
3887 
3888 
3889 namespace nlohmann
3890 {
3891 namespace detail
3892 {
3893 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename std::nullptr_t & n)3894 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3895 {
3896     if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3897     {
3898         JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
3899     }
3900     n = nullptr;
3901 }
3902 
3903 // overloads for basic_json template parameters
3904 template < typename BasicJsonType, typename ArithmeticType,
3905            enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3906                          !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3907                          int > = 0 >
get_arithmetic_value(const BasicJsonType & j,ArithmeticType & val)3908 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3909 {
3910     switch (static_cast<value_t>(j))
3911     {
3912         case value_t::number_unsigned:
3913         {
3914             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3915             break;
3916         }
3917         case value_t::number_integer:
3918         {
3919             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3920             break;
3921         }
3922         case value_t::number_float:
3923         {
3924             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3925             break;
3926         }
3927 
3928         case value_t::null:
3929         case value_t::object:
3930         case value_t::array:
3931         case value_t::string:
3932         case value_t::boolean:
3933         case value_t::binary:
3934         case value_t::discarded:
3935         default:
3936             JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
3937     }
3938 }
3939 
3940 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::boolean_t & b)3941 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3942 {
3943     if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3944     {
3945         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
3946     }
3947     b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3948 }
3949 
3950 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::string_t & s)3951 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3952 {
3953     if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3954     {
3955         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3956     }
3957     s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3958 }
3959 
3960 template <
3961     typename BasicJsonType, typename ConstructibleStringType,
3962     enable_if_t <
3963         is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
3964         !std::is_same<typename BasicJsonType::string_t,
3965                       ConstructibleStringType>::value,
3966         int > = 0 >
from_json(const BasicJsonType & j,ConstructibleStringType & s)3967 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3968 {
3969     if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3970     {
3971         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3972     }
3973 
3974     s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3975 }
3976 
3977 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_float_t & val)3978 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3979 {
3980     get_arithmetic_value(j, val);
3981 }
3982 
3983 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_unsigned_t & val)3984 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3985 {
3986     get_arithmetic_value(j, val);
3987 }
3988 
3989 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_integer_t & val)3990 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3991 {
3992     get_arithmetic_value(j, val);
3993 }
3994 
3995 template<typename BasicJsonType, typename EnumType,
3996          enable_if_t<std::is_enum<EnumType>::value, int> = 0>
from_json(const BasicJsonType & j,EnumType & e)3997 void from_json(const BasicJsonType& j, EnumType& e)
3998 {
3999     typename std::underlying_type<EnumType>::type val;
4000     get_arithmetic_value(j, val);
4001     e = static_cast<EnumType>(val);
4002 }
4003 
4004 // forward_list doesn't have an insert method
4005 template<typename BasicJsonType, typename T, typename Allocator,
4006          enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::forward_list<T,Allocator> & l)4007 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4008 {
4009     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4010     {
4011         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4012     }
4013     l.clear();
4014     std::transform(j.rbegin(), j.rend(),
4015                    std::front_inserter(l), [](const BasicJsonType & i)
4016     {
4017         return i.template get<T>();
4018     });
4019 }
4020 
4021 // valarray doesn't have an insert method
4022 template<typename BasicJsonType, typename T,
4023          enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::valarray<T> & l)4024 void from_json(const BasicJsonType& j, std::valarray<T>& l)
4025 {
4026     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4027     {
4028         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4029     }
4030     l.resize(j.size());
4031     std::transform(j.begin(), j.end(), std::begin(l),
4032                    [](const BasicJsonType & elem)
4033     {
4034         return elem.template get<T>();
4035     });
4036 }
4037 
4038 template<typename BasicJsonType, typename T, std::size_t N>
from_json(const BasicJsonType & j,T (& arr)[N])4039 auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4040 -> decltype(j.template get<T>(), void())
4041 {
4042     for (std::size_t i = 0; i < N; ++i)
4043     {
4044         arr[i] = j.at(i).template get<T>();
4045     }
4046 }
4047 
4048 template<typename BasicJsonType>
from_json_array_impl(const BasicJsonType & j,typename BasicJsonType::array_t & arr,priority_tag<3>)4049 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4050 {
4051     arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4052 }
4053 
4054 template<typename BasicJsonType, typename T, std::size_t N>
from_json_array_impl(const BasicJsonType & j,std::array<T,N> & arr,priority_tag<2>)4055 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4056                           priority_tag<2> /*unused*/)
4057 -> decltype(j.template get<T>(), void())
4058 {
4059     for (std::size_t i = 0; i < N; ++i)
4060     {
4061         arr[i] = j.at(i).template get<T>();
4062     }
4063 }
4064 
4065 template<typename BasicJsonType, typename ConstructibleArrayType,
4066          enable_if_t<
4067              std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4068              int> = 0>
from_json_array_impl(const BasicJsonType & j,ConstructibleArrayType & arr,priority_tag<1>)4069 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4070 -> decltype(
4071     arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4072     j.template get<typename ConstructibleArrayType::value_type>(),
4073     void())
4074 {
4075     using std::end;
4076 
4077     ConstructibleArrayType ret;
4078     ret.reserve(j.size());
4079     std::transform(j.begin(), j.end(),
4080                    std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4081     {
4082         // get<BasicJsonType>() returns *this, this won't call a from_json
4083         // method when value_type is BasicJsonType
4084         return i.template get<typename ConstructibleArrayType::value_type>();
4085     });
4086     arr = std::move(ret);
4087 }
4088 
4089 template<typename BasicJsonType, typename ConstructibleArrayType,
4090          enable_if_t<
4091              std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4092              int> = 0>
from_json_array_impl(const BasicJsonType & j,ConstructibleArrayType & arr,priority_tag<0>)4093 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4094                           priority_tag<0> /*unused*/)
4095 {
4096     using std::end;
4097 
4098     ConstructibleArrayType ret;
4099     std::transform(
4100         j.begin(), j.end(), std::inserter(ret, end(ret)),
4101         [](const BasicJsonType & i)
4102     {
4103         // get<BasicJsonType>() returns *this, this won't call a from_json
4104         // method when value_type is BasicJsonType
4105         return i.template get<typename ConstructibleArrayType::value_type>();
4106     });
4107     arr = std::move(ret);
4108 }
4109 
4110 template < typename BasicJsonType, typename ConstructibleArrayType,
4111            enable_if_t <
4112                is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4113                !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4114                !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
4115                !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4116                !is_basic_json<ConstructibleArrayType>::value,
4117                int > = 0 >
from_json(const BasicJsonType & j,ConstructibleArrayType & arr)4118 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4119 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4120 j.template get<typename ConstructibleArrayType::value_type>(),
4121 void())
4122 {
4123     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4124     {
4125         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4126     }
4127 
4128     from_json_array_impl(j, arr, priority_tag<3> {});
4129 }
4130 
4131 template < typename BasicJsonType, typename T, std::size_t... Idx >
from_json_inplace_array_impl(BasicJsonType && j,identity_tag<std::array<T,sizeof...(Idx)>>,index_sequence<Idx...>)4132 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4133         identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4134 {
4135     return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4136 }
4137 
4138 template < typename BasicJsonType, typename T, std::size_t N >
from_json(BasicJsonType && j,identity_tag<std::array<T,N>> tag)4139 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4140 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4141 {
4142     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4143     {
4144         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4145     }
4146 
4147     return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4148 }
4149 
4150 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::binary_t & bin)4151 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4152 {
4153     if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4154     {
4155         JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
4156     }
4157 
4158     bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4159 }
4160 
4161 template<typename BasicJsonType, typename ConstructibleObjectType,
4162          enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
from_json(const BasicJsonType & j,ConstructibleObjectType & obj)4163 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4164 {
4165     if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4166     {
4167         JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
4168     }
4169 
4170     ConstructibleObjectType ret;
4171     const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4172     using value_type = typename ConstructibleObjectType::value_type;
4173     std::transform(
4174         inner_object->begin(), inner_object->end(),
4175         std::inserter(ret, ret.begin()),
4176         [](typename BasicJsonType::object_t::value_type const & p)
4177     {
4178         return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4179     });
4180     obj = std::move(ret);
4181 }
4182 
4183 // overload for arithmetic types, not chosen for basic_json template arguments
4184 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4185 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4186 // an arithmetic type?
4187 template < typename BasicJsonType, typename ArithmeticType,
4188            enable_if_t <
4189                std::is_arithmetic<ArithmeticType>::value&&
4190                !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4191                !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4192                !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4193                !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4194                int > = 0 >
from_json(const BasicJsonType & j,ArithmeticType & val)4195 void from_json(const BasicJsonType& j, ArithmeticType& val)
4196 {
4197     switch (static_cast<value_t>(j))
4198     {
4199         case value_t::number_unsigned:
4200         {
4201             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4202             break;
4203         }
4204         case value_t::number_integer:
4205         {
4206             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4207             break;
4208         }
4209         case value_t::number_float:
4210         {
4211             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4212             break;
4213         }
4214         case value_t::boolean:
4215         {
4216             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4217             break;
4218         }
4219 
4220         case value_t::null:
4221         case value_t::object:
4222         case value_t::array:
4223         case value_t::string:
4224         case value_t::binary:
4225         case value_t::discarded:
4226         default:
4227             JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4228     }
4229 }
4230 
4231 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
from_json_tuple_impl_base(BasicJsonType && j,index_sequence<Idx...>)4232 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4233 {
4234     return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4235 }
4236 
4237 template < typename BasicJsonType, class A1, class A2 >
from_json_tuple_impl(BasicJsonType && j,identity_tag<std::pair<A1,A2>>,priority_tag<0>)4238 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4239 {
4240     return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4241             std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4242 }
4243 
4244 template<typename BasicJsonType, typename A1, typename A2>
from_json_tuple_impl(BasicJsonType && j,std::pair<A1,A2> & p,priority_tag<1>)4245 void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4246 {
4247     p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4248 }
4249 
4250 template<typename BasicJsonType, typename... Args>
from_json_tuple_impl(BasicJsonType && j,identity_tag<std::tuple<Args...>>,priority_tag<2>)4251 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4252 {
4253     return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4254 }
4255 
4256 template<typename BasicJsonType, typename... Args>
from_json_tuple_impl(BasicJsonType && j,std::tuple<Args...> & t,priority_tag<3>)4257 void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4258 {
4259     t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4260 }
4261 
4262 template<typename BasicJsonType, typename TupleRelated>
from_json(BasicJsonType && j,TupleRelated && t)4263 auto from_json(BasicJsonType&& j, TupleRelated&& t)
4264 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4265 {
4266     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4267     {
4268         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4269     }
4270 
4271     return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4272 }
4273 
4274 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4275            typename = enable_if_t < !std::is_constructible <
4276                                         typename BasicJsonType::string_t, Key >::value >>
from_json(const BasicJsonType & j,std::map<Key,Value,Compare,Allocator> & m)4277 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4278 {
4279     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4280     {
4281         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4282     }
4283     m.clear();
4284     for (const auto& p : j)
4285     {
4286         if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4287         {
4288             JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4289         }
4290         m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4291     }
4292 }
4293 
4294 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4295            typename = enable_if_t < !std::is_constructible <
4296                                         typename BasicJsonType::string_t, Key >::value >>
from_json(const BasicJsonType & j,std::unordered_map<Key,Value,Hash,KeyEqual,Allocator> & m)4297 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4298 {
4299     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4300     {
4301         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4302     }
4303     m.clear();
4304     for (const auto& p : j)
4305     {
4306         if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4307         {
4308             JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4309         }
4310         m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4311     }
4312 }
4313 
4314 struct from_json_fn
4315 {
4316     template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::from_json_fn4317     auto operator()(const BasicJsonType& j, T&& val) const
4318     noexcept(noexcept(from_json(j, std::forward<T>(val))))
4319     -> decltype(from_json(j, std::forward<T>(val)))
4320     {
4321         return from_json(j, std::forward<T>(val));
4322     }
4323 };
4324 }  // namespace detail
4325 
4326 /// namespace to hold default `from_json` function
4327 /// to see why this is required:
4328 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
4329 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4330 {
4331 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4332 } // namespace
4333 } // namespace nlohmann
4334 
4335 // #include <nlohmann/detail/conversions/to_json.hpp>
4336 
4337 
4338 #include <algorithm> // copy
4339 #include <iterator> // begin, end
4340 #include <string> // string
4341 #include <tuple> // tuple, get
4342 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4343 #include <utility> // move, forward, declval, pair
4344 #include <valarray> // valarray
4345 #include <vector> // vector
4346 
4347 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4348 
4349 
4350 #include <cstddef> // size_t
4351 #include <iterator> // input_iterator_tag
4352 #include <string> // string, to_string
4353 #include <tuple> // tuple_size, get, tuple_element
4354 #include <utility> // move
4355 
4356 // #include <nlohmann/detail/meta/type_traits.hpp>
4357 
4358 // #include <nlohmann/detail/value_t.hpp>
4359 
4360 
4361 namespace nlohmann
4362 {
4363 namespace detail
4364 {
4365 template<typename string_type>
int_to_string(string_type & target,std::size_t value)4366 void int_to_string( string_type& target, std::size_t value )
4367 {
4368     // For ADL
4369     using std::to_string;
4370     target = to_string(value);
4371 }
4372 template<typename IteratorType> class iteration_proxy_value
4373 {
4374   public:
4375     using difference_type = std::ptrdiff_t;
4376     using value_type = iteration_proxy_value;
4377     using pointer = value_type * ;
4378     using reference = value_type & ;
4379     using iterator_category = std::input_iterator_tag;
4380     using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4381 
4382   private:
4383     /// the iterator
4384     IteratorType anchor;
4385     /// an index for arrays (used to create key names)
4386     std::size_t array_index = 0;
4387     /// last stringified array index
4388     mutable std::size_t array_index_last = 0;
4389     /// a string representation of the array index
4390     mutable string_type array_index_str = "0";
4391     /// an empty string (to return a reference for primitive values)
4392     const string_type empty_str{};
4393 
4394   public:
iteration_proxy_value(IteratorType it)4395     explicit iteration_proxy_value(IteratorType it) noexcept
4396         : anchor(std::move(it))
4397     {}
4398 
4399     /// dereference operator (needed for range-based for)
operator *()4400     iteration_proxy_value& operator*()
4401     {
4402         return *this;
4403     }
4404 
4405     /// increment operator (needed for range-based for)
operator ++()4406     iteration_proxy_value& operator++()
4407     {
4408         ++anchor;
4409         ++array_index;
4410 
4411         return *this;
4412     }
4413 
4414     /// equality operator (needed for InputIterator)
operator ==(const iteration_proxy_value & o) const4415     bool operator==(const iteration_proxy_value& o) const
4416     {
4417         return anchor == o.anchor;
4418     }
4419 
4420     /// inequality operator (needed for range-based for)
operator !=(const iteration_proxy_value & o) const4421     bool operator!=(const iteration_proxy_value& o) const
4422     {
4423         return anchor != o.anchor;
4424     }
4425 
4426     /// return key of the iterator
key() const4427     const string_type& key() const
4428     {
4429         JSON_ASSERT(anchor.m_object != nullptr);
4430 
4431         switch (anchor.m_object->type())
4432         {
4433             // use integer array index as key
4434             case value_t::array:
4435             {
4436                 if (array_index != array_index_last)
4437                 {
4438                     int_to_string( array_index_str, array_index );
4439                     array_index_last = array_index;
4440                 }
4441                 return array_index_str;
4442             }
4443 
4444             // use key from the object
4445             case value_t::object:
4446                 return anchor.key();
4447 
4448             // use an empty key for all primitive types
4449             case value_t::null:
4450             case value_t::string:
4451             case value_t::boolean:
4452             case value_t::number_integer:
4453             case value_t::number_unsigned:
4454             case value_t::number_float:
4455             case value_t::binary:
4456             case value_t::discarded:
4457             default:
4458                 return empty_str;
4459         }
4460     }
4461 
4462     /// return value of the iterator
value() const4463     typename IteratorType::reference value() const
4464     {
4465         return anchor.value();
4466     }
4467 };
4468 
4469 /// proxy class for the items() function
4470 template<typename IteratorType> class iteration_proxy
4471 {
4472   private:
4473     /// the container to iterate
4474     typename IteratorType::reference container;
4475 
4476   public:
4477     /// construct iteration proxy from a container
iteration_proxy(typename IteratorType::reference cont)4478     explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4479         : container(cont) {}
4480 
4481     /// return iterator begin (needed for range-based for)
begin()4482     iteration_proxy_value<IteratorType> begin() noexcept
4483     {
4484         return iteration_proxy_value<IteratorType>(container.begin());
4485     }
4486 
4487     /// return iterator end (needed for range-based for)
end()4488     iteration_proxy_value<IteratorType> end() noexcept
4489     {
4490         return iteration_proxy_value<IteratorType>(container.end());
4491     }
4492 };
4493 // Structured Bindings Support
4494 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4495 // And see https://github.com/nlohmann/json/pull/1391
4496 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
get(const nlohmann::detail::iteration_proxy_value<IteratorType> & i)4497 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
4498 {
4499     return i.key();
4500 }
4501 // Structured Bindings Support
4502 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4503 // And see https://github.com/nlohmann/json/pull/1391
4504 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
get(const nlohmann::detail::iteration_proxy_value<IteratorType> & i)4505 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4506 {
4507     return i.value();
4508 }
4509 }  // namespace detail
4510 }  // namespace nlohmann
4511 
4512 // The Addition to the STD Namespace is required to add
4513 // Structured Bindings Support to the iteration_proxy_value class
4514 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4515 // And see https://github.com/nlohmann/json/pull/1391
4516 namespace std
4517 {
4518 #if defined(__clang__)
4519     // Fix: https://github.com/nlohmann/json/issues/1401
4520     #pragma clang diagnostic push
4521     #pragma clang diagnostic ignored "-Wmismatched-tags"
4522 #endif
4523 template<typename IteratorType>
4524 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4525             : public std::integral_constant<std::size_t, 2> {};
4526 
4527 template<std::size_t N, typename IteratorType>
4528 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4529 {
4530   public:
4531     using type = decltype(
4532                      get<N>(std::declval <
4533                             ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
4534 };
4535 #if defined(__clang__)
4536     #pragma clang diagnostic pop
4537 #endif
4538 } // namespace std
4539 
4540 // #include <nlohmann/detail/meta/cpp_future.hpp>
4541 
4542 // #include <nlohmann/detail/meta/type_traits.hpp>
4543 
4544 // #include <nlohmann/detail/value_t.hpp>
4545 
4546 
4547 namespace nlohmann
4548 {
4549 namespace detail
4550 {
4551 //////////////////
4552 // constructors //
4553 //////////////////
4554 
4555 /*
4556  * Note all external_constructor<>::construct functions need to call
4557  * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4558  * allocated value (e.g., a string). See bug issue
4559  * https://github.com/nlohmann/json/issues/2865 for more information.
4560  */
4561 
4562 template<value_t> struct external_constructor;
4563 
4564 template<>
4565 struct external_constructor<value_t::boolean>
4566 {
4567     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4568     static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4569     {
4570         j.m_value.destroy(j.m_type);
4571         j.m_type = value_t::boolean;
4572         j.m_value = b;
4573         j.assert_invariant();
4574     }
4575 };
4576 
4577 template<>
4578 struct external_constructor<value_t::string>
4579 {
4580     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4581     static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4582     {
4583         j.m_value.destroy(j.m_type);
4584         j.m_type = value_t::string;
4585         j.m_value = s;
4586         j.assert_invariant();
4587     }
4588 
4589     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4590     static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4591     {
4592         j.m_value.destroy(j.m_type);
4593         j.m_type = value_t::string;
4594         j.m_value = std::move(s);
4595         j.assert_invariant();
4596     }
4597 
4598     template < typename BasicJsonType, typename CompatibleStringType,
4599                enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4600                              int > = 0 >
constructnlohmann::detail::external_constructor4601     static void construct(BasicJsonType& j, const CompatibleStringType& str)
4602     {
4603         j.m_value.destroy(j.m_type);
4604         j.m_type = value_t::string;
4605         j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4606         j.assert_invariant();
4607     }
4608 };
4609 
4610 template<>
4611 struct external_constructor<value_t::binary>
4612 {
4613     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4614     static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4615     {
4616         j.m_value.destroy(j.m_type);
4617         j.m_type = value_t::binary;
4618         j.m_value = typename BasicJsonType::binary_t(b);
4619         j.assert_invariant();
4620     }
4621 
4622     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4623     static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4624     {
4625         j.m_value.destroy(j.m_type);
4626         j.m_type = value_t::binary;
4627         j.m_value = typename BasicJsonType::binary_t(std::move(b));
4628         j.assert_invariant();
4629     }
4630 };
4631 
4632 template<>
4633 struct external_constructor<value_t::number_float>
4634 {
4635     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4636     static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4637     {
4638         j.m_value.destroy(j.m_type);
4639         j.m_type = value_t::number_float;
4640         j.m_value = val;
4641         j.assert_invariant();
4642     }
4643 };
4644 
4645 template<>
4646 struct external_constructor<value_t::number_unsigned>
4647 {
4648     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4649     static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4650     {
4651         j.m_value.destroy(j.m_type);
4652         j.m_type = value_t::number_unsigned;
4653         j.m_value = val;
4654         j.assert_invariant();
4655     }
4656 };
4657 
4658 template<>
4659 struct external_constructor<value_t::number_integer>
4660 {
4661     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4662     static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4663     {
4664         j.m_value.destroy(j.m_type);
4665         j.m_type = value_t::number_integer;
4666         j.m_value = val;
4667         j.assert_invariant();
4668     }
4669 };
4670 
4671 template<>
4672 struct external_constructor<value_t::array>
4673 {
4674     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4675     static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4676     {
4677         j.m_value.destroy(j.m_type);
4678         j.m_type = value_t::array;
4679         j.m_value = arr;
4680         j.set_parents();
4681         j.assert_invariant();
4682     }
4683 
4684     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4685     static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4686     {
4687         j.m_value.destroy(j.m_type);
4688         j.m_type = value_t::array;
4689         j.m_value = std::move(arr);
4690         j.set_parents();
4691         j.assert_invariant();
4692     }
4693 
4694     template < typename BasicJsonType, typename CompatibleArrayType,
4695                enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4696                              int > = 0 >
constructnlohmann::detail::external_constructor4697     static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4698     {
4699         using std::begin;
4700         using std::end;
4701 
4702         j.m_value.destroy(j.m_type);
4703         j.m_type = value_t::array;
4704         j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4705         j.set_parents();
4706         j.assert_invariant();
4707     }
4708 
4709     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4710     static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4711     {
4712         j.m_value.destroy(j.m_type);
4713         j.m_type = value_t::array;
4714         j.m_value = value_t::array;
4715         j.m_value.array->reserve(arr.size());
4716         for (const bool x : arr)
4717         {
4718             j.m_value.array->push_back(x);
4719             j.set_parent(j.m_value.array->back());
4720         }
4721         j.assert_invariant();
4722     }
4723 
4724     template<typename BasicJsonType, typename T,
4725              enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
constructnlohmann::detail::external_constructor4726     static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4727     {
4728         j.m_value.destroy(j.m_type);
4729         j.m_type = value_t::array;
4730         j.m_value = value_t::array;
4731         j.m_value.array->resize(arr.size());
4732         if (arr.size() > 0)
4733         {
4734             std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4735         }
4736         j.set_parents();
4737         j.assert_invariant();
4738     }
4739 };
4740 
4741 template<>
4742 struct external_constructor<value_t::object>
4743 {
4744     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4745     static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4746     {
4747         j.m_value.destroy(j.m_type);
4748         j.m_type = value_t::object;
4749         j.m_value = obj;
4750         j.set_parents();
4751         j.assert_invariant();
4752     }
4753 
4754     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4755     static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4756     {
4757         j.m_value.destroy(j.m_type);
4758         j.m_type = value_t::object;
4759         j.m_value = std::move(obj);
4760         j.set_parents();
4761         j.assert_invariant();
4762     }
4763 
4764     template < typename BasicJsonType, typename CompatibleObjectType,
4765                enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
constructnlohmann::detail::external_constructor4766     static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4767     {
4768         using std::begin;
4769         using std::end;
4770 
4771         j.m_value.destroy(j.m_type);
4772         j.m_type = value_t::object;
4773         j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4774         j.set_parents();
4775         j.assert_invariant();
4776     }
4777 };
4778 
4779 /////////////
4780 // to_json //
4781 /////////////
4782 
4783 template<typename BasicJsonType, typename T,
4784          enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
to_json(BasicJsonType & j,T b)4785 void to_json(BasicJsonType& j, T b) noexcept
4786 {
4787     external_constructor<value_t::boolean>::construct(j, b);
4788 }
4789 
4790 template<typename BasicJsonType, typename CompatibleString,
4791          enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleString & s)4792 void to_json(BasicJsonType& j, const CompatibleString& s)
4793 {
4794     external_constructor<value_t::string>::construct(j, s);
4795 }
4796 
4797 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::string_t && s)4798 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4799 {
4800     external_constructor<value_t::string>::construct(j, std::move(s));
4801 }
4802 
4803 template<typename BasicJsonType, typename FloatType,
4804          enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
to_json(BasicJsonType & j,FloatType val)4805 void to_json(BasicJsonType& j, FloatType val) noexcept
4806 {
4807     external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4808 }
4809 
4810 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4811          enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberUnsignedType val)4812 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4813 {
4814     external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4815 }
4816 
4817 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4818          enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberIntegerType val)4819 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4820 {
4821     external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4822 }
4823 
4824 template<typename BasicJsonType, typename EnumType,
4825          enable_if_t<std::is_enum<EnumType>::value, int> = 0>
to_json(BasicJsonType & j,EnumType e)4826 void to_json(BasicJsonType& j, EnumType e) noexcept
4827 {
4828     using underlying_type = typename std::underlying_type<EnumType>::type;
4829     external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4830 }
4831 
4832 template<typename BasicJsonType>
to_json(BasicJsonType & j,const std::vector<bool> & e)4833 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4834 {
4835     external_constructor<value_t::array>::construct(j, e);
4836 }
4837 
4838 template < typename BasicJsonType, typename CompatibleArrayType,
4839            enable_if_t < is_compatible_array_type<BasicJsonType,
4840                          CompatibleArrayType>::value&&
4841                          !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4842                          !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4843                          !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4844                          !is_basic_json<CompatibleArrayType>::value,
4845                          int > = 0 >
to_json(BasicJsonType & j,const CompatibleArrayType & arr)4846 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4847 {
4848     external_constructor<value_t::array>::construct(j, arr);
4849 }
4850 
4851 template<typename BasicJsonType>
to_json(BasicJsonType & j,const typename BasicJsonType::binary_t & bin)4852 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4853 {
4854     external_constructor<value_t::binary>::construct(j, bin);
4855 }
4856 
4857 template<typename BasicJsonType, typename T,
4858          enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
to_json(BasicJsonType & j,const std::valarray<T> & arr)4859 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4860 {
4861     external_constructor<value_t::array>::construct(j, std::move(arr));
4862 }
4863 
4864 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::array_t && arr)4865 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4866 {
4867     external_constructor<value_t::array>::construct(j, std::move(arr));
4868 }
4869 
4870 template < typename BasicJsonType, typename CompatibleObjectType,
4871            enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
to_json(BasicJsonType & j,const CompatibleObjectType & obj)4872 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4873 {
4874     external_constructor<value_t::object>::construct(j, obj);
4875 }
4876 
4877 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::object_t && obj)4878 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4879 {
4880     external_constructor<value_t::object>::construct(j, std::move(obj));
4881 }
4882 
4883 template <
4884     typename BasicJsonType, typename T, std::size_t N,
4885     enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4886                   const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4887                   int > = 0 >
to_json(BasicJsonType & j,const T (& arr)[N])4888 void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4889 {
4890     external_constructor<value_t::array>::construct(j, arr);
4891 }
4892 
4893 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
to_json(BasicJsonType & j,const std::pair<T1,T2> & p)4894 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4895 {
4896     j = { p.first, p.second };
4897 }
4898 
4899 // for https://github.com/nlohmann/json/pull/1134
4900 template<typename BasicJsonType, typename T,
4901          enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
to_json(BasicJsonType & j,const T & b)4902 void to_json(BasicJsonType& j, const T& b)
4903 {
4904     j = { {b.key(), b.value()} };
4905 }
4906 
4907 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
to_json_tuple_impl(BasicJsonType & j,const Tuple & t,index_sequence<Idx...>)4908 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4909 {
4910     j = { std::get<Idx>(t)... };
4911 }
4912 
4913 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
to_json(BasicJsonType & j,const T & t)4914 void to_json(BasicJsonType& j, const T& t)
4915 {
4916     to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4917 }
4918 
4919 struct to_json_fn
4920 {
4921     template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::to_json_fn4922     auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4923     -> decltype(to_json(j, std::forward<T>(val)), void())
4924     {
4925         return to_json(j, std::forward<T>(val));
4926     }
4927 };
4928 }  // namespace detail
4929 
4930 /// namespace to hold default `to_json` function
4931 /// to see why this is required:
4932 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
4933 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4934 {
4935 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4936 } // namespace
4937 } // namespace nlohmann
4938 
4939 // #include <nlohmann/detail/meta/identity_tag.hpp>
4940 
4941 // #include <nlohmann/detail/meta/type_traits.hpp>
4942 
4943 
4944 namespace nlohmann
4945 {
4946 
4947 template<typename ValueType, typename>
4948 struct adl_serializer
4949 {
4950     /*!
4951     @brief convert a JSON value to any value type
4952 
4953     This function is usually called by the `get()` function of the
4954     @ref basic_json class (either explicit or via conversion operators).
4955 
4956     @note This function is chosen for default-constructible value types.
4957 
4958     @param[in] j        JSON value to read from
4959     @param[in,out] val  value to write to
4960     */
4961     template<typename BasicJsonType, typename TargetType = ValueType>
from_jsonnlohmann::adl_serializer4962     static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
4963         noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4964     -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4965     {
4966         ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4967     }
4968 
4969     /*!
4970     @brief convert a JSON value to any value type
4971 
4972     This function is usually called by the `get()` function of the
4973     @ref basic_json class (either explicit or via conversion operators).
4974 
4975     @note This function is chosen for value types which are not default-constructible.
4976 
4977     @param[in] j  JSON value to read from
4978 
4979     @return copy of the JSON value, converted to @a ValueType
4980     */
4981     template<typename BasicJsonType, typename TargetType = ValueType>
from_jsonnlohmann::adl_serializer4982     static auto from_json(BasicJsonType && j) noexcept(
4983     noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
4984     -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
4985     {
4986         return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
4987     }
4988 
4989     /*!
4990     @brief convert any value type to a JSON value
4991 
4992     This function is usually called by the constructors of the @ref basic_json
4993     class.
4994 
4995     @param[in,out] j  JSON value to write to
4996     @param[in] val    value to read from
4997     */
4998     template<typename BasicJsonType, typename TargetType = ValueType>
to_jsonnlohmann::adl_serializer4999     static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5000         noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5001     -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5002     {
5003         ::nlohmann::to_json(j, std::forward<TargetType>(val));
5004     }
5005 };
5006 }  // namespace nlohmann
5007 
5008 // #include <nlohmann/byte_container_with_subtype.hpp>
5009 
5010 
5011 #include <cstdint> // uint8_t, uint64_t
5012 #include <tuple> // tie
5013 #include <utility> // move
5014 
5015 namespace nlohmann
5016 {
5017 
5018 /*!
5019 @brief an internal type for a backed binary type
5020 
5021 This type extends the template parameter @a BinaryType provided to `basic_json`
5022 with a subtype used by BSON and MessagePack. This type exists so that the user
5023 does not have to specify a type themselves with a specific naming scheme in
5024 order to override the binary type.
5025 
5026 @tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by
5027                    default)
5028 
5029 @since version 3.8.0; changed type of subtypes to std::uint64_t in 3.10.0.
5030 */
5031 template<typename BinaryType>
5032 class byte_container_with_subtype : public BinaryType
5033 {
5034   public:
5035     /// the type of the underlying container
5036     using container_type = BinaryType;
5037     /// the type of the subtype
5038     using subtype_type = std::uint64_t;
5039 
byte_container_with_subtype()5040     byte_container_with_subtype() noexcept(noexcept(container_type()))
5041         : container_type()
5042     {}
5043 
byte_container_with_subtype(const container_type & b)5044     byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
5045         : container_type(b)
5046     {}
5047 
byte_container_with_subtype(container_type && b)5048     byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5049         : container_type(std::move(b))
5050     {}
5051 
byte_container_with_subtype(const container_type & b,subtype_type subtype_)5052     byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
5053         : container_type(b)
5054         , m_subtype(subtype_)
5055         , m_has_subtype(true)
5056     {}
5057 
byte_container_with_subtype(container_type && b,subtype_type subtype_)5058     byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5059         : container_type(std::move(b))
5060         , m_subtype(subtype_)
5061         , m_has_subtype(true)
5062     {}
5063 
operator ==(const byte_container_with_subtype & rhs) const5064     bool operator==(const byte_container_with_subtype& rhs) const
5065     {
5066         return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5067                std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5068     }
5069 
operator !=(const byte_container_with_subtype & rhs) const5070     bool operator!=(const byte_container_with_subtype& rhs) const
5071     {
5072         return !(rhs == *this);
5073     }
5074 
5075     /*!
5076     @brief sets the binary subtype
5077 
5078     Sets the binary subtype of the value, also flags a binary JSON value as
5079     having a subtype, which has implications for serialization.
5080 
5081     @complexity Constant.
5082 
5083     @exceptionsafety No-throw guarantee: this member function never throws
5084     exceptions.
5085 
5086     @sa see @ref subtype() -- return the binary subtype
5087     @sa see @ref clear_subtype() -- clears the binary subtype
5088     @sa see @ref has_subtype() -- returns whether or not the binary value has a
5089     subtype
5090 
5091     @since version 3.8.0
5092     */
set_subtype(subtype_type subtype_)5093     void set_subtype(subtype_type subtype_) noexcept
5094     {
5095         m_subtype = subtype_;
5096         m_has_subtype = true;
5097     }
5098 
5099     /*!
5100     @brief return the binary subtype
5101 
5102     Returns the numerical subtype of the value if it has a subtype. If it does
5103     not have a subtype, this function will return subtype_type(-1) as a sentinel
5104     value.
5105 
5106     @return the numerical subtype of the binary value
5107 
5108     @complexity Constant.
5109 
5110     @exceptionsafety No-throw guarantee: this member function never throws
5111     exceptions.
5112 
5113     @sa see @ref set_subtype() -- sets the binary subtype
5114     @sa see @ref clear_subtype() -- clears the binary subtype
5115     @sa see @ref has_subtype() -- returns whether or not the binary value has a
5116     subtype
5117 
5118     @since version 3.8.0; fixed return value to properly return
5119            subtype_type(-1) as documented in version 3.10.0
5120     */
subtype() const5121     constexpr subtype_type subtype() const noexcept
5122     {
5123         return m_has_subtype ? m_subtype : subtype_type(-1);
5124     }
5125 
5126     /*!
5127     @brief return whether the value has a subtype
5128 
5129     @return whether the value has a subtype
5130 
5131     @complexity Constant.
5132 
5133     @exceptionsafety No-throw guarantee: this member function never throws
5134     exceptions.
5135 
5136     @sa see @ref subtype() -- return the binary subtype
5137     @sa see @ref set_subtype() -- sets the binary subtype
5138     @sa see @ref clear_subtype() -- clears the binary subtype
5139 
5140     @since version 3.8.0
5141     */
has_subtype() const5142     constexpr bool has_subtype() const noexcept
5143     {
5144         return m_has_subtype;
5145     }
5146 
5147     /*!
5148     @brief clears the binary subtype
5149 
5150     Clears the binary subtype and flags the value as not having a subtype, which
5151     has implications for serialization; for instance MessagePack will prefer the
5152     bin family over the ext family.
5153 
5154     @complexity Constant.
5155 
5156     @exceptionsafety No-throw guarantee: this member function never throws
5157     exceptions.
5158 
5159     @sa see @ref subtype() -- return the binary subtype
5160     @sa see @ref set_subtype() -- sets the binary subtype
5161     @sa see @ref has_subtype() -- returns whether or not the binary value has a
5162     subtype
5163 
5164     @since version 3.8.0
5165     */
clear_subtype()5166     void clear_subtype() noexcept
5167     {
5168         m_subtype = 0;
5169         m_has_subtype = false;
5170     }
5171 
5172   private:
5173     subtype_type m_subtype = 0;
5174     bool m_has_subtype = false;
5175 };
5176 
5177 }  // namespace nlohmann
5178 
5179 // #include <nlohmann/detail/conversions/from_json.hpp>
5180 
5181 // #include <nlohmann/detail/conversions/to_json.hpp>
5182 
5183 // #include <nlohmann/detail/exceptions.hpp>
5184 
5185 // #include <nlohmann/detail/hash.hpp>
5186 
5187 
5188 #include <cstdint> // uint8_t
5189 #include <cstddef> // size_t
5190 #include <functional> // hash
5191 
5192 // #include <nlohmann/detail/macro_scope.hpp>
5193 
5194 // #include <nlohmann/detail/value_t.hpp>
5195 
5196 
5197 namespace nlohmann
5198 {
5199 namespace detail
5200 {
5201 
5202 // boost::hash_combine
combine(std::size_t seed,std::size_t h)5203 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5204 {
5205     seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5206     return seed;
5207 }
5208 
5209 /*!
5210 @brief hash a JSON value
5211 
5212 The hash function tries to rely on std::hash where possible. Furthermore, the
5213 type of the JSON value is taken into account to have different hash values for
5214 null, 0, 0U, and false, etc.
5215 
5216 @tparam BasicJsonType basic_json specialization
5217 @param j JSON value to hash
5218 @return hash value of j
5219 */
5220 template<typename BasicJsonType>
hash(const BasicJsonType & j)5221 std::size_t hash(const BasicJsonType& j)
5222 {
5223     using string_t = typename BasicJsonType::string_t;
5224     using number_integer_t = typename BasicJsonType::number_integer_t;
5225     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5226     using number_float_t = typename BasicJsonType::number_float_t;
5227 
5228     const auto type = static_cast<std::size_t>(j.type());
5229     switch (j.type())
5230     {
5231         case BasicJsonType::value_t::null:
5232         case BasicJsonType::value_t::discarded:
5233         {
5234             return combine(type, 0);
5235         }
5236 
5237         case BasicJsonType::value_t::object:
5238         {
5239             auto seed = combine(type, j.size());
5240             for (const auto& element : j.items())
5241             {
5242                 const auto h = std::hash<string_t> {}(element.key());
5243                 seed = combine(seed, h);
5244                 seed = combine(seed, hash(element.value()));
5245             }
5246             return seed;
5247         }
5248 
5249         case BasicJsonType::value_t::array:
5250         {
5251             auto seed = combine(type, j.size());
5252             for (const auto& element : j)
5253             {
5254                 seed = combine(seed, hash(element));
5255             }
5256             return seed;
5257         }
5258 
5259         case BasicJsonType::value_t::string:
5260         {
5261             const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5262             return combine(type, h);
5263         }
5264 
5265         case BasicJsonType::value_t::boolean:
5266         {
5267             const auto h = std::hash<bool> {}(j.template get<bool>());
5268             return combine(type, h);
5269         }
5270 
5271         case BasicJsonType::value_t::number_integer:
5272         {
5273             const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5274             return combine(type, h);
5275         }
5276 
5277         case BasicJsonType::value_t::number_unsigned:
5278         {
5279             const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5280             return combine(type, h);
5281         }
5282 
5283         case BasicJsonType::value_t::number_float:
5284         {
5285             const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5286             return combine(type, h);
5287         }
5288 
5289         case BasicJsonType::value_t::binary:
5290         {
5291             auto seed = combine(type, j.get_binary().size());
5292             const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5293             seed = combine(seed, h);
5294             seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5295             for (const auto byte : j.get_binary())
5296             {
5297                 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5298             }
5299             return seed;
5300         }
5301 
5302         default:                   // LCOV_EXCL_LINE
5303             JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5304             return 0;              // LCOV_EXCL_LINE
5305     }
5306 }
5307 
5308 }  // namespace detail
5309 }  // namespace nlohmann
5310 
5311 // #include <nlohmann/detail/input/binary_reader.hpp>
5312 
5313 
5314 #include <algorithm> // generate_n
5315 #include <array> // array
5316 #include <cmath> // ldexp
5317 #include <cstddef> // size_t
5318 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5319 #include <cstdio> // snprintf
5320 #include <cstring> // memcpy
5321 #include <iterator> // back_inserter
5322 #include <limits> // numeric_limits
5323 #include <string> // char_traits, string
5324 #include <utility> // make_pair, move
5325 #include <vector> // vector
5326 
5327 // #include <nlohmann/detail/exceptions.hpp>
5328 
5329 // #include <nlohmann/detail/input/input_adapters.hpp>
5330 
5331 
5332 #include <array> // array
5333 #include <cstddef> // size_t
5334 #include <cstring> // strlen
5335 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5336 #include <memory> // shared_ptr, make_shared, addressof
5337 #include <numeric> // accumulate
5338 #include <string> // string, char_traits
5339 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5340 #include <utility> // pair, declval
5341 
5342 #ifndef JSON_NO_IO
5343     #include <cstdio>   // FILE *
5344     #include <istream>  // istream
5345 #endif                  // JSON_NO_IO
5346 
5347 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
5348 
5349 // #include <nlohmann/detail/macro_scope.hpp>
5350 
5351 
5352 namespace nlohmann
5353 {
5354 namespace detail
5355 {
5356 /// the supported input formats
5357 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
5358 
5359 ////////////////////
5360 // input adapters //
5361 ////////////////////
5362 
5363 #ifndef JSON_NO_IO
5364 /*!
5365 Input adapter for stdio file access. This adapter read only 1 byte and do not use any
5366  buffer. This adapter is a very low level adapter.
5367 */
5368 class file_input_adapter
5369 {
5370   public:
5371     using char_type = char;
5372 
5373     JSON_HEDLEY_NON_NULL(2)
file_input_adapter(std::FILE * f)5374     explicit file_input_adapter(std::FILE* f) noexcept
5375         : m_file(f)
5376     {}
5377 
5378     // make class move-only
5379     file_input_adapter(const file_input_adapter&) = delete;
5380     file_input_adapter(file_input_adapter&&) noexcept = default;
5381     file_input_adapter& operator=(const file_input_adapter&) = delete;
5382     file_input_adapter& operator=(file_input_adapter&&) = delete;
5383     ~file_input_adapter() = default;
5384 
get_character()5385     std::char_traits<char>::int_type get_character() noexcept
5386     {
5387         return std::fgetc(m_file);
5388     }
5389 
5390   private:
5391     /// the file pointer to read from
5392     std::FILE* m_file;
5393 };
5394 
5395 
5396 /*!
5397 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
5398 beginning of input. Does not support changing the underlying std::streambuf
5399 in mid-input. Maintains underlying std::istream and std::streambuf to support
5400 subsequent use of standard std::istream operations to process any input
5401 characters following those used in parsing the JSON input.  Clears the
5402 std::istream flags; any input errors (e.g., EOF) will be detected by the first
5403 subsequent call for input from the std::istream.
5404 */
5405 class input_stream_adapter
5406 {
5407   public:
5408     using char_type = char;
5409 
~input_stream_adapter()5410     ~input_stream_adapter()
5411     {
5412         // clear stream flags; we use underlying streambuf I/O, do not
5413         // maintain ifstream flags, except eof
5414         if (is != nullptr)
5415         {
5416             is->clear(is->rdstate() & std::ios::eofbit);
5417         }
5418     }
5419 
input_stream_adapter(std::istream & i)5420     explicit input_stream_adapter(std::istream& i)
5421         : is(&i), sb(i.rdbuf())
5422     {}
5423 
5424     // delete because of pointer members
5425     input_stream_adapter(const input_stream_adapter&) = delete;
5426     input_stream_adapter& operator=(input_stream_adapter&) = delete;
5427     input_stream_adapter& operator=(input_stream_adapter&&) = delete;
5428 
input_stream_adapter(input_stream_adapter && rhs)5429     input_stream_adapter(input_stream_adapter&& rhs) noexcept
5430         : is(rhs.is), sb(rhs.sb)
5431     {
5432         rhs.is = nullptr;
5433         rhs.sb = nullptr;
5434     }
5435 
5436     // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5437     // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5438     // end up as the same value, eg. 0xFFFFFFFF.
get_character()5439     std::char_traits<char>::int_type get_character()
5440     {
5441         auto res = sb->sbumpc();
5442         // set eof manually, as we don't use the istream interface.
5443         if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5444         {
5445             is->clear(is->rdstate() | std::ios::eofbit);
5446         }
5447         return res;
5448     }
5449 
5450   private:
5451     /// the associated input stream
5452     std::istream* is = nullptr;
5453     std::streambuf* sb = nullptr;
5454 };
5455 #endif  // JSON_NO_IO
5456 
5457 // General-purpose iterator-based adapter. It might not be as fast as
5458 // theoretically possible for some containers, but it is extremely versatile.
5459 template<typename IteratorType>
5460 class iterator_input_adapter
5461 {
5462   public:
5463     using char_type = typename std::iterator_traits<IteratorType>::value_type;
5464 
iterator_input_adapter(IteratorType first,IteratorType last)5465     iterator_input_adapter(IteratorType first, IteratorType last)
5466         : current(std::move(first)), end(std::move(last))
5467     {}
5468 
get_character()5469     typename std::char_traits<char_type>::int_type get_character()
5470     {
5471         if (JSON_HEDLEY_LIKELY(current != end))
5472         {
5473             auto result = std::char_traits<char_type>::to_int_type(*current);
5474             std::advance(current, 1);
5475             return result;
5476         }
5477 
5478         return std::char_traits<char_type>::eof();
5479     }
5480 
5481   private:
5482     IteratorType current;
5483     IteratorType end;
5484 
5485     template<typename BaseInputAdapter, size_t T>
5486     friend struct wide_string_input_helper;
5487 
empty() const5488     bool empty() const
5489     {
5490         return current == end;
5491     }
5492 };
5493 
5494 
5495 template<typename BaseInputAdapter, size_t T>
5496 struct wide_string_input_helper;
5497 
5498 template<typename BaseInputAdapter>
5499 struct wide_string_input_helper<BaseInputAdapter, 4>
5500 {
5501     // UTF-32
fill_buffernlohmann::detail::wide_string_input_helper5502     static void fill_buffer(BaseInputAdapter& input,
5503                             std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5504                             size_t& utf8_bytes_index,
5505                             size_t& utf8_bytes_filled)
5506     {
5507         utf8_bytes_index = 0;
5508 
5509         if (JSON_HEDLEY_UNLIKELY(input.empty()))
5510         {
5511             utf8_bytes[0] = std::char_traits<char>::eof();
5512             utf8_bytes_filled = 1;
5513         }
5514         else
5515         {
5516             // get the current character
5517             const auto wc = input.get_character();
5518 
5519             // UTF-32 to UTF-8 encoding
5520             if (wc < 0x80)
5521             {
5522                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5523                 utf8_bytes_filled = 1;
5524             }
5525             else if (wc <= 0x7FF)
5526             {
5527                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5528                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5529                 utf8_bytes_filled = 2;
5530             }
5531             else if (wc <= 0xFFFF)
5532             {
5533                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5534                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5535                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5536                 utf8_bytes_filled = 3;
5537             }
5538             else if (wc <= 0x10FFFF)
5539             {
5540                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5541                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5542                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5543                 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5544                 utf8_bytes_filled = 4;
5545             }
5546             else
5547             {
5548                 // unknown character
5549                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5550                 utf8_bytes_filled = 1;
5551             }
5552         }
5553     }
5554 };
5555 
5556 template<typename BaseInputAdapter>
5557 struct wide_string_input_helper<BaseInputAdapter, 2>
5558 {
5559     // UTF-16
fill_buffernlohmann::detail::wide_string_input_helper5560     static void fill_buffer(BaseInputAdapter& input,
5561                             std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5562                             size_t& utf8_bytes_index,
5563                             size_t& utf8_bytes_filled)
5564     {
5565         utf8_bytes_index = 0;
5566 
5567         if (JSON_HEDLEY_UNLIKELY(input.empty()))
5568         {
5569             utf8_bytes[0] = std::char_traits<char>::eof();
5570             utf8_bytes_filled = 1;
5571         }
5572         else
5573         {
5574             // get the current character
5575             const auto wc = input.get_character();
5576 
5577             // UTF-16 to UTF-8 encoding
5578             if (wc < 0x80)
5579             {
5580                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5581                 utf8_bytes_filled = 1;
5582             }
5583             else if (wc <= 0x7FF)
5584             {
5585                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5586                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5587                 utf8_bytes_filled = 2;
5588             }
5589             else if (0xD800 > wc || wc >= 0xE000)
5590             {
5591                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5592                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5593                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5594                 utf8_bytes_filled = 3;
5595             }
5596             else
5597             {
5598                 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5599                 {
5600                     const auto wc2 = static_cast<unsigned int>(input.get_character());
5601                     const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5602                     utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5603                     utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5604                     utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5605                     utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5606                     utf8_bytes_filled = 4;
5607                 }
5608                 else
5609                 {
5610                     utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5611                     utf8_bytes_filled = 1;
5612                 }
5613             }
5614         }
5615     }
5616 };
5617 
5618 // Wraps another input apdater to convert wide character types into individual bytes.
5619 template<typename BaseInputAdapter, typename WideCharType>
5620 class wide_string_input_adapter
5621 {
5622   public:
5623     using char_type = char;
5624 
wide_string_input_adapter(BaseInputAdapter base)5625     wide_string_input_adapter(BaseInputAdapter base)
5626         : base_adapter(base) {}
5627 
get_character()5628     typename std::char_traits<char>::int_type get_character() noexcept
5629     {
5630         // check if buffer needs to be filled
5631         if (utf8_bytes_index == utf8_bytes_filled)
5632         {
5633             fill_buffer<sizeof(WideCharType)>();
5634 
5635             JSON_ASSERT(utf8_bytes_filled > 0);
5636             JSON_ASSERT(utf8_bytes_index == 0);
5637         }
5638 
5639         // use buffer
5640         JSON_ASSERT(utf8_bytes_filled > 0);
5641         JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5642         return utf8_bytes[utf8_bytes_index++];
5643     }
5644 
5645   private:
5646     BaseInputAdapter base_adapter;
5647 
5648     template<size_t T>
fill_buffer()5649     void fill_buffer()
5650     {
5651         wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5652     }
5653 
5654     /// a buffer for UTF-8 bytes
5655     std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5656 
5657     /// index to the utf8_codes array for the next valid byte
5658     std::size_t utf8_bytes_index = 0;
5659     /// number of valid bytes in the utf8_codes array
5660     std::size_t utf8_bytes_filled = 0;
5661 };
5662 
5663 
5664 template<typename IteratorType, typename Enable = void>
5665 struct iterator_input_adapter_factory
5666 {
5667     using iterator_type = IteratorType;
5668     using char_type = typename std::iterator_traits<iterator_type>::value_type;
5669     using adapter_type = iterator_input_adapter<iterator_type>;
5670 
createnlohmann::detail::iterator_input_adapter_factory5671     static adapter_type create(IteratorType first, IteratorType last)
5672     {
5673         return adapter_type(std::move(first), std::move(last));
5674     }
5675 };
5676 
5677 template<typename T>
5678 struct is_iterator_of_multibyte
5679 {
5680     using value_type = typename std::iterator_traits<T>::value_type;
5681     enum
5682     {
5683         value = sizeof(value_type) > 1
5684     };
5685 };
5686 
5687 template<typename IteratorType>
5688 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5689 {
5690     using iterator_type = IteratorType;
5691     using char_type = typename std::iterator_traits<iterator_type>::value_type;
5692     using base_adapter_type = iterator_input_adapter<iterator_type>;
5693     using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5694 
createnlohmann::detail::iterator_input_adapter_factory5695     static adapter_type create(IteratorType first, IteratorType last)
5696     {
5697         return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5698     }
5699 };
5700 
5701 // General purpose iterator-based input
5702 template<typename IteratorType>
input_adapter(IteratorType first,IteratorType last)5703 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5704 {
5705     using factory_type = iterator_input_adapter_factory<IteratorType>;
5706     return factory_type::create(first, last);
5707 }
5708 
5709 // Convenience shorthand from container to iterator
5710 // Enables ADL on begin(container) and end(container)
5711 // Encloses the using declarations in namespace for not to leak them to outside scope
5712 
5713 namespace container_input_adapter_factory_impl
5714 {
5715 
5716 using std::begin;
5717 using std::end;
5718 
5719 template<typename ContainerType, typename Enable = void>
5720 struct container_input_adapter_factory {};
5721 
5722 template<typename ContainerType>
5723 struct container_input_adapter_factory< ContainerType,
5724        void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5725        {
5726            using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5727 
createnlohmann::detail::container_input_adapter_factory_impl::container_input_adapter_factory5728            static adapter_type create(const ContainerType& container)
5729 {
5730     return input_adapter(begin(container), end(container));
5731 }
5732        };
5733 
5734 } // namespace container_input_adapter_factory_impl
5735 
5736 template<typename ContainerType>
input_adapter(const ContainerType & container)5737 typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
5738 {
5739     return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
5740 }
5741 
5742 #ifndef JSON_NO_IO
5743 // Special cases with fast paths
input_adapter(std::FILE * file)5744 inline file_input_adapter input_adapter(std::FILE* file)
5745 {
5746     return file_input_adapter(file);
5747 }
5748 
input_adapter(std::istream & stream)5749 inline input_stream_adapter input_adapter(std::istream& stream)
5750 {
5751     return input_stream_adapter(stream);
5752 }
5753 
input_adapter(std::istream && stream)5754 inline input_stream_adapter input_adapter(std::istream&& stream)
5755 {
5756     return input_stream_adapter(stream);
5757 }
5758 #endif  // JSON_NO_IO
5759 
5760 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5761 
5762 // Null-delimited strings, and the like.
5763 template < typename CharT,
5764            typename std::enable_if <
5765                std::is_pointer<CharT>::value&&
5766                !std::is_array<CharT>::value&&
5767                std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5768                sizeof(typename std::remove_pointer<CharT>::type) == 1,
5769                int >::type = 0 >
input_adapter(CharT b)5770 contiguous_bytes_input_adapter input_adapter(CharT b)
5771 {
5772     auto length = std::strlen(reinterpret_cast<const char*>(b));
5773     const auto* ptr = reinterpret_cast<const char*>(b);
5774     return input_adapter(ptr, ptr + length);
5775 }
5776 
5777 template<typename T, std::size_t N>
input_adapter(T (& array)[N])5778 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)
5779 {
5780     return input_adapter(array, array + N);
5781 }
5782 
5783 // This class only handles inputs of input_buffer_adapter type.
5784 // It's required so that expressions like {ptr, len} can be implicitely casted
5785 // to the correct adapter.
5786 class span_input_adapter
5787 {
5788   public:
5789     template < typename CharT,
5790                typename std::enable_if <
5791                    std::is_pointer<CharT>::value&&
5792                    std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5793                    sizeof(typename std::remove_pointer<CharT>::type) == 1,
5794                    int >::type = 0 >
span_input_adapter(CharT b,std::size_t l)5795     span_input_adapter(CharT b, std::size_t l)
5796         : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5797 
5798     template<class IteratorType,
5799              typename std::enable_if<
5800                  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5801                  int>::type = 0>
span_input_adapter(IteratorType first,IteratorType last)5802     span_input_adapter(IteratorType first, IteratorType last)
5803         : ia(input_adapter(first, last)) {}
5804 
get()5805     contiguous_bytes_input_adapter&& get()
5806     {
5807         return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5808     }
5809 
5810   private:
5811     contiguous_bytes_input_adapter ia;
5812 };
5813 }  // namespace detail
5814 }  // namespace nlohmann
5815 
5816 // #include <nlohmann/detail/input/json_sax.hpp>
5817 
5818 
5819 #include <cstddef>
5820 #include <string> // string
5821 #include <utility> // move
5822 #include <vector> // vector
5823 
5824 // #include <nlohmann/detail/exceptions.hpp>
5825 
5826 // #include <nlohmann/detail/macro_scope.hpp>
5827 
5828 
5829 namespace nlohmann
5830 {
5831 
5832 /*!
5833 @brief SAX interface
5834 
5835 This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
5836 Each function is called in different situations while the input is parsed. The
5837 boolean return value informs the parser whether to continue processing the
5838 input.
5839 */
5840 template<typename BasicJsonType>
5841 struct json_sax
5842 {
5843     using number_integer_t = typename BasicJsonType::number_integer_t;
5844     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5845     using number_float_t = typename BasicJsonType::number_float_t;
5846     using string_t = typename BasicJsonType::string_t;
5847     using binary_t = typename BasicJsonType::binary_t;
5848 
5849     /*!
5850     @brief a null value was read
5851     @return whether parsing should proceed
5852     */
5853     virtual bool null() = 0;
5854 
5855     /*!
5856     @brief a boolean value was read
5857     @param[in] val  boolean value
5858     @return whether parsing should proceed
5859     */
5860     virtual bool boolean(bool val) = 0;
5861 
5862     /*!
5863     @brief an integer number was read
5864     @param[in] val  integer value
5865     @return whether parsing should proceed
5866     */
5867     virtual bool number_integer(number_integer_t val) = 0;
5868 
5869     /*!
5870     @brief an unsigned integer number was read
5871     @param[in] val  unsigned integer value
5872     @return whether parsing should proceed
5873     */
5874     virtual bool number_unsigned(number_unsigned_t val) = 0;
5875 
5876     /*!
5877     @brief an floating-point number was read
5878     @param[in] val  floating-point value
5879     @param[in] s    raw token value
5880     @return whether parsing should proceed
5881     */
5882     virtual bool number_float(number_float_t val, const string_t& s) = 0;
5883 
5884     /*!
5885     @brief a string was read
5886     @param[in] val  string value
5887     @return whether parsing should proceed
5888     @note It is safe to move the passed string.
5889     */
5890     virtual bool string(string_t& val) = 0;
5891 
5892     /*!
5893     @brief a binary string was read
5894     @param[in] val  binary value
5895     @return whether parsing should proceed
5896     @note It is safe to move the passed binary.
5897     */
5898     virtual bool binary(binary_t& val) = 0;
5899 
5900     /*!
5901     @brief the beginning of an object was read
5902     @param[in] elements  number of object elements or -1 if unknown
5903     @return whether parsing should proceed
5904     @note binary formats may report the number of elements
5905     */
5906     virtual bool start_object(std::size_t elements) = 0;
5907 
5908     /*!
5909     @brief an object key was read
5910     @param[in] val  object key
5911     @return whether parsing should proceed
5912     @note It is safe to move the passed string.
5913     */
5914     virtual bool key(string_t& val) = 0;
5915 
5916     /*!
5917     @brief the end of an object was read
5918     @return whether parsing should proceed
5919     */
5920     virtual bool end_object() = 0;
5921 
5922     /*!
5923     @brief the beginning of an array was read
5924     @param[in] elements  number of array elements or -1 if unknown
5925     @return whether parsing should proceed
5926     @note binary formats may report the number of elements
5927     */
5928     virtual bool start_array(std::size_t elements) = 0;
5929 
5930     /*!
5931     @brief the end of an array was read
5932     @return whether parsing should proceed
5933     */
5934     virtual bool end_array() = 0;
5935 
5936     /*!
5937     @brief a parse error occurred
5938     @param[in] position    the position in the input where the error occurs
5939     @param[in] last_token  the last read token
5940     @param[in] ex          an exception object describing the error
5941     @return whether parsing should proceed (must return false)
5942     */
5943     virtual bool parse_error(std::size_t position,
5944                              const std::string& last_token,
5945                              const detail::exception& ex) = 0;
5946 
5947     json_sax() = default;
5948     json_sax(const json_sax&) = default;
5949     json_sax(json_sax&&) noexcept = default;
5950     json_sax& operator=(const json_sax&) = default;
5951     json_sax& operator=(json_sax&&) noexcept = default;
5952     virtual ~json_sax() = default;
5953 };
5954 
5955 
5956 namespace detail
5957 {
5958 /*!
5959 @brief SAX implementation to create a JSON value from SAX events
5960 
5961 This class implements the @ref json_sax interface and processes the SAX events
5962 to create a JSON value which makes it basically a DOM parser. The structure or
5963 hierarchy of the JSON value is managed by the stack `ref_stack` which contains
5964 a pointer to the respective array or object for each recursion depth.
5965 
5966 After successful parsing, the value that is passed by reference to the
5967 constructor contains the parsed value.
5968 
5969 @tparam BasicJsonType  the JSON type
5970 */
5971 template<typename BasicJsonType>
5972 class json_sax_dom_parser
5973 {
5974   public:
5975     using number_integer_t = typename BasicJsonType::number_integer_t;
5976     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5977     using number_float_t = typename BasicJsonType::number_float_t;
5978     using string_t = typename BasicJsonType::string_t;
5979     using binary_t = typename BasicJsonType::binary_t;
5980 
5981     /*!
5982     @param[in,out] r  reference to a JSON value that is manipulated while
5983                        parsing
5984     @param[in] allow_exceptions_  whether parse errors yield exceptions
5985     */
json_sax_dom_parser(BasicJsonType & r,const bool allow_exceptions_=true)5986     explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5987         : root(r), allow_exceptions(allow_exceptions_)
5988     {}
5989 
5990     // make class move-only
5991     json_sax_dom_parser(const json_sax_dom_parser&) = delete;
5992     json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5993     json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
5994     json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5995     ~json_sax_dom_parser() = default;
5996 
null()5997     bool null()
5998     {
5999         handle_value(nullptr);
6000         return true;
6001     }
6002 
boolean(bool val)6003     bool boolean(bool val)
6004     {
6005         handle_value(val);
6006         return true;
6007     }
6008 
number_integer(number_integer_t val)6009     bool number_integer(number_integer_t val)
6010     {
6011         handle_value(val);
6012         return true;
6013     }
6014 
number_unsigned(number_unsigned_t val)6015     bool number_unsigned(number_unsigned_t val)
6016     {
6017         handle_value(val);
6018         return true;
6019     }
6020 
number_float(number_float_t val,const string_t &)6021     bool number_float(number_float_t val, const string_t& /*unused*/)
6022     {
6023         handle_value(val);
6024         return true;
6025     }
6026 
string(string_t & val)6027     bool string(string_t& val)
6028     {
6029         handle_value(val);
6030         return true;
6031     }
6032 
binary(binary_t & val)6033     bool binary(binary_t& val)
6034     {
6035         handle_value(std::move(val));
6036         return true;
6037     }
6038 
start_object(std::size_t len)6039     bool start_object(std::size_t len)
6040     {
6041         ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6042 
6043         if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6044         {
6045             JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6046         }
6047 
6048         return true;
6049     }
6050 
key(string_t & val)6051     bool key(string_t& val)
6052     {
6053         // add null at given key and store the reference for later
6054         object_element = &(ref_stack.back()->m_value.object->operator[](val));
6055         return true;
6056     }
6057 
end_object()6058     bool end_object()
6059     {
6060         ref_stack.back()->set_parents();
6061         ref_stack.pop_back();
6062         return true;
6063     }
6064 
start_array(std::size_t len)6065     bool start_array(std::size_t len)
6066     {
6067         ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6068 
6069         if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6070         {
6071             JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6072         }
6073 
6074         return true;
6075     }
6076 
end_array()6077     bool end_array()
6078     {
6079         ref_stack.back()->set_parents();
6080         ref_stack.pop_back();
6081         return true;
6082     }
6083 
6084     template<class Exception>
parse_error(std::size_t,const std::string &,const Exception & ex)6085     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6086                      const Exception& ex)
6087     {
6088         errored = true;
6089         static_cast<void>(ex);
6090         if (allow_exceptions)
6091         {
6092             JSON_THROW(ex);
6093         }
6094         return false;
6095     }
6096 
is_errored() const6097     constexpr bool is_errored() const
6098     {
6099         return errored;
6100     }
6101 
6102   private:
6103     /*!
6104     @invariant If the ref stack is empty, then the passed value will be the new
6105                root.
6106     @invariant If the ref stack contains a value, then it is an array or an
6107                object to which we can add elements
6108     */
6109     template<typename Value>
6110     JSON_HEDLEY_RETURNS_NON_NULL
handle_value(Value && v)6111     BasicJsonType* handle_value(Value&& v)
6112     {
6113         if (ref_stack.empty())
6114         {
6115             root = BasicJsonType(std::forward<Value>(v));
6116             return &root;
6117         }
6118 
6119         JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6120 
6121         if (ref_stack.back()->is_array())
6122         {
6123             ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6124             return &(ref_stack.back()->m_value.array->back());
6125         }
6126 
6127         JSON_ASSERT(ref_stack.back()->is_object());
6128         JSON_ASSERT(object_element);
6129         *object_element = BasicJsonType(std::forward<Value>(v));
6130         return object_element;
6131     }
6132 
6133     /// the parsed JSON value
6134     BasicJsonType& root;
6135     /// stack to model hierarchy of values
6136     std::vector<BasicJsonType*> ref_stack {};
6137     /// helper to hold the reference for the next object element
6138     BasicJsonType* object_element = nullptr;
6139     /// whether a syntax error occurred
6140     bool errored = false;
6141     /// whether to throw exceptions in case of errors
6142     const bool allow_exceptions = true;
6143 };
6144 
6145 template<typename BasicJsonType>
6146 class json_sax_dom_callback_parser
6147 {
6148   public:
6149     using number_integer_t = typename BasicJsonType::number_integer_t;
6150     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6151     using number_float_t = typename BasicJsonType::number_float_t;
6152     using string_t = typename BasicJsonType::string_t;
6153     using binary_t = typename BasicJsonType::binary_t;
6154     using parser_callback_t = typename BasicJsonType::parser_callback_t;
6155     using parse_event_t = typename BasicJsonType::parse_event_t;
6156 
json_sax_dom_callback_parser(BasicJsonType & r,const parser_callback_t cb,const bool allow_exceptions_=true)6157     json_sax_dom_callback_parser(BasicJsonType& r,
6158                                  const parser_callback_t cb,
6159                                  const bool allow_exceptions_ = true)
6160         : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6161     {
6162         keep_stack.push_back(true);
6163     }
6164 
6165     // make class move-only
6166     json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
6167     json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6168     json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
6169     json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6170     ~json_sax_dom_callback_parser() = default;
6171 
null()6172     bool null()
6173     {
6174         handle_value(nullptr);
6175         return true;
6176     }
6177 
boolean(bool val)6178     bool boolean(bool val)
6179     {
6180         handle_value(val);
6181         return true;
6182     }
6183 
number_integer(number_integer_t val)6184     bool number_integer(number_integer_t val)
6185     {
6186         handle_value(val);
6187         return true;
6188     }
6189 
number_unsigned(number_unsigned_t val)6190     bool number_unsigned(number_unsigned_t val)
6191     {
6192         handle_value(val);
6193         return true;
6194     }
6195 
number_float(number_float_t val,const string_t &)6196     bool number_float(number_float_t val, const string_t& /*unused*/)
6197     {
6198         handle_value(val);
6199         return true;
6200     }
6201 
string(string_t & val)6202     bool string(string_t& val)
6203     {
6204         handle_value(val);
6205         return true;
6206     }
6207 
binary(binary_t & val)6208     bool binary(binary_t& val)
6209     {
6210         handle_value(std::move(val));
6211         return true;
6212     }
6213 
start_object(std::size_t len)6214     bool start_object(std::size_t len)
6215     {
6216         // check callback for object start
6217         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6218         keep_stack.push_back(keep);
6219 
6220         auto val = handle_value(BasicJsonType::value_t::object, true);
6221         ref_stack.push_back(val.second);
6222 
6223         // check object limit
6224         if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6225         {
6226             JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6227         }
6228 
6229         return true;
6230     }
6231 
key(string_t & val)6232     bool key(string_t& val)
6233     {
6234         BasicJsonType k = BasicJsonType(val);
6235 
6236         // check callback for key
6237         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6238         key_keep_stack.push_back(keep);
6239 
6240         // add discarded value at given key and store the reference for later
6241         if (keep && ref_stack.back())
6242         {
6243             object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6244         }
6245 
6246         return true;
6247     }
6248 
end_object()6249     bool end_object()
6250     {
6251         if (ref_stack.back())
6252         {
6253             if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6254             {
6255                 // discard object
6256                 *ref_stack.back() = discarded;
6257             }
6258             else
6259             {
6260                 ref_stack.back()->set_parents();
6261             }
6262         }
6263 
6264         JSON_ASSERT(!ref_stack.empty());
6265         JSON_ASSERT(!keep_stack.empty());
6266         ref_stack.pop_back();
6267         keep_stack.pop_back();
6268 
6269         if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6270         {
6271             // remove discarded value
6272             for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6273             {
6274                 if (it->is_discarded())
6275                 {
6276                     ref_stack.back()->erase(it);
6277                     break;
6278                 }
6279             }
6280         }
6281 
6282         return true;
6283     }
6284 
start_array(std::size_t len)6285     bool start_array(std::size_t len)
6286     {
6287         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6288         keep_stack.push_back(keep);
6289 
6290         auto val = handle_value(BasicJsonType::value_t::array, true);
6291         ref_stack.push_back(val.second);
6292 
6293         // check array limit
6294         if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6295         {
6296             JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6297         }
6298 
6299         return true;
6300     }
6301 
end_array()6302     bool end_array()
6303     {
6304         bool keep = true;
6305 
6306         if (ref_stack.back())
6307         {
6308             keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6309             if (keep)
6310             {
6311                 ref_stack.back()->set_parents();
6312             }
6313             else
6314             {
6315                 // discard array
6316                 *ref_stack.back() = discarded;
6317             }
6318         }
6319 
6320         JSON_ASSERT(!ref_stack.empty());
6321         JSON_ASSERT(!keep_stack.empty());
6322         ref_stack.pop_back();
6323         keep_stack.pop_back();
6324 
6325         // remove discarded value
6326         if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6327         {
6328             ref_stack.back()->m_value.array->pop_back();
6329         }
6330 
6331         return true;
6332     }
6333 
6334     template<class Exception>
parse_error(std::size_t,const std::string &,const Exception & ex)6335     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6336                      const Exception& ex)
6337     {
6338         errored = true;
6339         static_cast<void>(ex);
6340         if (allow_exceptions)
6341         {
6342             JSON_THROW(ex);
6343         }
6344         return false;
6345     }
6346 
is_errored() const6347     constexpr bool is_errored() const
6348     {
6349         return errored;
6350     }
6351 
6352   private:
6353     /*!
6354     @param[in] v  value to add to the JSON value we build during parsing
6355     @param[in] skip_callback  whether we should skip calling the callback
6356                function; this is required after start_array() and
6357                start_object() SAX events, because otherwise we would call the
6358                callback function with an empty array or object, respectively.
6359 
6360     @invariant If the ref stack is empty, then the passed value will be the new
6361                root.
6362     @invariant If the ref stack contains a value, then it is an array or an
6363                object to which we can add elements
6364 
6365     @return pair of boolean (whether value should be kept) and pointer (to the
6366             passed value in the ref_stack hierarchy; nullptr if not kept)
6367     */
6368     template<typename Value>
handle_value(Value && v,const bool skip_callback=false)6369     std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6370     {
6371         JSON_ASSERT(!keep_stack.empty());
6372 
6373         // do not handle this value if we know it would be added to a discarded
6374         // container
6375         if (!keep_stack.back())
6376         {
6377             return {false, nullptr};
6378         }
6379 
6380         // create value
6381         auto value = BasicJsonType(std::forward<Value>(v));
6382 
6383         // check callback
6384         const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6385 
6386         // do not handle this value if we just learnt it shall be discarded
6387         if (!keep)
6388         {
6389             return {false, nullptr};
6390         }
6391 
6392         if (ref_stack.empty())
6393         {
6394             root = std::move(value);
6395             return {true, &root};
6396         }
6397 
6398         // skip this value if we already decided to skip the parent
6399         // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6400         if (!ref_stack.back())
6401         {
6402             return {false, nullptr};
6403         }
6404 
6405         // we now only expect arrays and objects
6406         JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6407 
6408         // array
6409         if (ref_stack.back()->is_array())
6410         {
6411             ref_stack.back()->m_value.array->emplace_back(std::move(value));
6412             return {true, &(ref_stack.back()->m_value.array->back())};
6413         }
6414 
6415         // object
6416         JSON_ASSERT(ref_stack.back()->is_object());
6417         // check if we should store an element for the current key
6418         JSON_ASSERT(!key_keep_stack.empty());
6419         const bool store_element = key_keep_stack.back();
6420         key_keep_stack.pop_back();
6421 
6422         if (!store_element)
6423         {
6424             return {false, nullptr};
6425         }
6426 
6427         JSON_ASSERT(object_element);
6428         *object_element = std::move(value);
6429         return {true, object_element};
6430     }
6431 
6432     /// the parsed JSON value
6433     BasicJsonType& root;
6434     /// stack to model hierarchy of values
6435     std::vector<BasicJsonType*> ref_stack {};
6436     /// stack to manage which values to keep
6437     std::vector<bool> keep_stack {};
6438     /// stack to manage which object keys to keep
6439     std::vector<bool> key_keep_stack {};
6440     /// helper to hold the reference for the next object element
6441     BasicJsonType* object_element = nullptr;
6442     /// whether a syntax error occurred
6443     bool errored = false;
6444     /// callback function
6445     const parser_callback_t callback = nullptr;
6446     /// whether to throw exceptions in case of errors
6447     const bool allow_exceptions = true;
6448     /// a discarded value for the callback
6449     BasicJsonType discarded = BasicJsonType::value_t::discarded;
6450 };
6451 
6452 template<typename BasicJsonType>
6453 class json_sax_acceptor
6454 {
6455   public:
6456     using number_integer_t = typename BasicJsonType::number_integer_t;
6457     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6458     using number_float_t = typename BasicJsonType::number_float_t;
6459     using string_t = typename BasicJsonType::string_t;
6460     using binary_t = typename BasicJsonType::binary_t;
6461 
null()6462     bool null()
6463     {
6464         return true;
6465     }
6466 
boolean(bool)6467     bool boolean(bool /*unused*/)
6468     {
6469         return true;
6470     }
6471 
number_integer(number_integer_t)6472     bool number_integer(number_integer_t /*unused*/)
6473     {
6474         return true;
6475     }
6476 
number_unsigned(number_unsigned_t)6477     bool number_unsigned(number_unsigned_t /*unused*/)
6478     {
6479         return true;
6480     }
6481 
number_float(number_float_t,const string_t &)6482     bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6483     {
6484         return true;
6485     }
6486 
string(string_t &)6487     bool string(string_t& /*unused*/)
6488     {
6489         return true;
6490     }
6491 
binary(binary_t &)6492     bool binary(binary_t& /*unused*/)
6493     {
6494         return true;
6495     }
6496 
start_object(std::size_t=std::size_t (-1))6497     bool start_object(std::size_t /*unused*/ = std::size_t(-1))
6498     {
6499         return true;
6500     }
6501 
key(string_t &)6502     bool key(string_t& /*unused*/)
6503     {
6504         return true;
6505     }
6506 
end_object()6507     bool end_object()
6508     {
6509         return true;
6510     }
6511 
start_array(std::size_t=std::size_t (-1))6512     bool start_array(std::size_t /*unused*/ = std::size_t(-1))
6513     {
6514         return true;
6515     }
6516 
end_array()6517     bool end_array()
6518     {
6519         return true;
6520     }
6521 
parse_error(std::size_t,const std::string &,const detail::exception &)6522     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6523     {
6524         return false;
6525     }
6526 };
6527 }  // namespace detail
6528 
6529 }  // namespace nlohmann
6530 
6531 // #include <nlohmann/detail/input/lexer.hpp>
6532 
6533 
6534 #include <array> // array
6535 #include <clocale> // localeconv
6536 #include <cstddef> // size_t
6537 #include <cstdio> // snprintf
6538 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6539 #include <initializer_list> // initializer_list
6540 #include <string> // char_traits, string
6541 #include <utility> // move
6542 #include <vector> // vector
6543 
6544 // #include <nlohmann/detail/input/input_adapters.hpp>
6545 
6546 // #include <nlohmann/detail/input/position_t.hpp>
6547 
6548 // #include <nlohmann/detail/macro_scope.hpp>
6549 
6550 
6551 namespace nlohmann
6552 {
6553 namespace detail
6554 {
6555 ///////////
6556 // lexer //
6557 ///////////
6558 
6559 template<typename BasicJsonType>
6560 class lexer_base
6561 {
6562   public:
6563     /// token types for the parser
6564     enum class token_type
6565     {
6566         uninitialized,    ///< indicating the scanner is uninitialized
6567         literal_true,     ///< the `true` literal
6568         literal_false,    ///< the `false` literal
6569         literal_null,     ///< the `null` literal
6570         value_string,     ///< a string -- use get_string() for actual value
6571         value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value
6572         value_integer,    ///< a signed integer -- use get_number_integer() for actual value
6573         value_float,      ///< an floating point number -- use get_number_float() for actual value
6574         begin_array,      ///< the character for array begin `[`
6575         begin_object,     ///< the character for object begin `{`
6576         end_array,        ///< the character for array end `]`
6577         end_object,       ///< the character for object end `}`
6578         name_separator,   ///< the name separator `:`
6579         value_separator,  ///< the value separator `,`
6580         parse_error,      ///< indicating a parse error
6581         end_of_input,     ///< indicating the end of the input buffer
6582         literal_or_value  ///< a literal or the begin of a value (only for diagnostics)
6583     };
6584 
6585     /// return name of values of type token_type (only used for errors)
6586     JSON_HEDLEY_RETURNS_NON_NULL
6587     JSON_HEDLEY_CONST
token_type_name(const token_type t)6588     static const char* token_type_name(const token_type t) noexcept
6589     {
6590         switch (t)
6591         {
6592             case token_type::uninitialized:
6593                 return "<uninitialized>";
6594             case token_type::literal_true:
6595                 return "true literal";
6596             case token_type::literal_false:
6597                 return "false literal";
6598             case token_type::literal_null:
6599                 return "null literal";
6600             case token_type::value_string:
6601                 return "string literal";
6602             case token_type::value_unsigned:
6603             case token_type::value_integer:
6604             case token_type::value_float:
6605                 return "number literal";
6606             case token_type::begin_array:
6607                 return "'['";
6608             case token_type::begin_object:
6609                 return "'{'";
6610             case token_type::end_array:
6611                 return "']'";
6612             case token_type::end_object:
6613                 return "'}'";
6614             case token_type::name_separator:
6615                 return "':'";
6616             case token_type::value_separator:
6617                 return "','";
6618             case token_type::parse_error:
6619                 return "<parse error>";
6620             case token_type::end_of_input:
6621                 return "end of input";
6622             case token_type::literal_or_value:
6623                 return "'[', '{', or a literal";
6624             // LCOV_EXCL_START
6625             default: // catch non-enum values
6626                 return "unknown token";
6627                 // LCOV_EXCL_STOP
6628         }
6629     }
6630 };
6631 /*!
6632 @brief lexical analysis
6633 
6634 This class organizes the lexical analysis during JSON deserialization.
6635 */
6636 template<typename BasicJsonType, typename InputAdapterType>
6637 class lexer : public lexer_base<BasicJsonType>
6638 {
6639     using number_integer_t = typename BasicJsonType::number_integer_t;
6640     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6641     using number_float_t = typename BasicJsonType::number_float_t;
6642     using string_t = typename BasicJsonType::string_t;
6643     using char_type = typename InputAdapterType::char_type;
6644     using char_int_type = typename std::char_traits<char_type>::int_type;
6645 
6646   public:
6647     using token_type = typename lexer_base<BasicJsonType>::token_type;
6648 
lexer(InputAdapterType && adapter,bool ignore_comments_=false)6649     explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6650         : ia(std::move(adapter))
6651         , ignore_comments(ignore_comments_)
6652         , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6653     {}
6654 
6655     // delete because of pointer members
6656     lexer(const lexer&) = delete;
6657     lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6658     lexer& operator=(lexer&) = delete;
6659     lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6660     ~lexer() = default;
6661 
6662   private:
6663     /////////////////////
6664     // locales
6665     /////////////////////
6666 
6667     /// return the locale-dependent decimal point
6668     JSON_HEDLEY_PURE
get_decimal_point()6669     static char get_decimal_point() noexcept
6670     {
6671         const auto* loc = localeconv();
6672         JSON_ASSERT(loc != nullptr);
6673         return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6674     }
6675 
6676     /////////////////////
6677     // scan functions
6678     /////////////////////
6679 
6680     /*!
6681     @brief get codepoint from 4 hex characters following `\u`
6682 
6683     For input "\u c1 c2 c3 c4" the codepoint is:
6684       (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
6685     = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
6686 
6687     Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
6688     must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
6689     conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
6690     between the ASCII value of the character and the desired integer value.
6691 
6692     @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
6693             non-hex character)
6694     */
get_codepoint()6695     int get_codepoint()
6696     {
6697         // this function only makes sense after reading `\u`
6698         JSON_ASSERT(current == 'u');
6699         int codepoint = 0;
6700 
6701         const auto factors = { 12u, 8u, 4u, 0u };
6702         for (const auto factor : factors)
6703         {
6704             get();
6705 
6706             if (current >= '0' && current <= '9')
6707             {
6708                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6709             }
6710             else if (current >= 'A' && current <= 'F')
6711             {
6712                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6713             }
6714             else if (current >= 'a' && current <= 'f')
6715             {
6716                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6717             }
6718             else
6719             {
6720                 return -1;
6721             }
6722         }
6723 
6724         JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6725         return codepoint;
6726     }
6727 
6728     /*!
6729     @brief check if the next byte(s) are inside a given range
6730 
6731     Adds the current byte and, for each passed range, reads a new byte and
6732     checks if it is inside the range. If a violation was detected, set up an
6733     error message and return false. Otherwise, return true.
6734 
6735     @param[in] ranges  list of integers; interpreted as list of pairs of
6736                        inclusive lower and upper bound, respectively
6737 
6738     @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
6739          1, 2, or 3 pairs. This precondition is enforced by an assertion.
6740 
6741     @return true if and only if no range violation was detected
6742     */
next_byte_in_range(std::initializer_list<char_int_type> ranges)6743     bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6744     {
6745         JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6746         add(current);
6747 
6748         for (auto range = ranges.begin(); range != ranges.end(); ++range)
6749         {
6750             get();
6751             if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6752             {
6753                 add(current);
6754             }
6755             else
6756             {
6757                 error_message = "invalid string: ill-formed UTF-8 byte";
6758                 return false;
6759             }
6760         }
6761 
6762         return true;
6763     }
6764 
6765     /*!
6766     @brief scan a string literal
6767 
6768     This function scans a string according to Sect. 7 of RFC 8259. While
6769     scanning, bytes are escaped and copied into buffer token_buffer. Then the
6770     function returns successfully, token_buffer is *not* null-terminated (as it
6771     may contain \0 bytes), and token_buffer.size() is the number of bytes in the
6772     string.
6773 
6774     @return token_type::value_string if string could be successfully scanned,
6775             token_type::parse_error otherwise
6776 
6777     @note In case of errors, variable error_message contains a textual
6778           description.
6779     */
scan_string()6780     token_type scan_string()
6781     {
6782         // reset token_buffer (ignore opening quote)
6783         reset();
6784 
6785         // we entered the function by reading an open quote
6786         JSON_ASSERT(current == '\"');
6787 
6788         while (true)
6789         {
6790             // get next character
6791             switch (get())
6792             {
6793                 // end of file while parsing string
6794                 case std::char_traits<char_type>::eof():
6795                 {
6796                     error_message = "invalid string: missing closing quote";
6797                     return token_type::parse_error;
6798                 }
6799 
6800                 // closing quote
6801                 case '\"':
6802                 {
6803                     return token_type::value_string;
6804                 }
6805 
6806                 // escapes
6807                 case '\\':
6808                 {
6809                     switch (get())
6810                     {
6811                         // quotation mark
6812                         case '\"':
6813                             add('\"');
6814                             break;
6815                         // reverse solidus
6816                         case '\\':
6817                             add('\\');
6818                             break;
6819                         // solidus
6820                         case '/':
6821                             add('/');
6822                             break;
6823                         // backspace
6824                         case 'b':
6825                             add('\b');
6826                             break;
6827                         // form feed
6828                         case 'f':
6829                             add('\f');
6830                             break;
6831                         // line feed
6832                         case 'n':
6833                             add('\n');
6834                             break;
6835                         // carriage return
6836                         case 'r':
6837                             add('\r');
6838                             break;
6839                         // tab
6840                         case 't':
6841                             add('\t');
6842                             break;
6843 
6844                         // unicode escapes
6845                         case 'u':
6846                         {
6847                             const int codepoint1 = get_codepoint();
6848                             int codepoint = codepoint1; // start with codepoint1
6849 
6850                             if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6851                             {
6852                                 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6853                                 return token_type::parse_error;
6854                             }
6855 
6856                             // check if code point is a high surrogate
6857                             if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6858                             {
6859                                 // expect next \uxxxx entry
6860                                 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6861                                 {
6862                                     const int codepoint2 = get_codepoint();
6863 
6864                                     if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6865                                     {
6866                                         error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6867                                         return token_type::parse_error;
6868                                     }
6869 
6870                                     // check if codepoint2 is a low surrogate
6871                                     if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6872                                     {
6873                                         // overwrite codepoint
6874                                         codepoint = static_cast<int>(
6875                                                         // high surrogate occupies the most significant 22 bits
6876                                                         (static_cast<unsigned int>(codepoint1) << 10u)
6877                                                         // low surrogate occupies the least significant 15 bits
6878                                                         + static_cast<unsigned int>(codepoint2)
6879                                                         // there is still the 0xD800, 0xDC00 and 0x10000 noise
6880                                                         // in the result so we have to subtract with:
6881                                                         // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6882                                                         - 0x35FDC00u);
6883                                     }
6884                                     else
6885                                     {
6886                                         error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6887                                         return token_type::parse_error;
6888                                     }
6889                                 }
6890                                 else
6891                                 {
6892                                     error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6893                                     return token_type::parse_error;
6894                                 }
6895                             }
6896                             else
6897                             {
6898                                 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6899                                 {
6900                                     error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6901                                     return token_type::parse_error;
6902                                 }
6903                             }
6904 
6905                             // result of the above calculation yields a proper codepoint
6906                             JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6907 
6908                             // translate codepoint into bytes
6909                             if (codepoint < 0x80)
6910                             {
6911                                 // 1-byte characters: 0xxxxxxx (ASCII)
6912                                 add(static_cast<char_int_type>(codepoint));
6913                             }
6914                             else if (codepoint <= 0x7FF)
6915                             {
6916                                 // 2-byte characters: 110xxxxx 10xxxxxx
6917                                 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6918                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6919                             }
6920                             else if (codepoint <= 0xFFFF)
6921                             {
6922                                 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6923                                 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6924                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6925                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6926                             }
6927                             else
6928                             {
6929                                 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6930                                 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6931                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
6932                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6933                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6934                             }
6935 
6936                             break;
6937                         }
6938 
6939                         // other characters after escape
6940                         default:
6941                             error_message = "invalid string: forbidden character after backslash";
6942                             return token_type::parse_error;
6943                     }
6944 
6945                     break;
6946                 }
6947 
6948                 // invalid control characters
6949                 case 0x00:
6950                 {
6951                     error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6952                     return token_type::parse_error;
6953                 }
6954 
6955                 case 0x01:
6956                 {
6957                     error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6958                     return token_type::parse_error;
6959                 }
6960 
6961                 case 0x02:
6962                 {
6963                     error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6964                     return token_type::parse_error;
6965                 }
6966 
6967                 case 0x03:
6968                 {
6969                     error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6970                     return token_type::parse_error;
6971                 }
6972 
6973                 case 0x04:
6974                 {
6975                     error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6976                     return token_type::parse_error;
6977                 }
6978 
6979                 case 0x05:
6980                 {
6981                     error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6982                     return token_type::parse_error;
6983                 }
6984 
6985                 case 0x06:
6986                 {
6987                     error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6988                     return token_type::parse_error;
6989                 }
6990 
6991                 case 0x07:
6992                 {
6993                     error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6994                     return token_type::parse_error;
6995                 }
6996 
6997                 case 0x08:
6998                 {
6999                     error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7000                     return token_type::parse_error;
7001                 }
7002 
7003                 case 0x09:
7004                 {
7005                     error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7006                     return token_type::parse_error;
7007                 }
7008 
7009                 case 0x0A:
7010                 {
7011                     error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7012                     return token_type::parse_error;
7013                 }
7014 
7015                 case 0x0B:
7016                 {
7017                     error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7018                     return token_type::parse_error;
7019                 }
7020 
7021                 case 0x0C:
7022                 {
7023                     error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7024                     return token_type::parse_error;
7025                 }
7026 
7027                 case 0x0D:
7028                 {
7029                     error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7030                     return token_type::parse_error;
7031                 }
7032 
7033                 case 0x0E:
7034                 {
7035                     error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7036                     return token_type::parse_error;
7037                 }
7038 
7039                 case 0x0F:
7040                 {
7041                     error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7042                     return token_type::parse_error;
7043                 }
7044 
7045                 case 0x10:
7046                 {
7047                     error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7048                     return token_type::parse_error;
7049                 }
7050 
7051                 case 0x11:
7052                 {
7053                     error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7054                     return token_type::parse_error;
7055                 }
7056 
7057                 case 0x12:
7058                 {
7059                     error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7060                     return token_type::parse_error;
7061                 }
7062 
7063                 case 0x13:
7064                 {
7065                     error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7066                     return token_type::parse_error;
7067                 }
7068 
7069                 case 0x14:
7070                 {
7071                     error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7072                     return token_type::parse_error;
7073                 }
7074 
7075                 case 0x15:
7076                 {
7077                     error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7078                     return token_type::parse_error;
7079                 }
7080 
7081                 case 0x16:
7082                 {
7083                     error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7084                     return token_type::parse_error;
7085                 }
7086 
7087                 case 0x17:
7088                 {
7089                     error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7090                     return token_type::parse_error;
7091                 }
7092 
7093                 case 0x18:
7094                 {
7095                     error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7096                     return token_type::parse_error;
7097                 }
7098 
7099                 case 0x19:
7100                 {
7101                     error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7102                     return token_type::parse_error;
7103                 }
7104 
7105                 case 0x1A:
7106                 {
7107                     error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7108                     return token_type::parse_error;
7109                 }
7110 
7111                 case 0x1B:
7112                 {
7113                     error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7114                     return token_type::parse_error;
7115                 }
7116 
7117                 case 0x1C:
7118                 {
7119                     error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7120                     return token_type::parse_error;
7121                 }
7122 
7123                 case 0x1D:
7124                 {
7125                     error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7126                     return token_type::parse_error;
7127                 }
7128 
7129                 case 0x1E:
7130                 {
7131                     error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7132                     return token_type::parse_error;
7133                 }
7134 
7135                 case 0x1F:
7136                 {
7137                     error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7138                     return token_type::parse_error;
7139                 }
7140 
7141                 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7142                 case 0x20:
7143                 case 0x21:
7144                 case 0x23:
7145                 case 0x24:
7146                 case 0x25:
7147                 case 0x26:
7148                 case 0x27:
7149                 case 0x28:
7150                 case 0x29:
7151                 case 0x2A:
7152                 case 0x2B:
7153                 case 0x2C:
7154                 case 0x2D:
7155                 case 0x2E:
7156                 case 0x2F:
7157                 case 0x30:
7158                 case 0x31:
7159                 case 0x32:
7160                 case 0x33:
7161                 case 0x34:
7162                 case 0x35:
7163                 case 0x36:
7164                 case 0x37:
7165                 case 0x38:
7166                 case 0x39:
7167                 case 0x3A:
7168                 case 0x3B:
7169                 case 0x3C:
7170                 case 0x3D:
7171                 case 0x3E:
7172                 case 0x3F:
7173                 case 0x40:
7174                 case 0x41:
7175                 case 0x42:
7176                 case 0x43:
7177                 case 0x44:
7178                 case 0x45:
7179                 case 0x46:
7180                 case 0x47:
7181                 case 0x48:
7182                 case 0x49:
7183                 case 0x4A:
7184                 case 0x4B:
7185                 case 0x4C:
7186                 case 0x4D:
7187                 case 0x4E:
7188                 case 0x4F:
7189                 case 0x50:
7190                 case 0x51:
7191                 case 0x52:
7192                 case 0x53:
7193                 case 0x54:
7194                 case 0x55:
7195                 case 0x56:
7196                 case 0x57:
7197                 case 0x58:
7198                 case 0x59:
7199                 case 0x5A:
7200                 case 0x5B:
7201                 case 0x5D:
7202                 case 0x5E:
7203                 case 0x5F:
7204                 case 0x60:
7205                 case 0x61:
7206                 case 0x62:
7207                 case 0x63:
7208                 case 0x64:
7209                 case 0x65:
7210                 case 0x66:
7211                 case 0x67:
7212                 case 0x68:
7213                 case 0x69:
7214                 case 0x6A:
7215                 case 0x6B:
7216                 case 0x6C:
7217                 case 0x6D:
7218                 case 0x6E:
7219                 case 0x6F:
7220                 case 0x70:
7221                 case 0x71:
7222                 case 0x72:
7223                 case 0x73:
7224                 case 0x74:
7225                 case 0x75:
7226                 case 0x76:
7227                 case 0x77:
7228                 case 0x78:
7229                 case 0x79:
7230                 case 0x7A:
7231                 case 0x7B:
7232                 case 0x7C:
7233                 case 0x7D:
7234                 case 0x7E:
7235                 case 0x7F:
7236                 {
7237                     add(current);
7238                     break;
7239                 }
7240 
7241                 // U+0080..U+07FF: bytes C2..DF 80..BF
7242                 case 0xC2:
7243                 case 0xC3:
7244                 case 0xC4:
7245                 case 0xC5:
7246                 case 0xC6:
7247                 case 0xC7:
7248                 case 0xC8:
7249                 case 0xC9:
7250                 case 0xCA:
7251                 case 0xCB:
7252                 case 0xCC:
7253                 case 0xCD:
7254                 case 0xCE:
7255                 case 0xCF:
7256                 case 0xD0:
7257                 case 0xD1:
7258                 case 0xD2:
7259                 case 0xD3:
7260                 case 0xD4:
7261                 case 0xD5:
7262                 case 0xD6:
7263                 case 0xD7:
7264                 case 0xD8:
7265                 case 0xD9:
7266                 case 0xDA:
7267                 case 0xDB:
7268                 case 0xDC:
7269                 case 0xDD:
7270                 case 0xDE:
7271                 case 0xDF:
7272                 {
7273                     if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7274                     {
7275                         return token_type::parse_error;
7276                     }
7277                     break;
7278                 }
7279 
7280                 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7281                 case 0xE0:
7282                 {
7283                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7284                     {
7285                         return token_type::parse_error;
7286                     }
7287                     break;
7288                 }
7289 
7290                 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7291                 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7292                 case 0xE1:
7293                 case 0xE2:
7294                 case 0xE3:
7295                 case 0xE4:
7296                 case 0xE5:
7297                 case 0xE6:
7298                 case 0xE7:
7299                 case 0xE8:
7300                 case 0xE9:
7301                 case 0xEA:
7302                 case 0xEB:
7303                 case 0xEC:
7304                 case 0xEE:
7305                 case 0xEF:
7306                 {
7307                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7308                     {
7309                         return token_type::parse_error;
7310                     }
7311                     break;
7312                 }
7313 
7314                 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7315                 case 0xED:
7316                 {
7317                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7318                     {
7319                         return token_type::parse_error;
7320                     }
7321                     break;
7322                 }
7323 
7324                 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7325                 case 0xF0:
7326                 {
7327                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7328                     {
7329                         return token_type::parse_error;
7330                     }
7331                     break;
7332                 }
7333 
7334                 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7335                 case 0xF1:
7336                 case 0xF2:
7337                 case 0xF3:
7338                 {
7339                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7340                     {
7341                         return token_type::parse_error;
7342                     }
7343                     break;
7344                 }
7345 
7346                 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7347                 case 0xF4:
7348                 {
7349                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7350                     {
7351                         return token_type::parse_error;
7352                     }
7353                     break;
7354                 }
7355 
7356                 // remaining bytes (80..C1 and F5..FF) are ill-formed
7357                 default:
7358                 {
7359                     error_message = "invalid string: ill-formed UTF-8 byte";
7360                     return token_type::parse_error;
7361                 }
7362             }
7363         }
7364     }
7365 
7366     /*!
7367      * @brief scan a comment
7368      * @return whether comment could be scanned successfully
7369      */
scan_comment()7370     bool scan_comment()
7371     {
7372         switch (get())
7373         {
7374             // single-line comments skip input until a newline or EOF is read
7375             case '/':
7376             {
7377                 while (true)
7378                 {
7379                     switch (get())
7380                     {
7381                         case '\n':
7382                         case '\r':
7383                         case std::char_traits<char_type>::eof():
7384                         case '\0':
7385                             return true;
7386 
7387                         default:
7388                             break;
7389                     }
7390                 }
7391             }
7392 
7393             // multi-line comments skip input until */ is read
7394             case '*':
7395             {
7396                 while (true)
7397                 {
7398                     switch (get())
7399                     {
7400                         case std::char_traits<char_type>::eof():
7401                         case '\0':
7402                         {
7403                             error_message = "invalid comment; missing closing '*/'";
7404                             return false;
7405                         }
7406 
7407                         case '*':
7408                         {
7409                             switch (get())
7410                             {
7411                                 case '/':
7412                                     return true;
7413 
7414                                 default:
7415                                 {
7416                                     unget();
7417                                     continue;
7418                                 }
7419                             }
7420                         }
7421 
7422                         default:
7423                             continue;
7424                     }
7425                 }
7426             }
7427 
7428             // unexpected character after reading '/'
7429             default:
7430             {
7431                 error_message = "invalid comment; expecting '/' or '*' after '/'";
7432                 return false;
7433             }
7434         }
7435     }
7436 
7437     JSON_HEDLEY_NON_NULL(2)
strtof(float & f,const char * str,char ** endptr)7438     static void strtof(float& f, const char* str, char** endptr) noexcept
7439     {
7440         f = std::strtof(str, endptr);
7441     }
7442 
7443     JSON_HEDLEY_NON_NULL(2)
strtof(double & f,const char * str,char ** endptr)7444     static void strtof(double& f, const char* str, char** endptr) noexcept
7445     {
7446         f = std::strtod(str, endptr);
7447     }
7448 
7449     JSON_HEDLEY_NON_NULL(2)
strtof(long double & f,const char * str,char ** endptr)7450     static void strtof(long double& f, const char* str, char** endptr) noexcept
7451     {
7452         f = std::strtold(str, endptr);
7453     }
7454 
7455     /*!
7456     @brief scan a number literal
7457 
7458     This function scans a string according to Sect. 6 of RFC 8259.
7459 
7460     The function is realized with a deterministic finite state machine derived
7461     from the grammar described in RFC 8259. Starting in state "init", the
7462     input is read and used to determined the next state. Only state "done"
7463     accepts the number. State "error" is a trap state to model errors. In the
7464     table below, "anything" means any character but the ones listed before.
7465 
7466     state    | 0        | 1-9      | e E      | +       | -       | .        | anything
7467     ---------|----------|----------|----------|---------|---------|----------|-----------
7468     init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]
7469     minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]
7470     zero     | done     | done     | exponent | done    | done    | decimal1 | done
7471     any1     | any1     | any1     | exponent | done    | done    | decimal1 | done
7472     decimal1 | decimal2 | decimal2 | [error]  | [error] | [error] | [error]  | [error]
7473     decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done
7474     exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]
7475     sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]
7476     any2     | any2     | any2     | done     | done    | done    | done     | done
7477 
7478     The state machine is realized with one label per state (prefixed with
7479     "scan_number_") and `goto` statements between them. The state machine
7480     contains cycles, but any cycle can be left when EOF is read. Therefore,
7481     the function is guaranteed to terminate.
7482 
7483     During scanning, the read bytes are stored in token_buffer. This string is
7484     then converted to a signed integer, an unsigned integer, or a
7485     floating-point number.
7486 
7487     @return token_type::value_unsigned, token_type::value_integer, or
7488             token_type::value_float if number could be successfully scanned,
7489             token_type::parse_error otherwise
7490 
7491     @note The scanner is independent of the current locale. Internally, the
7492           locale's decimal point is used instead of `.` to work with the
7493           locale-dependent converters.
7494     */
scan_number()7495     token_type scan_number()  // lgtm [cpp/use-of-goto]
7496     {
7497         // reset token_buffer to store the number's bytes
7498         reset();
7499 
7500         // the type of the parsed number; initially set to unsigned; will be
7501         // changed if minus sign, decimal point or exponent is read
7502         token_type number_type = token_type::value_unsigned;
7503 
7504         // state (init): we just found out we need to scan a number
7505         switch (current)
7506         {
7507             case '-':
7508             {
7509                 add(current);
7510                 goto scan_number_minus;
7511             }
7512 
7513             case '0':
7514             {
7515                 add(current);
7516                 goto scan_number_zero;
7517             }
7518 
7519             case '1':
7520             case '2':
7521             case '3':
7522             case '4':
7523             case '5':
7524             case '6':
7525             case '7':
7526             case '8':
7527             case '9':
7528             {
7529                 add(current);
7530                 goto scan_number_any1;
7531             }
7532 
7533             // all other characters are rejected outside scan_number()
7534             default:            // LCOV_EXCL_LINE
7535                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7536         }
7537 
7538 scan_number_minus:
7539         // state: we just parsed a leading minus sign
7540         number_type = token_type::value_integer;
7541         switch (get())
7542         {
7543             case '0':
7544             {
7545                 add(current);
7546                 goto scan_number_zero;
7547             }
7548 
7549             case '1':
7550             case '2':
7551             case '3':
7552             case '4':
7553             case '5':
7554             case '6':
7555             case '7':
7556             case '8':
7557             case '9':
7558             {
7559                 add(current);
7560                 goto scan_number_any1;
7561             }
7562 
7563             default:
7564             {
7565                 error_message = "invalid number; expected digit after '-'";
7566                 return token_type::parse_error;
7567             }
7568         }
7569 
7570 scan_number_zero:
7571         // state: we just parse a zero (maybe with a leading minus sign)
7572         switch (get())
7573         {
7574             case '.':
7575             {
7576                 add(decimal_point_char);
7577                 goto scan_number_decimal1;
7578             }
7579 
7580             case 'e':
7581             case 'E':
7582             {
7583                 add(current);
7584                 goto scan_number_exponent;
7585             }
7586 
7587             default:
7588                 goto scan_number_done;
7589         }
7590 
7591 scan_number_any1:
7592         // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7593         switch (get())
7594         {
7595             case '0':
7596             case '1':
7597             case '2':
7598             case '3':
7599             case '4':
7600             case '5':
7601             case '6':
7602             case '7':
7603             case '8':
7604             case '9':
7605             {
7606                 add(current);
7607                 goto scan_number_any1;
7608             }
7609 
7610             case '.':
7611             {
7612                 add(decimal_point_char);
7613                 goto scan_number_decimal1;
7614             }
7615 
7616             case 'e':
7617             case 'E':
7618             {
7619                 add(current);
7620                 goto scan_number_exponent;
7621             }
7622 
7623             default:
7624                 goto scan_number_done;
7625         }
7626 
7627 scan_number_decimal1:
7628         // state: we just parsed a decimal point
7629         number_type = token_type::value_float;
7630         switch (get())
7631         {
7632             case '0':
7633             case '1':
7634             case '2':
7635             case '3':
7636             case '4':
7637             case '5':
7638             case '6':
7639             case '7':
7640             case '8':
7641             case '9':
7642             {
7643                 add(current);
7644                 goto scan_number_decimal2;
7645             }
7646 
7647             default:
7648             {
7649                 error_message = "invalid number; expected digit after '.'";
7650                 return token_type::parse_error;
7651             }
7652         }
7653 
7654 scan_number_decimal2:
7655         // we just parsed at least one number after a decimal point
7656         switch (get())
7657         {
7658             case '0':
7659             case '1':
7660             case '2':
7661             case '3':
7662             case '4':
7663             case '5':
7664             case '6':
7665             case '7':
7666             case '8':
7667             case '9':
7668             {
7669                 add(current);
7670                 goto scan_number_decimal2;
7671             }
7672 
7673             case 'e':
7674             case 'E':
7675             {
7676                 add(current);
7677                 goto scan_number_exponent;
7678             }
7679 
7680             default:
7681                 goto scan_number_done;
7682         }
7683 
7684 scan_number_exponent:
7685         // we just parsed an exponent
7686         number_type = token_type::value_float;
7687         switch (get())
7688         {
7689             case '+':
7690             case '-':
7691             {
7692                 add(current);
7693                 goto scan_number_sign;
7694             }
7695 
7696             case '0':
7697             case '1':
7698             case '2':
7699             case '3':
7700             case '4':
7701             case '5':
7702             case '6':
7703             case '7':
7704             case '8':
7705             case '9':
7706             {
7707                 add(current);
7708                 goto scan_number_any2;
7709             }
7710 
7711             default:
7712             {
7713                 error_message =
7714                     "invalid number; expected '+', '-', or digit after exponent";
7715                 return token_type::parse_error;
7716             }
7717         }
7718 
7719 scan_number_sign:
7720         // we just parsed an exponent sign
7721         switch (get())
7722         {
7723             case '0':
7724             case '1':
7725             case '2':
7726             case '3':
7727             case '4':
7728             case '5':
7729             case '6':
7730             case '7':
7731             case '8':
7732             case '9':
7733             {
7734                 add(current);
7735                 goto scan_number_any2;
7736             }
7737 
7738             default:
7739             {
7740                 error_message = "invalid number; expected digit after exponent sign";
7741                 return token_type::parse_error;
7742             }
7743         }
7744 
7745 scan_number_any2:
7746         // we just parsed a number after the exponent or exponent sign
7747         switch (get())
7748         {
7749             case '0':
7750             case '1':
7751             case '2':
7752             case '3':
7753             case '4':
7754             case '5':
7755             case '6':
7756             case '7':
7757             case '8':
7758             case '9':
7759             {
7760                 add(current);
7761                 goto scan_number_any2;
7762             }
7763 
7764             default:
7765                 goto scan_number_done;
7766         }
7767 
7768 scan_number_done:
7769         // unget the character after the number (we only read it to know that
7770         // we are done scanning a number)
7771         unget();
7772 
7773         char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7774         errno = 0;
7775 
7776         // try to parse integers first and fall back to floats
7777         if (number_type == token_type::value_unsigned)
7778         {
7779             const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7780 
7781             // we checked the number format before
7782             JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7783 
7784             if (errno == 0)
7785             {
7786                 value_unsigned = static_cast<number_unsigned_t>(x);
7787                 if (value_unsigned == x)
7788                 {
7789                     return token_type::value_unsigned;
7790                 }
7791             }
7792         }
7793         else if (number_type == token_type::value_integer)
7794         {
7795             const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7796 
7797             // we checked the number format before
7798             JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7799 
7800             if (errno == 0)
7801             {
7802                 value_integer = static_cast<number_integer_t>(x);
7803                 if (value_integer == x)
7804                 {
7805                     return token_type::value_integer;
7806                 }
7807             }
7808         }
7809 
7810         // this code is reached if we parse a floating-point number or if an
7811         // integer conversion above failed
7812         strtof(value_float, token_buffer.data(), &endptr);
7813 
7814         // we checked the number format before
7815         JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7816 
7817         return token_type::value_float;
7818     }
7819 
7820     /*!
7821     @param[in] literal_text  the literal text to expect
7822     @param[in] length        the length of the passed literal text
7823     @param[in] return_type   the token type to return on success
7824     */
7825     JSON_HEDLEY_NON_NULL(2)
scan_literal(const char_type * literal_text,const std::size_t length,token_type return_type)7826     token_type scan_literal(const char_type* literal_text, const std::size_t length,
7827                             token_type return_type)
7828     {
7829         JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7830         for (std::size_t i = 1; i < length; ++i)
7831         {
7832             if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7833             {
7834                 error_message = "invalid literal";
7835                 return token_type::parse_error;
7836             }
7837         }
7838         return return_type;
7839     }
7840 
7841     /////////////////////
7842     // input management
7843     /////////////////////
7844 
7845     /// reset token_buffer; current character is beginning of token
reset()7846     void reset() noexcept
7847     {
7848         token_buffer.clear();
7849         token_string.clear();
7850         token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7851     }
7852 
7853     /*
7854     @brief get next character from the input
7855 
7856     This function provides the interface to the used input adapter. It does
7857     not throw in case the input reached EOF, but returns a
7858     `std::char_traits<char>::eof()` in that case.  Stores the scanned characters
7859     for use in error messages.
7860 
7861     @return character read from the input
7862     */
get()7863     char_int_type get()
7864     {
7865         ++position.chars_read_total;
7866         ++position.chars_read_current_line;
7867 
7868         if (next_unget)
7869         {
7870             // just reset the next_unget variable and work with current
7871             next_unget = false;
7872         }
7873         else
7874         {
7875             current = ia.get_character();
7876         }
7877 
7878         if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7879         {
7880             token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7881         }
7882 
7883         if (current == '\n')
7884         {
7885             ++position.lines_read;
7886             position.chars_read_current_line = 0;
7887         }
7888 
7889         return current;
7890     }
7891 
7892     /*!
7893     @brief unget current character (read it again on next get)
7894 
7895     We implement unget by setting variable next_unget to true. The input is not
7896     changed - we just simulate ungetting by modifying chars_read_total,
7897     chars_read_current_line, and token_string. The next call to get() will
7898     behave as if the unget character is read again.
7899     */
unget()7900     void unget()
7901     {
7902         next_unget = true;
7903 
7904         --position.chars_read_total;
7905 
7906         // in case we "unget" a newline, we have to also decrement the lines_read
7907         if (position.chars_read_current_line == 0)
7908         {
7909             if (position.lines_read > 0)
7910             {
7911                 --position.lines_read;
7912             }
7913         }
7914         else
7915         {
7916             --position.chars_read_current_line;
7917         }
7918 
7919         if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7920         {
7921             JSON_ASSERT(!token_string.empty());
7922             token_string.pop_back();
7923         }
7924     }
7925 
7926     /// add a character to token_buffer
add(char_int_type c)7927     void add(char_int_type c)
7928     {
7929         token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7930     }
7931 
7932   public:
7933     /////////////////////
7934     // value getters
7935     /////////////////////
7936 
7937     /// return integer value
get_number_integer() const7938     constexpr number_integer_t get_number_integer() const noexcept
7939     {
7940         return value_integer;
7941     }
7942 
7943     /// return unsigned integer value
get_number_unsigned() const7944     constexpr number_unsigned_t get_number_unsigned() const noexcept
7945     {
7946         return value_unsigned;
7947     }
7948 
7949     /// return floating-point value
get_number_float() const7950     constexpr number_float_t get_number_float() const noexcept
7951     {
7952         return value_float;
7953     }
7954 
7955     /// return current string value (implicitly resets the token; useful only once)
get_string()7956     string_t& get_string()
7957     {
7958         return token_buffer;
7959     }
7960 
7961     /////////////////////
7962     // diagnostics
7963     /////////////////////
7964 
7965     /// return position of last read token
get_position() const7966     constexpr position_t get_position() const noexcept
7967     {
7968         return position;
7969     }
7970 
7971     /// return the last read token (for errors only).  Will never contain EOF
7972     /// (an arbitrary value that is not a valid char value, often -1), because
7973     /// 255 may legitimately occur.  May contain NUL, which should be escaped.
get_token_string() const7974     std::string get_token_string() const
7975     {
7976         // escape control characters
7977         std::string result;
7978         for (const auto c : token_string)
7979         {
7980             if (static_cast<unsigned char>(c) <= '\x1F')
7981             {
7982                 // escape control characters
7983                 std::array<char, 9> cs{{}};
7984                 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7985                 result += cs.data();
7986             }
7987             else
7988             {
7989                 // add character as is
7990                 result.push_back(static_cast<std::string::value_type>(c));
7991             }
7992         }
7993 
7994         return result;
7995     }
7996 
7997     /// return syntax error message
7998     JSON_HEDLEY_RETURNS_NON_NULL
get_error_message() const7999     constexpr const char* get_error_message() const noexcept
8000     {
8001         return error_message;
8002     }
8003 
8004     /////////////////////
8005     // actual scanner
8006     /////////////////////
8007 
8008     /*!
8009     @brief skip the UTF-8 byte order mark
8010     @return true iff there is no BOM or the correct BOM has been skipped
8011     */
skip_bom()8012     bool skip_bom()
8013     {
8014         if (get() == 0xEF)
8015         {
8016             // check if we completely parse the BOM
8017             return get() == 0xBB && get() == 0xBF;
8018         }
8019 
8020         // the first character is not the beginning of the BOM; unget it to
8021         // process is later
8022         unget();
8023         return true;
8024     }
8025 
skip_whitespace()8026     void skip_whitespace()
8027     {
8028         do
8029         {
8030             get();
8031         }
8032         while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8033     }
8034 
scan()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
8045         skip_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
8056             skip_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 ',':
8073                 return token_type::value_separator;
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')}};
8079                 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
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')}};
8084                 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
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')}};
8089                 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
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
8137     position_t position {};
8138 
8139     /// raw input token string (for error messages)
8140     std::vector<char_type> token_string {};
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 
8173 namespace 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>
8181 using boolean_function_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>
8205 using start_object_function_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>
8216 using start_array_function_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>
8223 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
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 =
8243         is_detected_exact<bool, null_function_t, SAX>::value &&
8244         is_detected_exact<bool, boolean_function_t, SAX>::value &&
8245         is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
8246         is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
8247         is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
8248         is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
8249         is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
8250         is_detected_exact<bool, start_object_function_t, SAX>::value &&
8251         is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
8252         is_detected_exact<bool, end_object_function_t, SAX>::value &&
8253         is_detected_exact<bool, start_array_function_t, SAX>::value &&
8254         is_detected_exact<bool, end_array_function_t, SAX>::value &&
8255         is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
8256 };
8257 
8258 template<typename SAX, typename BasicJsonType>
8259 struct is_sax_static_asserts
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(
8280         is_detected_exact<bool, number_integer_function_t, SAX,
8281         number_integer_t>::value,
8282         "Missing/invalid function: bool number_integer(number_integer_t)");
8283     static_assert(
8284         is_detected_exact<bool, number_unsigned_function_t, SAX,
8285         number_unsigned_t>::value,
8286         "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8287     static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8288                   number_float_t, string_t>::value,
8289                   "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8290     static_assert(
8291         is_detected_exact<bool, string_function_t, SAX, string_t>::value,
8292         "Missing/invalid function: bool string(string_t&)");
8293     static_assert(
8294         is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
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(
8307         is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
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 
8319 namespace nlohmann
8320 {
8321 namespace detail
8322 {
8323 
8324 /// how to treat CBOR tags
8325 enum class cbor_tag_handler_t
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 */
little_endianess(int num=1)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>>
8353 class binary_reader
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     */
binary_reader(InputAdapterType && adapter)8370     explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
8371     {
8372         (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
8373     }
8374 
8375     // make class move-only
8376     binary_reader(const binary_reader&) = delete;
8377     binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8378     binary_reader& operator=(const binary_reader&) = delete;
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     */
8390     JSON_HEDLEY_NON_NULL(3)
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)8391     bool sax_parse(const input_format_t format,
8392                    json_sax_t* sax_,
8393                    const bool strict = true,
8394                    const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8395     {
8396         sax = sax_;
8397         bool result = false;
8398 
8399         switch (format)
8400         {
8401             case input_format_t::bson:
8402                 result = parse_bson_internal();
8403                 break;
8404 
8405             case input_format_t::cbor:
8406                 result = parse_cbor_internal(true, tag_handler);
8407                 break;
8408 
8409             case input_format_t::msgpack:
8410                 result = parse_msgpack_internal();
8411                 break;
8412 
8413             case input_format_t::ubjson:
8414                 result = parse_ubjson_internal();
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         {
8425             if (format == input_format_t::ubjson)
8426             {
8427                 get_ignore_noop();
8428             }
8429             else
8430             {
8431                 get();
8432             }
8433 
8434             if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8435             {
8436                 return sax->parse_error(chars_read, get_token_string(),
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     */
parse_bson_internal()8453     bool parse_bson_internal()
8454     {
8455         std::int32_t document_size{};
8456         get_number<std::int32_t, true>(input_format_t::bson, document_size);
8457 
8458         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
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     */
get_bson_cstr(string_t & result)8478     bool get_bson_cstr(string_t& result)
8479     {
8480         auto out = std::back_inserter(result);
8481         while (true)
8482         {
8483             get();
8484             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
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>
get_bson_string(const NumberType len,string_t & result)8508     bool get_bson_string(const NumberType len, string_t& result)
8509     {
8510         if (JSON_HEDLEY_UNLIKELY(len < 1))
8511         {
8512             auto last_token = get_token_string();
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>
get_bson_binary(const NumberType len,binary_t & result)8529     bool get_bson_binary(const NumberType len, binary_t& result)
8530     {
8531         if (JSON_HEDLEY_UNLIKELY(len < 0))
8532         {
8533             auto last_token = get_token_string();
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{};
8539         get_number<std::uint8_t>(input_format_t::bson, subtype);
8540         result.set_subtype(subtype);
8541 
8542         return get_binary(input_format_t::bson, len, result);
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     */
parse_bson_element_internal(const char_int_type element_type,const std::size_t element_type_parse_position)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{};
8569                 string_t value;
8570                 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
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{};
8586                 binary_t value;
8587                 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
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{};
8603                 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8604             }
8605 
8606             case 0x12: // int64
8607             {
8608                 std::int64_t value{};
8609                 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(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     */
parse_bson_element_list(const bool is_array)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 
8644             const std::size_t element_type_parse_position = chars_read;
8645             if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8646             {
8647                 return false;
8648             }
8649 
8650             if (!is_array && !sax->key(key))
8651             {
8652                 return false;
8653             }
8654 
8655             if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
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     */
parse_bson_array()8671     bool parse_bson_array()
8672     {
8673         std::int32_t document_size{};
8674         get_number<std::int32_t, true>(input_format_t::bson, document_size);
8675 
8676         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
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     */
parse_cbor_internal(const bool get_char,const cbor_tag_handler_t tag_handler)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{};
8740                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8741             }
8742 
8743             case 0x19: // Unsigned integer (two-byte uint16_t follows)
8744             {
8745                 std::uint16_t number{};
8746                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8747             }
8748 
8749             case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8750             {
8751                 std::uint32_t number{};
8752                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8753             }
8754 
8755             case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8756             {
8757                 std::uint64_t number{};
8758                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(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{};
8791                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8792             }
8793 
8794             case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8795             {
8796                 std::uint16_t number{};
8797                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8798             }
8799 
8800             case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8801             {
8802                 std::uint32_t number{};
8803                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8804             }
8805 
8806             case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8807             {
8808                 std::uint64_t number{};
8809                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
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{};
8913                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8914             }
8915 
8916             case 0x99: // array (two-byte uint16_t for n follow)
8917             {
8918                 std::uint16_t len{};
8919                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8920             }
8921 
8922             case 0x9A: // array (four-byte uint32_t for n follow)
8923             {
8924                 std::uint32_t len{};
8925                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8926             }
8927 
8928             case 0x9B: // array (eight-byte uint64_t for n follow)
8929             {
8930                 std::uint64_t len{};
8931                 return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
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{};
8967                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8968             }
8969 
8970             case 0xB9: // map (two-byte uint16_t for n follow)
8971             {
8972                 std::uint16_t len{};
8973                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8974             }
8975 
8976             case 0xBA: // map (four-byte uint32_t for n follow)
8977             {
8978                 std::uint32_t len{};
8979                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8980             }
8981 
8982             case 0xBB: // map (eight-byte uint64_t for n follow)
8983             {
8984                 std::uint64_t len{};
8985                 return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
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                 {
9013                     case cbor_tag_handler_t::error:
9014                     {
9015                         auto last_token = get_token_string();
9016                         return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9017                     }
9018 
9019                     case cbor_tag_handler_t::ignore:
9020                     {
9021                         // ignore binary subtype
9022                         switch (current)
9023                         {
9024                             case 0xD8:
9025                             {
9026                                 std::uint8_t subtype_to_ignore{};
9027                                 get_number(input_format_t::cbor, subtype_to_ignore);
9028                                 break;
9029                             }
9030                             case 0xD9:
9031                             {
9032                                 std::uint16_t subtype_to_ignore{};
9033                                 get_number(input_format_t::cbor, subtype_to_ignore);
9034                                 break;
9035                             }
9036                             case 0xDA:
9037                             {
9038                                 std::uint32_t subtype_to_ignore{};
9039                                 get_number(input_format_t::cbor, subtype_to_ignore);
9040                                 break;
9041                             }
9042                             case 0xDB:
9043                             {
9044                                 std::uint64_t subtype_to_ignore{};
9045                                 get_number(input_format_t::cbor, subtype_to_ignore);
9046                                 break;
9047                             }
9048                             default:
9049                                 break;
9050                         }
9051                         return parse_cbor_internal(true, tag_handler);
9052                     }
9053 
9054                     case cbor_tag_handler_t::store:
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{};
9063                                 get_number(input_format_t::cbor, subtype);
9064                                 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9065                                 break;
9066                             }
9067                             case 0xD9:
9068                             {
9069                                 std::uint16_t subtype{};
9070                                 get_number(input_format_t::cbor, subtype);
9071                                 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9072                                 break;
9073                             }
9074                             case 0xDA:
9075                             {
9076                                 std::uint32_t subtype{};
9077                                 get_number(input_format_t::cbor, subtype);
9078                                 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9079                                 break;
9080                             }
9081                             case 0xDB:
9082                             {
9083                                 std::uint64_t subtype{};
9084                                 get_number(input_format_t::cbor, subtype);
9085                                 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(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();
9113                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9114                 {
9115                     return false;
9116                 }
9117                 const auto byte2_raw = get();
9118                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
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             {
9172                 auto last_token = get_token_string();
9173                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
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     */
get_cbor_string(string_t & result)9189     bool get_cbor_string(string_t& result)
9190     {
9191         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
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{};
9230                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9231             }
9232 
9233             case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9234             {
9235                 std::uint16_t len{};
9236                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9237             }
9238 
9239             case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9240             {
9241                 std::uint32_t len{};
9242                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9243             }
9244 
9245             case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9246             {
9247                 std::uint64_t len{};
9248                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9249             }
9250 
9251             case 0x7F: // UTF-8 string (indefinite length)
9252             {
9253                 while (get() != 0xFF)
9254                 {
9255                     string_t chunk;
9256                     if (!get_cbor_string(chunk))
9257                     {
9258                         return false;
9259                     }
9260                     result.append(chunk);
9261                 }
9262                 return true;
9263             }
9264 
9265             default:
9266             {
9267                 auto last_token = get_token_string();
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     */
get_cbor_binary(binary_t & result)9284     bool get_cbor_binary(binary_t& result)
9285     {
9286         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
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) &&
9326                        get_binary(input_format_t::cbor, len, result);
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) &&
9333                        get_binary(input_format_t::cbor, len, result);
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) &&
9340                        get_binary(input_format_t::cbor, len, result);
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) &&
9347                        get_binary(input_format_t::cbor, len, result);
9348             }
9349 
9350             case 0x5F: // Binary data (indefinite length)
9351             {
9352                 while (get() != 0xFF)
9353                 {
9354                     binary_t chunk;
9355                     if (!get_cbor_binary(chunk))
9356                     {
9357                         return false;
9358                     }
9359                     result.insert(result.end(), chunk.begin(), chunk.end());
9360                 }
9361                 return true;
9362             }
9363 
9364             default:
9365             {
9366                 auto last_token = get_token_string();
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     */
get_cbor_array(const std::size_t len,const cbor_tag_handler_t tag_handler)9378     bool get_cbor_array(const std::size_t len,
9379                         const cbor_tag_handler_t tag_handler)
9380     {
9381         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
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             {
9390                 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9391                 {
9392                     return false;
9393                 }
9394             }
9395         }
9396         else
9397         {
9398             while (get() != 0xFF)
9399             {
9400                 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
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     */
get_cbor_object(const std::size_t len,const cbor_tag_handler_t tag_handler)9416     bool get_cbor_object(const std::size_t len,
9417                          const cbor_tag_handler_t tag_handler)
9418     {
9419         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
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();
9432                     if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9433                     {
9434                         return false;
9435                     }
9436 
9437                     if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9438                     {
9439                         return false;
9440                     }
9441                     key.clear();
9442                 }
9443             }
9444             else
9445             {
9446                 while (get() != 0xFF)
9447                 {
9448                     if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9449                     {
9450                         return false;
9451                     }
9452 
9453                     if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
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     */
parse_msgpack_internal()9472     bool parse_msgpack_internal()
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{};
9718                 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9719             }
9720 
9721             case 0xCB: // float 64
9722             {
9723                 double number{};
9724                 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9725             }
9726 
9727             case 0xCC: // uint 8
9728             {
9729                 std::uint8_t number{};
9730                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9731             }
9732 
9733             case 0xCD: // uint 16
9734             {
9735                 std::uint16_t number{};
9736                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9737             }
9738 
9739             case 0xCE: // uint 32
9740             {
9741                 std::uint32_t number{};
9742                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9743             }
9744 
9745             case 0xCF: // uint 64
9746             {
9747                 std::uint64_t number{};
9748                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9749             }
9750 
9751             case 0xD0: // int 8
9752             {
9753                 std::int8_t number{};
9754                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9755             }
9756 
9757             case 0xD1: // int 16
9758             {
9759                 std::int16_t number{};
9760                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9761             }
9762 
9763             case 0xD2: // int 32
9764             {
9765                 std::int32_t number{};
9766                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9767             }
9768 
9769             case 0xD3: // int 64
9770             {
9771                 std::int64_t number{};
9772                 return get_number(input_format_t::msgpack, number) && sax->number_integer(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             {
9836                 auto last_token = get_token_string();
9837                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
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     */
get_msgpack_string(string_t & result)9852     bool get_msgpack_string(string_t& result)
9853     {
9854         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
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{};
9901                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9902             }
9903 
9904             case 0xDA: // str 16
9905             {
9906                 std::uint16_t len{};
9907                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9908             }
9909 
9910             case 0xDB: // str 32
9911             {
9912                 std::uint32_t len{};
9913                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9914             }
9915 
9916             default:
9917             {
9918                 auto last_token = get_token_string();
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     */
get_msgpack_binary(binary_t & result)9934     bool get_msgpack_binary(binary_t& result)
9935     {
9936         // helper function to set the subtype
9937         auto assign_and_return_true = [&result](std::int8_t 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{};
9948                 return get_number(input_format_t::msgpack, len) &&
9949                        get_binary(input_format_t::msgpack, len, result);
9950             }
9951 
9952             case 0xC5: // bin 16
9953             {
9954                 std::uint16_t len{};
9955                 return get_number(input_format_t::msgpack, len) &&
9956                        get_binary(input_format_t::msgpack, len, result);
9957             }
9958 
9959             case 0xC6: // bin 32
9960             {
9961                 std::uint32_t len{};
9962                 return get_number(input_format_t::msgpack, len) &&
9963                        get_binary(input_format_t::msgpack, len, result);
9964             }
9965 
9966             case 0xC7: // ext 8
9967             {
9968                 std::uint8_t len{};
9969                 std::int8_t subtype{};
9970                 return get_number(input_format_t::msgpack, len) &&
9971                        get_number(input_format_t::msgpack, subtype) &&
9972                        get_binary(input_format_t::msgpack, len, result) &&
9973                        assign_and_return_true(subtype);
9974             }
9975 
9976             case 0xC8: // ext 16
9977             {
9978                 std::uint16_t len{};
9979                 std::int8_t subtype{};
9980                 return get_number(input_format_t::msgpack, len) &&
9981                        get_number(input_format_t::msgpack, subtype) &&
9982                        get_binary(input_format_t::msgpack, len, result) &&
9983                        assign_and_return_true(subtype);
9984             }
9985 
9986             case 0xC9: // ext 32
9987             {
9988                 std::uint32_t len{};
9989                 std::int8_t subtype{};
9990                 return get_number(input_format_t::msgpack, len) &&
9991                        get_number(input_format_t::msgpack, subtype) &&
9992                        get_binary(input_format_t::msgpack, len, result) &&
9993                        assign_and_return_true(subtype);
9994             }
9995 
9996             case 0xD4: // fixext 1
9997             {
9998                 std::int8_t subtype{};
9999                 return get_number(input_format_t::msgpack, subtype) &&
10000                        get_binary(input_format_t::msgpack, 1, result) &&
10001                        assign_and_return_true(subtype);
10002             }
10003 
10004             case 0xD5: // fixext 2
10005             {
10006                 std::int8_t subtype{};
10007                 return get_number(input_format_t::msgpack, subtype) &&
10008                        get_binary(input_format_t::msgpack, 2, result) &&
10009                        assign_and_return_true(subtype);
10010             }
10011 
10012             case 0xD6: // fixext 4
10013             {
10014                 std::int8_t subtype{};
10015                 return get_number(input_format_t::msgpack, subtype) &&
10016                        get_binary(input_format_t::msgpack, 4, result) &&
10017                        assign_and_return_true(subtype);
10018             }
10019 
10020             case 0xD7: // fixext 8
10021             {
10022                 std::int8_t subtype{};
10023                 return get_number(input_format_t::msgpack, subtype) &&
10024                        get_binary(input_format_t::msgpack, 8, result) &&
10025                        assign_and_return_true(subtype);
10026             }
10027 
10028             case 0xD8: // fixext 16
10029             {
10030                 std::int8_t subtype{};
10031                 return get_number(input_format_t::msgpack, subtype) &&
10032                        get_binary(input_format_t::msgpack, 16, result) &&
10033                        assign_and_return_true(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     */
get_msgpack_array(const std::size_t len)10045     bool get_msgpack_array(const std::size_t len)
10046     {
10047         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10048         {
10049             return false;
10050         }
10051 
10052         for (std::size_t i = 0; i < len; ++i)
10053         {
10054             if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
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     */
get_msgpack_object(const std::size_t len)10067     bool get_msgpack_object(const std::size_t len)
10068     {
10069         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10070         {
10071             return false;
10072         }
10073 
10074         string_t key;
10075         for (std::size_t i = 0; i < len; ++i)
10076         {
10077             get();
10078             if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10079             {
10080                 return false;
10081             }
10082 
10083             if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
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     */
parse_ubjson_internal(const bool get_char=true)10104     bool parse_ubjson_internal(const bool get_char = true)
10105     {
10106         return get_ubjson_value(get_char ? get_ignore_noop() : current);
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     */
get_ubjson_string(string_t & result,const bool get_char=true)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 
10130         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10131         {
10132             return false;
10133         }
10134 
10135         switch (current)
10136         {
10137             case 'U':
10138             {
10139                 std::uint8_t len{};
10140                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10141             }
10142 
10143             case 'i':
10144             {
10145                 std::int8_t len{};
10146                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10147             }
10148 
10149             case 'I':
10150             {
10151                 std::int16_t len{};
10152                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10153             }
10154 
10155             case 'l':
10156             {
10157                 std::int32_t len{};
10158                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10159             }
10160 
10161             case 'L':
10162             {
10163                 std::int64_t len{};
10164                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10165             }
10166 
10167             default:
10168                 auto last_token = get_token_string();
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     */
get_ubjson_size_value(std::size_t & result)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{};
10184                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, 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{};
10195                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, 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{};
10206                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, 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{};
10217                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, 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{};
10228                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10229                 {
10230                     return false;
10231                 }
10232                 result = static_cast<std::size_t>(number);
10233                 return true;
10234             }
10235 
10236             default:
10237             {
10238                 auto last_token = get_token_string();
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     */
get_ubjson_size_type(std::pair<std::size_t,char_int_type> & result)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 
10259         get_ignore_noop();
10260 
10261         if (current == '$')
10262         {
10263             result.second = get();  // must not ignore 'N', because 'N' maybe the type
10264             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
10265             {
10266                 return false;
10267             }
10268 
10269             get_ignore_noop();
10270             if (JSON_HEDLEY_UNLIKELY(current != '#'))
10271             {
10272                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10273                 {
10274                     return false;
10275                 }
10276                 auto last_token = get_token_string();
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 
10280             return get_ubjson_size_value(result.first);
10281         }
10282 
10283         if (current == '#')
10284         {
10285             return get_ubjson_size_value(result.first);
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     */
get_ubjson_value(const char_int_type prefix)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{};
10313                 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
10314             }
10315 
10316             case 'i':
10317             {
10318                 std::int8_t number{};
10319                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10320             }
10321 
10322             case 'I':
10323             {
10324                 std::int16_t number{};
10325                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10326             }
10327 
10328             case 'l':
10329             {
10330                 std::int32_t number{};
10331                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10332             }
10333 
10334             case 'L':
10335             {
10336                 std::int64_t number{};
10337                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10338             }
10339 
10340             case 'd':
10341             {
10342                 float number{};
10343                 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10344             }
10345 
10346             case 'D':
10347             {
10348                 double number{};
10349                 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10350             }
10351 
10352             case 'H':
10353             {
10354                 return get_ubjson_high_precision_number();
10355             }
10356 
10357             case 'C':  // char
10358             {
10359                 get();
10360                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
10361                 {
10362                     return false;
10363                 }
10364                 if (JSON_HEDLEY_UNLIKELY(current > 127))
10365                 {
10366                     auto last_token = get_token_string();
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             {
10387                 auto last_token = get_token_string();
10388                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
10389             }
10390         }
10391     }
10392 
10393     /*!
10394     @return whether array creation completed
10395     */
get_ubjson_array()10396     bool get_ubjson_array()
10397     {
10398         std::pair<std::size_t, char_int_type> size_and_type;
10399         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10400         {
10401             return false;
10402         }
10403 
10404         if (size_and_type.first != string_t::npos)
10405         {
10406             if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
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                     {
10417                         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
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                 {
10428                     if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10429                     {
10430                         return false;
10431                     }
10432                 }
10433             }
10434         }
10435         else
10436         {
10437             if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10438             {
10439                 return false;
10440             }
10441 
10442             while (current != ']')
10443             {
10444                 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
10445                 {
10446                     return false;
10447                 }
10448                 get_ignore_noop();
10449             }
10450         }
10451 
10452         return sax->end_array();
10453     }
10454 
10455     /*!
10456     @return whether object creation completed
10457     */
get_ubjson_object()10458     bool get_ubjson_object()
10459     {
10460         std::pair<std::size_t, char_int_type> size_and_type;
10461         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10462         {
10463             return false;
10464         }
10465 
10466         string_t key;
10467         if (size_and_type.first != string_t::npos)
10468         {
10469             if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
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                 {
10478                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10479                     {
10480                         return false;
10481                     }
10482                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
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                 {
10493                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10494                     {
10495                         return false;
10496                     }
10497                     if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10498                     {
10499                         return false;
10500                     }
10501                     key.clear();
10502                 }
10503             }
10504         }
10505         else
10506         {
10507             if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10508             {
10509                 return false;
10510             }
10511 
10512             while (current != '}')
10513             {
10514                 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
10515                 {
10516                     return false;
10517                 }
10518                 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10519                 {
10520                     return false;
10521                 }
10522                 get_ignore_noop();
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 
get_ubjson_high_precision_number()10533     bool get_ubjson_high_precision_number()
10534     {
10535         // get size of following number string
10536         std::size_t size{};
10537         auto res = get_ubjson_size_value(size);
10538         if (JSON_HEDLEY_UNLIKELY(!res))
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();
10548             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
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));
10557         auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
10558         const auto result_number = number_lexer.scan();
10559         const auto number_string = number_lexer.get_token_string();
10560         const auto result_remainder = number_lexer.scan();
10561 
10562         using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
10563 
10564         if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
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         {
10571             case token_type::value_integer:
10572                 return sax->number_integer(number_lexer.get_number_integer());
10573             case token_type::value_unsigned:
10574                 return sax->number_unsigned(number_lexer.get_number_unsigned());
10575             case token_type::value_float:
10576                 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
10577             case token_type::uninitialized:
10578             case token_type::literal_true:
10579             case token_type::literal_false:
10580             case token_type::literal_null:
10581             case token_type::value_string:
10582             case token_type::begin_array:
10583             case token_type::begin_object:
10584             case token_type::end_array:
10585             case token_type::end_object:
10586             case token_type::name_separator:
10587             case token_type::value_separator:
10588             case token_type::parse_error:
10589             case token_type::end_of_input:
10590             case token_type::literal_or_value:
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     */
get()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     */
get_ignore_noop()10618     char_int_type get_ignore_noop()
10619     {
10620         do
10621         {
10622             get();
10623         }
10624         while (current == 'N');
10625 
10626         return current;
10627     }
10628 
10629     /*
10630     @brief read a number from the input
10631 
10632     @tparam NumberType the type of the number
10633     @param[in] format   the current format (for diagnostics)
10634     @param[out] result  number of type @a NumberType
10635 
10636     @return whether conversion completed
10637 
10638     @note This function needs to respect the system's endianess, because
10639           bytes in CBOR, MessagePack, and UBJSON are stored in network order
10640           (big endian) and therefore need reordering on little endian systems.
10641     */
10642     template<typename NumberType, bool InputIsLittleEndian = false>
get_number(const input_format_t format,NumberType & result)10643     bool get_number(const input_format_t format, NumberType& result)
10644     {
10645         // step 1: read input into array with system's byte order
10646         std::array<std::uint8_t, sizeof(NumberType)> vec{};
10647         for (std::size_t i = 0; i < sizeof(NumberType); ++i)
10648         {
10649             get();
10650             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10651             {
10652                 return false;
10653             }
10654 
10655             // reverse byte order prior to conversion if necessary
10656             if (is_little_endian != InputIsLittleEndian)
10657             {
10658                 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10659             }
10660             else
10661             {
10662                 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10663             }
10664         }
10665 
10666         // step 2: convert array into number of type T and return
10667         std::memcpy(&result, vec.data(), sizeof(NumberType));
10668         return true;
10669     }
10670 
10671     /*!
10672     @brief create a string by reading characters from the input
10673 
10674     @tparam NumberType the type of the number
10675     @param[in] format the current format (for diagnostics)
10676     @param[in] len number of characters to read
10677     @param[out] result string created by reading @a len bytes
10678 
10679     @return whether string creation completed
10680 
10681     @note We can not reserve @a len bytes for the result, because @a len
10682           may be too large. Usually, @ref unexpect_eof() detects the end of
10683           the input before we run out of string memory.
10684     */
10685     template<typename NumberType>
get_string(const input_format_t format,const NumberType len,string_t & result)10686     bool get_string(const input_format_t format,
10687                     const NumberType len,
10688                     string_t& result)
10689     {
10690         bool success = true;
10691         for (NumberType i = 0; i < len; i++)
10692         {
10693             get();
10694             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10695             {
10696                 success = false;
10697                 break;
10698             }
10699             result.push_back(static_cast<typename string_t::value_type>(current));
10700         }
10701         return success;
10702     }
10703 
10704     /*!
10705     @brief create a byte array by reading bytes from the input
10706 
10707     @tparam NumberType the type of the number
10708     @param[in] format the current format (for diagnostics)
10709     @param[in] len number of bytes to read
10710     @param[out] result byte array created by reading @a len bytes
10711 
10712     @return whether byte array creation completed
10713 
10714     @note We can not reserve @a len bytes for the result, because @a len
10715           may be too large. Usually, @ref unexpect_eof() detects the end of
10716           the input before we run out of memory.
10717     */
10718     template<typename NumberType>
get_binary(const input_format_t format,const NumberType len,binary_t & result)10719     bool get_binary(const input_format_t format,
10720                     const NumberType len,
10721                     binary_t& result)
10722     {
10723         bool success = true;
10724         for (NumberType i = 0; i < len; i++)
10725         {
10726             get();
10727             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10728             {
10729                 success = false;
10730                 break;
10731             }
10732             result.push_back(static_cast<std::uint8_t>(current));
10733         }
10734         return success;
10735     }
10736 
10737     /*!
10738     @param[in] format   the current format (for diagnostics)
10739     @param[in] context  further context information (for diagnostics)
10740     @return whether the last read character is not EOF
10741     */
10742     JSON_HEDLEY_NON_NULL(3)
unexpect_eof(const input_format_t format,const char * context) const10743     bool unexpect_eof(const input_format_t format, const char* context) const
10744     {
10745         if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10746         {
10747             return sax->parse_error(chars_read, "<end of file>",
10748                                     parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
10749         }
10750         return true;
10751     }
10752 
10753     /*!
10754     @return a string representation of the last read byte
10755     */
get_token_string() const10756     std::string get_token_string() const
10757     {
10758         std::array<char, 3> cr{{}};
10759         (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10760         return std::string{cr.data()};
10761     }
10762 
10763     /*!
10764     @param[in] format   the current format
10765     @param[in] detail   a detailed error message
10766     @param[in] context  further context information
10767     @return a message string to use in the parse_error exceptions
10768     */
exception_message(const input_format_t format,const std::string & detail,const std::string & context) const10769     std::string exception_message(const input_format_t format,
10770                                   const std::string& detail,
10771                                   const std::string& context) const
10772     {
10773         std::string error_msg = "syntax error while parsing ";
10774 
10775         switch (format)
10776         {
10777             case input_format_t::cbor:
10778                 error_msg += "CBOR";
10779                 break;
10780 
10781             case input_format_t::msgpack:
10782                 error_msg += "MessagePack";
10783                 break;
10784 
10785             case input_format_t::ubjson:
10786                 error_msg += "UBJSON";
10787                 break;
10788 
10789             case input_format_t::bson:
10790                 error_msg += "BSON";
10791                 break;
10792 
10793             case input_format_t::json: // LCOV_EXCL_LINE
10794             default:            // LCOV_EXCL_LINE
10795                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10796         }
10797 
10798         return error_msg + " " + context + ": " + detail;
10799     }
10800 
10801   private:
10802     /// input adapter
10803     InputAdapterType ia;
10804 
10805     /// the current character
10806     char_int_type current = std::char_traits<char_type>::eof();
10807 
10808     /// the number of characters read
10809     std::size_t chars_read = 0;
10810 
10811     /// whether we can assume little endianess
10812     const bool is_little_endian = little_endianess();
10813 
10814     /// the SAX parser
10815     json_sax_t* sax = nullptr;
10816 };
10817 }  // namespace detail
10818 }  // namespace nlohmann
10819 
10820 // #include <nlohmann/detail/input/input_adapters.hpp>
10821 
10822 // #include <nlohmann/detail/input/lexer.hpp>
10823 
10824 // #include <nlohmann/detail/input/parser.hpp>
10825 
10826 
10827 #include <cmath> // isfinite
10828 #include <cstdint> // uint8_t
10829 #include <functional> // function
10830 #include <string> // string
10831 #include <utility> // move
10832 #include <vector> // vector
10833 
10834 // #include <nlohmann/detail/exceptions.hpp>
10835 
10836 // #include <nlohmann/detail/input/input_adapters.hpp>
10837 
10838 // #include <nlohmann/detail/input/json_sax.hpp>
10839 
10840 // #include <nlohmann/detail/input/lexer.hpp>
10841 
10842 // #include <nlohmann/detail/macro_scope.hpp>
10843 
10844 // #include <nlohmann/detail/meta/is_sax.hpp>
10845 
10846 // #include <nlohmann/detail/value_t.hpp>
10847 
10848 
10849 namespace nlohmann
10850 {
10851 namespace detail
10852 {
10853 ////////////
10854 // parser //
10855 ////////////
10856 
10857 enum class parse_event_t : std::uint8_t
10858 {
10859     /// the parser read `{` and started to process a JSON object
10860     object_start,
10861     /// the parser read `}` and finished processing a JSON object
10862     object_end,
10863     /// the parser read `[` and started to process a JSON array
10864     array_start,
10865     /// the parser read `]` and finished processing a JSON array
10866     array_end,
10867     /// the parser read a key of a value in an object
10868     key,
10869     /// the parser finished reading a JSON value
10870     value
10871 };
10872 
10873 template<typename BasicJsonType>
10874 using parser_callback_t =
10875     std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
10876 
10877 /*!
10878 @brief syntax analysis
10879 
10880 This class implements a recursive descent parser.
10881 */
10882 template<typename BasicJsonType, typename InputAdapterType>
10883 class parser
10884 {
10885     using number_integer_t = typename BasicJsonType::number_integer_t;
10886     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10887     using number_float_t = typename BasicJsonType::number_float_t;
10888     using string_t = typename BasicJsonType::string_t;
10889     using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10890     using token_type = typename lexer_t::token_type;
10891 
10892   public:
10893     /// a parser reading from an input adapter
parser(InputAdapterType && adapter,const parser_callback_t<BasicJsonType> cb=nullptr,const bool allow_exceptions_=true,const bool skip_comments=false)10894     explicit parser(InputAdapterType&& adapter,
10895                     const parser_callback_t<BasicJsonType> cb = nullptr,
10896                     const bool allow_exceptions_ = true,
10897                     const bool skip_comments = false)
10898         : callback(cb)
10899         , m_lexer(std::move(adapter), skip_comments)
10900         , allow_exceptions(allow_exceptions_)
10901     {
10902         // read first token
10903         get_token();
10904     }
10905 
10906     /*!
10907     @brief public parser interface
10908 
10909     @param[in] strict      whether to expect the last token to be EOF
10910     @param[in,out] result  parsed JSON value
10911 
10912     @throw parse_error.101 in case of an unexpected token
10913     @throw parse_error.102 if to_unicode fails or surrogate error
10914     @throw parse_error.103 if to_unicode fails
10915     */
parse(const bool strict,BasicJsonType & result)10916     void parse(const bool strict, BasicJsonType& result)
10917     {
10918         if (callback)
10919         {
10920             json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
10921             sax_parse_internal(&sdp);
10922 
10923             // in strict mode, input must be completely read
10924             if (strict && (get_token() != token_type::end_of_input))
10925             {
10926                 sdp.parse_error(m_lexer.get_position(),
10927                                 m_lexer.get_token_string(),
10928                                 parse_error::create(101, m_lexer.get_position(),
10929                                                     exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10930             }
10931 
10932             // in case of an error, return discarded value
10933             if (sdp.is_errored())
10934             {
10935                 result = value_t::discarded;
10936                 return;
10937             }
10938 
10939             // set top-level value to null if it was discarded by the callback
10940             // function
10941             if (result.is_discarded())
10942             {
10943                 result = nullptr;
10944             }
10945         }
10946         else
10947         {
10948             json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
10949             sax_parse_internal(&sdp);
10950 
10951             // in strict mode, input must be completely read
10952             if (strict && (get_token() != token_type::end_of_input))
10953             {
10954                 sdp.parse_error(m_lexer.get_position(),
10955                                 m_lexer.get_token_string(),
10956                                 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10957             }
10958 
10959             // in case of an error, return discarded value
10960             if (sdp.is_errored())
10961             {
10962                 result = value_t::discarded;
10963                 return;
10964             }
10965         }
10966 
10967         result.assert_invariant();
10968     }
10969 
10970     /*!
10971     @brief public accept interface
10972 
10973     @param[in] strict  whether to expect the last token to be EOF
10974     @return whether the input is a proper JSON text
10975     */
accept(const bool strict=true)10976     bool accept(const bool strict = true)
10977     {
10978         json_sax_acceptor<BasicJsonType> sax_acceptor;
10979         return sax_parse(&sax_acceptor, strict);
10980     }
10981 
10982     template<typename SAX>
10983     JSON_HEDLEY_NON_NULL(2)
sax_parse(SAX * sax,const bool strict=true)10984     bool sax_parse(SAX* sax, const bool strict = true)
10985     {
10986         (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
10987         const bool result = sax_parse_internal(sax);
10988 
10989         // strict mode: next byte must be EOF
10990         if (result && strict && (get_token() != token_type::end_of_input))
10991         {
10992             return sax->parse_error(m_lexer.get_position(),
10993                                     m_lexer.get_token_string(),
10994                                     parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10995         }
10996 
10997         return result;
10998     }
10999 
11000   private:
11001     template<typename SAX>
11002     JSON_HEDLEY_NON_NULL(2)
sax_parse_internal(SAX * sax)11003     bool sax_parse_internal(SAX* sax)
11004     {
11005         // stack to remember the hierarchy of structured values we are parsing
11006         // true = array; false = object
11007         std::vector<bool> states;
11008         // value to avoid a goto (see comment where set to true)
11009         bool skip_to_state_evaluation = false;
11010 
11011         while (true)
11012         {
11013             if (!skip_to_state_evaluation)
11014             {
11015                 // invariant: get_token() was called before each iteration
11016                 switch (last_token)
11017                 {
11018                     case token_type::begin_object:
11019                     {
11020                         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
11021                         {
11022                             return false;
11023                         }
11024 
11025                         // closing } -> we are done
11026                         if (get_token() == token_type::end_object)
11027                         {
11028                             if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11029                             {
11030                                 return false;
11031                             }
11032                             break;
11033                         }
11034 
11035                         // parse key
11036                         if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11037                         {
11038                             return sax->parse_error(m_lexer.get_position(),
11039                                                     m_lexer.get_token_string(),
11040                                                     parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11041                         }
11042                         if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11043                         {
11044                             return false;
11045                         }
11046 
11047                         // parse separator (:)
11048                         if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11049                         {
11050                             return sax->parse_error(m_lexer.get_position(),
11051                                                     m_lexer.get_token_string(),
11052                                                     parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11053                         }
11054 
11055                         // remember we are now inside an object
11056                         states.push_back(false);
11057 
11058                         // parse values
11059                         get_token();
11060                         continue;
11061                     }
11062 
11063                     case token_type::begin_array:
11064                     {
11065                         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
11066                         {
11067                             return false;
11068                         }
11069 
11070                         // closing ] -> we are done
11071                         if (get_token() == token_type::end_array)
11072                         {
11073                             if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11074                             {
11075                                 return false;
11076                             }
11077                             break;
11078                         }
11079 
11080                         // remember we are now inside an array
11081                         states.push_back(true);
11082 
11083                         // parse values (no need to call get_token)
11084                         continue;
11085                     }
11086 
11087                     case token_type::value_float:
11088                     {
11089                         const auto res = m_lexer.get_number_float();
11090 
11091                         if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11092                         {
11093                             return sax->parse_error(m_lexer.get_position(),
11094                                                     m_lexer.get_token_string(),
11095                                                     out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
11096                         }
11097 
11098                         if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11099                         {
11100                             return false;
11101                         }
11102 
11103                         break;
11104                     }
11105 
11106                     case token_type::literal_false:
11107                     {
11108                         if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11109                         {
11110                             return false;
11111                         }
11112                         break;
11113                     }
11114 
11115                     case token_type::literal_null:
11116                     {
11117                         if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11118                         {
11119                             return false;
11120                         }
11121                         break;
11122                     }
11123 
11124                     case token_type::literal_true:
11125                     {
11126                         if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11127                         {
11128                             return false;
11129                         }
11130                         break;
11131                     }
11132 
11133                     case token_type::value_integer:
11134                     {
11135                         if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11136                         {
11137                             return false;
11138                         }
11139                         break;
11140                     }
11141 
11142                     case token_type::value_string:
11143                     {
11144                         if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11145                         {
11146                             return false;
11147                         }
11148                         break;
11149                     }
11150 
11151                     case token_type::value_unsigned:
11152                     {
11153                         if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11154                         {
11155                             return false;
11156                         }
11157                         break;
11158                     }
11159 
11160                     case token_type::parse_error:
11161                     {
11162                         // using "uninitialized" to avoid "expected" message
11163                         return sax->parse_error(m_lexer.get_position(),
11164                                                 m_lexer.get_token_string(),
11165                                                 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
11166                     }
11167 
11168                     case token_type::uninitialized:
11169                     case token_type::end_array:
11170                     case token_type::end_object:
11171                     case token_type::name_separator:
11172                     case token_type::value_separator:
11173                     case token_type::end_of_input:
11174                     case token_type::literal_or_value:
11175                     default: // the last token was unexpected
11176                     {
11177                         return sax->parse_error(m_lexer.get_position(),
11178                                                 m_lexer.get_token_string(),
11179                                                 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
11180                     }
11181                 }
11182             }
11183             else
11184             {
11185                 skip_to_state_evaluation = false;
11186             }
11187 
11188             // we reached this line after we successfully parsed a value
11189             if (states.empty())
11190             {
11191                 // empty stack: we reached the end of the hierarchy: done
11192                 return true;
11193             }
11194 
11195             if (states.back())  // array
11196             {
11197                 // comma -> next value
11198                 if (get_token() == token_type::value_separator)
11199                 {
11200                     // parse a new value
11201                     get_token();
11202                     continue;
11203                 }
11204 
11205                 // closing ]
11206                 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11207                 {
11208                     if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11209                     {
11210                         return false;
11211                     }
11212 
11213                     // We are done with this array. Before we can parse a
11214                     // new value, we need to evaluate the new state first.
11215                     // By setting skip_to_state_evaluation to false, we
11216                     // are effectively jumping to the beginning of this if.
11217                     JSON_ASSERT(!states.empty());
11218                     states.pop_back();
11219                     skip_to_state_evaluation = true;
11220                     continue;
11221                 }
11222 
11223                 return sax->parse_error(m_lexer.get_position(),
11224                                         m_lexer.get_token_string(),
11225                                         parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11226             }
11227 
11228             // states.back() is false -> object
11229 
11230             // comma -> next value
11231             if (get_token() == token_type::value_separator)
11232             {
11233                 // parse key
11234                 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11235                 {
11236                     return sax->parse_error(m_lexer.get_position(),
11237                                             m_lexer.get_token_string(),
11238                                             parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11239                 }
11240 
11241                 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11242                 {
11243                     return false;
11244                 }
11245 
11246                 // parse separator (:)
11247                 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11248                 {
11249                     return sax->parse_error(m_lexer.get_position(),
11250                                             m_lexer.get_token_string(),
11251                                             parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11252                 }
11253 
11254                 // parse values
11255                 get_token();
11256                 continue;
11257             }
11258 
11259             // closing }
11260             if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11261             {
11262                 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11263                 {
11264                     return false;
11265                 }
11266 
11267                 // We are done with this object. Before we can parse a
11268                 // new value, we need to evaluate the new state first.
11269                 // By setting skip_to_state_evaluation to false, we
11270                 // are effectively jumping to the beginning of this if.
11271                 JSON_ASSERT(!states.empty());
11272                 states.pop_back();
11273                 skip_to_state_evaluation = true;
11274                 continue;
11275             }
11276 
11277             return sax->parse_error(m_lexer.get_position(),
11278                                     m_lexer.get_token_string(),
11279                                     parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11280         }
11281     }
11282 
11283     /// get next token from lexer
get_token()11284     token_type get_token()
11285     {
11286         return last_token = m_lexer.scan();
11287     }
11288 
exception_message(const token_type expected,const std::string & context)11289     std::string exception_message(const token_type expected, const std::string& context)
11290     {
11291         std::string error_msg = "syntax error ";
11292 
11293         if (!context.empty())
11294         {
11295             error_msg += "while parsing " + context + " ";
11296         }
11297 
11298         error_msg += "- ";
11299 
11300         if (last_token == token_type::parse_error)
11301         {
11302             error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
11303                          m_lexer.get_token_string() + "'";
11304         }
11305         else
11306         {
11307             error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
11308         }
11309 
11310         if (expected != token_type::uninitialized)
11311         {
11312             error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
11313         }
11314 
11315         return error_msg;
11316     }
11317 
11318   private:
11319     /// callback function
11320     const parser_callback_t<BasicJsonType> callback = nullptr;
11321     /// the type of the last read token
11322     token_type last_token = token_type::uninitialized;
11323     /// the lexer
11324     lexer_t m_lexer;
11325     /// whether to throw exceptions in case of errors
11326     const bool allow_exceptions = true;
11327 };
11328 
11329 }  // namespace detail
11330 }  // namespace nlohmann
11331 
11332 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
11333 
11334 
11335 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11336 
11337 
11338 #include <cstddef> // ptrdiff_t
11339 #include <limits>  // numeric_limits
11340 
11341 // #include <nlohmann/detail/macro_scope.hpp>
11342 
11343 
11344 namespace nlohmann
11345 {
11346 namespace detail
11347 {
11348 /*
11349 @brief an iterator for primitive JSON types
11350 
11351 This class models an iterator for primitive JSON types (boolean, number,
11352 string). It's only purpose is to allow the iterator/const_iterator classes
11353 to "iterate" over primitive values. Internally, the iterator is modeled by
11354 a `difference_type` variable. Value begin_value (`0`) models the begin,
11355 end_value (`1`) models past the end.
11356 */
11357 class primitive_iterator_t
11358 {
11359   private:
11360     using difference_type = std::ptrdiff_t;
11361     static constexpr difference_type begin_value = 0;
11362     static constexpr difference_type end_value = begin_value + 1;
11363 
11364   JSON_PRIVATE_UNLESS_TESTED:
11365     /// iterator as signed integer type
11366     difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11367 
11368   public:
get_value() const11369     constexpr difference_type get_value() const noexcept
11370     {
11371         return m_it;
11372     }
11373 
11374     /// set iterator to a defined beginning
set_begin()11375     void set_begin() noexcept
11376     {
11377         m_it = begin_value;
11378     }
11379 
11380     /// set iterator to a defined past the end
set_end()11381     void set_end() noexcept
11382     {
11383         m_it = end_value;
11384     }
11385 
11386     /// return whether the iterator can be dereferenced
is_begin() const11387     constexpr bool is_begin() const noexcept
11388     {
11389         return m_it == begin_value;
11390     }
11391 
11392     /// return whether the iterator is at end
is_end() const11393     constexpr bool is_end() const noexcept
11394     {
11395         return m_it == end_value;
11396     }
11397 
operator ==(primitive_iterator_t lhs,primitive_iterator_t rhs)11398     friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11399     {
11400         return lhs.m_it == rhs.m_it;
11401     }
11402 
operator <(primitive_iterator_t lhs,primitive_iterator_t rhs)11403     friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11404     {
11405         return lhs.m_it < rhs.m_it;
11406     }
11407 
operator +(difference_type n)11408     primitive_iterator_t operator+(difference_type n) noexcept
11409     {
11410         auto result = *this;
11411         result += n;
11412         return result;
11413     }
11414 
operator -(primitive_iterator_t lhs,primitive_iterator_t rhs)11415     friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11416     {
11417         return lhs.m_it - rhs.m_it;
11418     }
11419 
operator ++()11420     primitive_iterator_t& operator++() noexcept
11421     {
11422         ++m_it;
11423         return *this;
11424     }
11425 
operator ++(int)11426     primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
11427     {
11428         auto result = *this;
11429         ++m_it;
11430         return result;
11431     }
11432 
operator --()11433     primitive_iterator_t& operator--() noexcept
11434     {
11435         --m_it;
11436         return *this;
11437     }
11438 
operator --(int)11439     primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
11440     {
11441         auto result = *this;
11442         --m_it;
11443         return result;
11444     }
11445 
operator +=(difference_type n)11446     primitive_iterator_t& operator+=(difference_type n) noexcept
11447     {
11448         m_it += n;
11449         return *this;
11450     }
11451 
operator -=(difference_type n)11452     primitive_iterator_t& operator-=(difference_type n) noexcept
11453     {
11454         m_it -= n;
11455         return *this;
11456     }
11457 };
11458 }  // namespace detail
11459 }  // namespace nlohmann
11460 
11461 
11462 namespace nlohmann
11463 {
11464 namespace detail
11465 {
11466 /*!
11467 @brief an iterator value
11468 
11469 @note This structure could easily be a union, but MSVC currently does not allow
11470 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
11471 */
11472 template<typename BasicJsonType> struct internal_iterator
11473 {
11474     /// iterator for JSON objects
11475     typename BasicJsonType::object_t::iterator object_iterator {};
11476     /// iterator for JSON arrays
11477     typename BasicJsonType::array_t::iterator array_iterator {};
11478     /// generic iterator for all other types
11479     primitive_iterator_t primitive_iterator {};
11480 };
11481 }  // namespace detail
11482 }  // namespace nlohmann
11483 
11484 // #include <nlohmann/detail/iterators/iter_impl.hpp>
11485 
11486 
11487 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
11488 #include <type_traits> // conditional, is_const, remove_const
11489 
11490 // #include <nlohmann/detail/exceptions.hpp>
11491 
11492 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
11493 
11494 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11495 
11496 // #include <nlohmann/detail/macro_scope.hpp>
11497 
11498 // #include <nlohmann/detail/meta/cpp_future.hpp>
11499 
11500 // #include <nlohmann/detail/meta/type_traits.hpp>
11501 
11502 // #include <nlohmann/detail/value_t.hpp>
11503 
11504 
11505 namespace nlohmann
11506 {
11507 namespace detail
11508 {
11509 // forward declare, to be able to friend it later on
11510 template<typename IteratorType> class iteration_proxy;
11511 template<typename IteratorType> class iteration_proxy_value;
11512 
11513 /*!
11514 @brief a template for a bidirectional iterator for the @ref basic_json class
11515 This class implements a both iterators (iterator and const_iterator) for the
11516 @ref basic_json class.
11517 @note An iterator is called *initialized* when a pointer to a JSON value has
11518       been set (e.g., by a constructor or a copy assignment). If the iterator is
11519       default-constructed, it is *uninitialized* and most methods are undefined.
11520       **The library uses assertions to detect calls on uninitialized iterators.**
11521 @requirement The class satisfies the following concept requirements:
11522 -
11523 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
11524   The iterator that can be moved can be moved in both directions (i.e.
11525   incremented and decremented).
11526 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
11527        iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
11528 */
11529 template<typename BasicJsonType>
11530 class iter_impl
11531 {
11532     /// the iterator with BasicJsonType of different const-ness
11533     using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
11534     /// allow basic_json to access private members
11535     friend other_iter_impl;
11536     friend BasicJsonType;
11537     friend iteration_proxy<iter_impl>;
11538     friend iteration_proxy_value<iter_impl>;
11539 
11540     using object_t = typename BasicJsonType::object_t;
11541     using array_t = typename BasicJsonType::array_t;
11542     // make sure BasicJsonType is basic_json or const basic_json
11543     static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
11544                   "iter_impl only accepts (const) basic_json");
11545 
11546   public:
11547 
11548     /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
11549     /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
11550     /// A user-defined iterator should provide publicly accessible typedefs named
11551     /// iterator_category, value_type, difference_type, pointer, and reference.
11552     /// Note that value_type is required to be non-const, even for constant iterators.
11553     using iterator_category = std::bidirectional_iterator_tag;
11554 
11555     /// the type of the values when the iterator is dereferenced
11556     using value_type = typename BasicJsonType::value_type;
11557     /// a type to represent differences between iterators
11558     using difference_type = typename BasicJsonType::difference_type;
11559     /// defines a pointer to the type iterated over (value_type)
11560     using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
11561           typename BasicJsonType::const_pointer,
11562           typename BasicJsonType::pointer>::type;
11563     /// defines a reference to the type iterated over (value_type)
11564     using reference =
11565         typename std::conditional<std::is_const<BasicJsonType>::value,
11566         typename BasicJsonType::const_reference,
11567         typename BasicJsonType::reference>::type;
11568 
11569     iter_impl() = default;
11570     ~iter_impl() = default;
11571     iter_impl(iter_impl&&) noexcept = default;
11572     iter_impl& operator=(iter_impl&&) noexcept = default;
11573 
11574     /*!
11575     @brief constructor for a given JSON instance
11576     @param[in] object  pointer to a JSON object for this iterator
11577     @pre object != nullptr
11578     @post The iterator is initialized; i.e. `m_object != nullptr`.
11579     */
iter_impl(pointer object)11580     explicit iter_impl(pointer object) noexcept : m_object(object)
11581     {
11582         JSON_ASSERT(m_object != nullptr);
11583 
11584         switch (m_object->m_type)
11585         {
11586             case value_t::object:
11587             {
11588                 m_it.object_iterator = typename object_t::iterator();
11589                 break;
11590             }
11591 
11592             case value_t::array:
11593             {
11594                 m_it.array_iterator = typename array_t::iterator();
11595                 break;
11596             }
11597 
11598             case value_t::null:
11599             case value_t::string:
11600             case value_t::boolean:
11601             case value_t::number_integer:
11602             case value_t::number_unsigned:
11603             case value_t::number_float:
11604             case value_t::binary:
11605             case value_t::discarded:
11606             default:
11607             {
11608                 m_it.primitive_iterator = primitive_iterator_t();
11609                 break;
11610             }
11611         }
11612     }
11613 
11614     /*!
11615     @note The conventional copy constructor and copy assignment are implicitly
11616           defined. Combined with the following converting constructor and
11617           assignment, they support: (1) copy from iterator to iterator, (2)
11618           copy from const iterator to const iterator, and (3) conversion from
11619           iterator to const iterator. However conversion from const iterator
11620           to iterator is not defined.
11621     */
11622 
11623     /*!
11624     @brief const copy constructor
11625     @param[in] other const iterator to copy from
11626     @note This copy constructor had to be defined explicitly to circumvent a bug
11627           occurring on msvc v19.0 compiler (VS 2015) debug build. For more
11628           information refer to: https://github.com/nlohmann/json/issues/1608
11629     */
iter_impl(const iter_impl<const BasicJsonType> & other)11630     iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
11631         : m_object(other.m_object), m_it(other.m_it)
11632     {}
11633 
11634     /*!
11635     @brief converting assignment
11636     @param[in] other const iterator to copy from
11637     @return const/non-const iterator
11638     @note It is not checked whether @a other is initialized.
11639     */
operator =(const iter_impl<const BasicJsonType> & other)11640     iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
11641     {
11642         if (&other != this)
11643         {
11644             m_object = other.m_object;
11645             m_it = other.m_it;
11646         }
11647         return *this;
11648     }
11649 
11650     /*!
11651     @brief converting constructor
11652     @param[in] other  non-const iterator to copy from
11653     @note It is not checked whether @a other is initialized.
11654     */
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)11655     iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
11656         : m_object(other.m_object), m_it(other.m_it)
11657     {}
11658 
11659     /*!
11660     @brief converting assignment
11661     @param[in] other  non-const iterator to copy from
11662     @return const/non-const iterator
11663     @note It is not checked whether @a other is initialized.
11664     */
operator =(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)11665     iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
11666     {
11667         m_object = other.m_object;
11668         m_it = other.m_it;
11669         return *this;
11670     }
11671 
11672   JSON_PRIVATE_UNLESS_TESTED:
11673     /*!
11674     @brief set the iterator to the first value
11675     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11676     */
11677     void set_begin() noexcept
11678     {
11679         JSON_ASSERT(m_object != nullptr);
11680 
11681         switch (m_object->m_type)
11682         {
11683             case value_t::object:
11684             {
11685                 m_it.object_iterator = m_object->m_value.object->begin();
11686                 break;
11687             }
11688 
11689             case value_t::array:
11690             {
11691                 m_it.array_iterator = m_object->m_value.array->begin();
11692                 break;
11693             }
11694 
11695             case value_t::null:
11696             {
11697                 // set to end so begin()==end() is true: null is empty
11698                 m_it.primitive_iterator.set_end();
11699                 break;
11700             }
11701 
11702             case value_t::string:
11703             case value_t::boolean:
11704             case value_t::number_integer:
11705             case value_t::number_unsigned:
11706             case value_t::number_float:
11707             case value_t::binary:
11708             case value_t::discarded:
11709             default:
11710             {
11711                 m_it.primitive_iterator.set_begin();
11712                 break;
11713             }
11714         }
11715     }
11716 
11717     /*!
11718     @brief set the iterator past the last value
11719     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11720     */
set_end()11721     void set_end() noexcept
11722     {
11723         JSON_ASSERT(m_object != nullptr);
11724 
11725         switch (m_object->m_type)
11726         {
11727             case value_t::object:
11728             {
11729                 m_it.object_iterator = m_object->m_value.object->end();
11730                 break;
11731             }
11732 
11733             case value_t::array:
11734             {
11735                 m_it.array_iterator = m_object->m_value.array->end();
11736                 break;
11737             }
11738 
11739             case value_t::null:
11740             case value_t::string:
11741             case value_t::boolean:
11742             case value_t::number_integer:
11743             case value_t::number_unsigned:
11744             case value_t::number_float:
11745             case value_t::binary:
11746             case value_t::discarded:
11747             default:
11748             {
11749                 m_it.primitive_iterator.set_end();
11750                 break;
11751             }
11752         }
11753     }
11754 
11755   public:
11756     /*!
11757     @brief return a reference to the value pointed to by the iterator
11758     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11759     */
operator *() const11760     reference operator*() const
11761     {
11762         JSON_ASSERT(m_object != nullptr);
11763 
11764         switch (m_object->m_type)
11765         {
11766             case value_t::object:
11767             {
11768                 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11769                 return m_it.object_iterator->second;
11770             }
11771 
11772             case value_t::array:
11773             {
11774                 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11775                 return *m_it.array_iterator;
11776             }
11777 
11778             case value_t::null:
11779                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11780 
11781             case value_t::string:
11782             case value_t::boolean:
11783             case value_t::number_integer:
11784             case value_t::number_unsigned:
11785             case value_t::number_float:
11786             case value_t::binary:
11787             case value_t::discarded:
11788             default:
11789             {
11790                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11791                 {
11792                     return *m_object;
11793                 }
11794 
11795                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11796             }
11797         }
11798     }
11799 
11800     /*!
11801     @brief dereference the iterator
11802     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11803     */
operator ->() const11804     pointer operator->() const
11805     {
11806         JSON_ASSERT(m_object != nullptr);
11807 
11808         switch (m_object->m_type)
11809         {
11810             case value_t::object:
11811             {
11812                 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11813                 return &(m_it.object_iterator->second);
11814             }
11815 
11816             case value_t::array:
11817             {
11818                 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11819                 return &*m_it.array_iterator;
11820             }
11821 
11822             case value_t::null:
11823             case value_t::string:
11824             case value_t::boolean:
11825             case value_t::number_integer:
11826             case value_t::number_unsigned:
11827             case value_t::number_float:
11828             case value_t::binary:
11829             case value_t::discarded:
11830             default:
11831             {
11832                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11833                 {
11834                     return m_object;
11835                 }
11836 
11837                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11838             }
11839         }
11840     }
11841 
11842     /*!
11843     @brief post-increment (it++)
11844     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11845     */
operator ++(int)11846     iter_impl const operator++(int) // NOLINT(readability-const-return-type)
11847     {
11848         auto result = *this;
11849         ++(*this);
11850         return result;
11851     }
11852 
11853     /*!
11854     @brief pre-increment (++it)
11855     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11856     */
operator ++()11857     iter_impl& operator++()
11858     {
11859         JSON_ASSERT(m_object != nullptr);
11860 
11861         switch (m_object->m_type)
11862         {
11863             case value_t::object:
11864             {
11865                 std::advance(m_it.object_iterator, 1);
11866                 break;
11867             }
11868 
11869             case value_t::array:
11870             {
11871                 std::advance(m_it.array_iterator, 1);
11872                 break;
11873             }
11874 
11875             case value_t::null:
11876             case value_t::string:
11877             case value_t::boolean:
11878             case value_t::number_integer:
11879             case value_t::number_unsigned:
11880             case value_t::number_float:
11881             case value_t::binary:
11882             case value_t::discarded:
11883             default:
11884             {
11885                 ++m_it.primitive_iterator;
11886                 break;
11887             }
11888         }
11889 
11890         return *this;
11891     }
11892 
11893     /*!
11894     @brief post-decrement (it--)
11895     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11896     */
operator --(int)11897     iter_impl const operator--(int) // NOLINT(readability-const-return-type)
11898     {
11899         auto result = *this;
11900         --(*this);
11901         return result;
11902     }
11903 
11904     /*!
11905     @brief pre-decrement (--it)
11906     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11907     */
operator --()11908     iter_impl& operator--()
11909     {
11910         JSON_ASSERT(m_object != nullptr);
11911 
11912         switch (m_object->m_type)
11913         {
11914             case value_t::object:
11915             {
11916                 std::advance(m_it.object_iterator, -1);
11917                 break;
11918             }
11919 
11920             case value_t::array:
11921             {
11922                 std::advance(m_it.array_iterator, -1);
11923                 break;
11924             }
11925 
11926             case value_t::null:
11927             case value_t::string:
11928             case value_t::boolean:
11929             case value_t::number_integer:
11930             case value_t::number_unsigned:
11931             case value_t::number_float:
11932             case value_t::binary:
11933             case value_t::discarded:
11934             default:
11935             {
11936                 --m_it.primitive_iterator;
11937                 break;
11938             }
11939         }
11940 
11941         return *this;
11942     }
11943 
11944     /*!
11945     @brief comparison: equal
11946     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11947     */
11948     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 >
operator ==(const IterImpl & other) const11949     bool operator==(const IterImpl& other) const
11950     {
11951         // if objects are not the same, the comparison is undefined
11952         if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11953         {
11954             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
11955         }
11956 
11957         JSON_ASSERT(m_object != nullptr);
11958 
11959         switch (m_object->m_type)
11960         {
11961             case value_t::object:
11962                 return (m_it.object_iterator == other.m_it.object_iterator);
11963 
11964             case value_t::array:
11965                 return (m_it.array_iterator == other.m_it.array_iterator);
11966 
11967             case value_t::null:
11968             case value_t::string:
11969             case value_t::boolean:
11970             case value_t::number_integer:
11971             case value_t::number_unsigned:
11972             case value_t::number_float:
11973             case value_t::binary:
11974             case value_t::discarded:
11975             default:
11976                 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
11977         }
11978     }
11979 
11980     /*!
11981     @brief comparison: not equal
11982     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11983     */
11984     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 >
operator !=(const IterImpl & other) const11985     bool operator!=(const IterImpl& other) const
11986     {
11987         return !operator==(other);
11988     }
11989 
11990     /*!
11991     @brief comparison: smaller
11992     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11993     */
operator <(const iter_impl & other) const11994     bool operator<(const iter_impl& other) const
11995     {
11996         // if objects are not the same, the comparison is undefined
11997         if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11998         {
11999             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12000         }
12001 
12002         JSON_ASSERT(m_object != nullptr);
12003 
12004         switch (m_object->m_type)
12005         {
12006             case value_t::object:
12007                 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
12008 
12009             case value_t::array:
12010                 return (m_it.array_iterator < other.m_it.array_iterator);
12011 
12012             case value_t::null:
12013             case value_t::string:
12014             case value_t::boolean:
12015             case value_t::number_integer:
12016             case value_t::number_unsigned:
12017             case value_t::number_float:
12018             case value_t::binary:
12019             case value_t::discarded:
12020             default:
12021                 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
12022         }
12023     }
12024 
12025     /*!
12026     @brief comparison: less than or equal
12027     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12028     */
operator <=(const iter_impl & other) const12029     bool operator<=(const iter_impl& other) const
12030     {
12031         return !other.operator < (*this);
12032     }
12033 
12034     /*!
12035     @brief comparison: greater than
12036     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12037     */
operator >(const iter_impl & other) const12038     bool operator>(const iter_impl& other) const
12039     {
12040         return !operator<=(other);
12041     }
12042 
12043     /*!
12044     @brief comparison: greater than or equal
12045     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12046     */
operator >=(const iter_impl & other) const12047     bool operator>=(const iter_impl& other) const
12048     {
12049         return !operator<(other);
12050     }
12051 
12052     /*!
12053     @brief add to iterator
12054     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12055     */
operator +=(difference_type i)12056     iter_impl& operator+=(difference_type i)
12057     {
12058         JSON_ASSERT(m_object != nullptr);
12059 
12060         switch (m_object->m_type)
12061         {
12062             case value_t::object:
12063                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12064 
12065             case value_t::array:
12066             {
12067                 std::advance(m_it.array_iterator, i);
12068                 break;
12069             }
12070 
12071             case value_t::null:
12072             case value_t::string:
12073             case value_t::boolean:
12074             case value_t::number_integer:
12075             case value_t::number_unsigned:
12076             case value_t::number_float:
12077             case value_t::binary:
12078             case value_t::discarded:
12079             default:
12080             {
12081                 m_it.primitive_iterator += i;
12082                 break;
12083             }
12084         }
12085 
12086         return *this;
12087     }
12088 
12089     /*!
12090     @brief subtract from iterator
12091     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12092     */
operator -=(difference_type i)12093     iter_impl& operator-=(difference_type i)
12094     {
12095         return operator+=(-i);
12096     }
12097 
12098     /*!
12099     @brief add to iterator
12100     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12101     */
operator +(difference_type i) const12102     iter_impl operator+(difference_type i) const
12103     {
12104         auto result = *this;
12105         result += i;
12106         return result;
12107     }
12108 
12109     /*!
12110     @brief addition of distance and iterator
12111     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12112     */
operator +(difference_type i,const iter_impl & it)12113     friend iter_impl operator+(difference_type i, const iter_impl& it)
12114     {
12115         auto result = it;
12116         result += i;
12117         return result;
12118     }
12119 
12120     /*!
12121     @brief subtract from iterator
12122     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12123     */
operator -(difference_type i) const12124     iter_impl operator-(difference_type i) const
12125     {
12126         auto result = *this;
12127         result -= i;
12128         return result;
12129     }
12130 
12131     /*!
12132     @brief return difference
12133     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12134     */
operator -(const iter_impl & other) const12135     difference_type operator-(const iter_impl& other) const
12136     {
12137         JSON_ASSERT(m_object != nullptr);
12138 
12139         switch (m_object->m_type)
12140         {
12141             case value_t::object:
12142                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12143 
12144             case value_t::array:
12145                 return m_it.array_iterator - other.m_it.array_iterator;
12146 
12147             case value_t::null:
12148             case value_t::string:
12149             case value_t::boolean:
12150             case value_t::number_integer:
12151             case value_t::number_unsigned:
12152             case value_t::number_float:
12153             case value_t::binary:
12154             case value_t::discarded:
12155             default:
12156                 return m_it.primitive_iterator - other.m_it.primitive_iterator;
12157         }
12158     }
12159 
12160     /*!
12161     @brief access to successor
12162     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12163     */
operator [](difference_type n) const12164     reference operator[](difference_type n) const
12165     {
12166         JSON_ASSERT(m_object != nullptr);
12167 
12168         switch (m_object->m_type)
12169         {
12170             case value_t::object:
12171                 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
12172 
12173             case value_t::array:
12174                 return *std::next(m_it.array_iterator, n);
12175 
12176             case value_t::null:
12177                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12178 
12179             case value_t::string:
12180             case value_t::boolean:
12181             case value_t::number_integer:
12182             case value_t::number_unsigned:
12183             case value_t::number_float:
12184             case value_t::binary:
12185             case value_t::discarded:
12186             default:
12187             {
12188                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
12189                 {
12190                     return *m_object;
12191                 }
12192 
12193                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12194             }
12195         }
12196     }
12197 
12198     /*!
12199     @brief return the key of an object iterator
12200     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12201     */
key() const12202     const typename object_t::key_type& key() const
12203     {
12204         JSON_ASSERT(m_object != nullptr);
12205 
12206         if (JSON_HEDLEY_LIKELY(m_object->is_object()))
12207         {
12208             return m_it.object_iterator->first;
12209         }
12210 
12211         JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
12212     }
12213 
12214     /*!
12215     @brief return the value of an iterator
12216     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12217     */
value() const12218     reference value() const
12219     {
12220         return operator*();
12221     }
12222 
12223   JSON_PRIVATE_UNLESS_TESTED:
12224     /// associated JSON instance
12225     pointer m_object = nullptr;
12226     /// the actual iterator of the associated instance
12227     internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
12228 };
12229 } // namespace detail
12230 } // namespace nlohmann
12231 
12232 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12233 
12234 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12235 
12236 
12237 #include <cstddef> // ptrdiff_t
12238 #include <iterator> // reverse_iterator
12239 #include <utility> // declval
12240 
12241 namespace nlohmann
12242 {
12243 namespace detail
12244 {
12245 //////////////////////
12246 // reverse_iterator //
12247 //////////////////////
12248 
12249 /*!
12250 @brief a template for a reverse iterator class
12251 
12252 @tparam Base the base iterator type to reverse. Valid types are @ref
12253 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
12254 create @ref const_reverse_iterator).
12255 
12256 @requirement The class satisfies the following concept requirements:
12257 -
12258 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
12259   The iterator that can be moved can be moved in both directions (i.e.
12260   incremented and decremented).
12261 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
12262   It is possible to write to the pointed-to element (only if @a Base is
12263   @ref iterator).
12264 
12265 @since version 1.0.0
12266 */
12267 template<typename Base>
12268 class json_reverse_iterator : public std::reverse_iterator<Base>
12269 {
12270   public:
12271     using difference_type = std::ptrdiff_t;
12272     /// shortcut to the reverse iterator adapter
12273     using base_iterator = std::reverse_iterator<Base>;
12274     /// the reference type for the pointed-to element
12275     using reference = typename Base::reference;
12276 
12277     /// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type & it)12278     explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
12279         : base_iterator(it) {}
12280 
12281     /// create reverse iterator from base class
json_reverse_iterator(const base_iterator & it)12282     explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12283 
12284     /// post-increment (it++)
operator ++(int)12285     json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
12286     {
12287         return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12288     }
12289 
12290     /// pre-increment (++it)
operator ++()12291     json_reverse_iterator& operator++()
12292     {
12293         return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12294     }
12295 
12296     /// post-decrement (it--)
operator --(int)12297     json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
12298     {
12299         return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12300     }
12301 
12302     /// pre-decrement (--it)
operator --()12303     json_reverse_iterator& operator--()
12304     {
12305         return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12306     }
12307 
12308     /// add to iterator
operator +=(difference_type i)12309     json_reverse_iterator& operator+=(difference_type i)
12310     {
12311         return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12312     }
12313 
12314     /// add to iterator
operator +(difference_type i) const12315     json_reverse_iterator operator+(difference_type i) const
12316     {
12317         return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12318     }
12319 
12320     /// subtract from iterator
operator -(difference_type i) const12321     json_reverse_iterator operator-(difference_type i) const
12322     {
12323         return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12324     }
12325 
12326     /// return difference
operator -(const json_reverse_iterator & other) const12327     difference_type operator-(const json_reverse_iterator& other) const
12328     {
12329         return base_iterator(*this) - base_iterator(other);
12330     }
12331 
12332     /// access to successor
operator [](difference_type n) const12333     reference operator[](difference_type n) const
12334     {
12335         return *(this->operator+(n));
12336     }
12337 
12338     /// return the key of an object iterator
key() const12339     auto key() const -> decltype(std::declval<Base>().key())
12340     {
12341         auto it = --this->base();
12342         return it.key();
12343     }
12344 
12345     /// return the value of an iterator
value() const12346     reference value() const
12347     {
12348         auto it = --this->base();
12349         return it.operator * ();
12350     }
12351 };
12352 }  // namespace detail
12353 }  // namespace nlohmann
12354 
12355 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12356 
12357 // #include <nlohmann/detail/json_pointer.hpp>
12358 
12359 
12360 #include <algorithm> // all_of
12361 #include <cctype> // isdigit
12362 #include <limits> // max
12363 #include <numeric> // accumulate
12364 #include <string> // string
12365 #include <utility> // move
12366 #include <vector> // vector
12367 
12368 // #include <nlohmann/detail/exceptions.hpp>
12369 
12370 // #include <nlohmann/detail/macro_scope.hpp>
12371 
12372 // #include <nlohmann/detail/string_escape.hpp>
12373 
12374 // #include <nlohmann/detail/value_t.hpp>
12375 
12376 
12377 namespace nlohmann
12378 {
12379 template<typename BasicJsonType>
12380 class json_pointer
12381 {
12382     // allow basic_json to access private members
12383     NLOHMANN_BASIC_JSON_TPL_DECLARATION
12384     friend class basic_json;
12385 
12386   public:
12387     /*!
12388     @brief create JSON pointer
12389 
12390     Create a JSON pointer according to the syntax described in
12391     [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
12392 
12393     @param[in] s  string representing the JSON pointer; if omitted, the empty
12394                   string is assumed which references the whole JSON value
12395 
12396     @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
12397                            not begin with a slash (`/`); see example below
12398 
12399     @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
12400     not followed by `0` (representing `~`) or `1` (representing `/`); see
12401     example below
12402 
12403     @liveexample{The example shows the construction several valid JSON pointers
12404     as well as the exceptional behavior.,json_pointer}
12405 
12406     @since version 2.0.0
12407     */
json_pointer(const std::string & s="")12408     explicit json_pointer(const std::string& s = "")
12409         : reference_tokens(split(s))
12410     {}
12411 
12412     /*!
12413     @brief return a string representation of the JSON pointer
12414 
12415     @invariant For each JSON pointer `ptr`, it holds:
12416     @code {.cpp}
12417     ptr == json_pointer(ptr.to_string());
12418     @endcode
12419 
12420     @return a string representation of the JSON pointer
12421 
12422     @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
12423 
12424     @since version 2.0.0
12425     */
to_string() const12426     std::string to_string() const
12427     {
12428         return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12429                                std::string{},
12430                                [](const std::string & a, const std::string & b)
12431         {
12432             return a + "/" + detail::escape(b);
12433         });
12434     }
12435 
12436     /// @copydoc to_string()
operator std::string() const12437     operator std::string() const
12438     {
12439         return to_string();
12440     }
12441 
12442     /*!
12443     @brief append another JSON pointer at the end of this JSON pointer
12444 
12445     @param[in] ptr  JSON pointer to append
12446     @return JSON pointer with @a ptr appended
12447 
12448     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12449 
12450     @complexity Linear in the length of @a ptr.
12451 
12452     @sa see @ref operator/=(std::string) to append a reference token
12453     @sa see @ref operator/=(std::size_t) to append an array index
12454     @sa see @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
12455 
12456     @since version 3.6.0
12457     */
operator /=(const json_pointer & ptr)12458     json_pointer& operator/=(const json_pointer& ptr)
12459     {
12460         reference_tokens.insert(reference_tokens.end(),
12461                                 ptr.reference_tokens.begin(),
12462                                 ptr.reference_tokens.end());
12463         return *this;
12464     }
12465 
12466     /*!
12467     @brief append an unescaped reference token at the end of this JSON pointer
12468 
12469     @param[in] token  reference token to append
12470     @return JSON pointer with @a token appended without escaping @a token
12471 
12472     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12473 
12474     @complexity Amortized constant.
12475 
12476     @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12477     @sa see @ref operator/=(std::size_t) to append an array index
12478     @sa see @ref operator/(const json_pointer&, std::size_t) for a binary operator
12479 
12480     @since version 3.6.0
12481     */
operator /=(std::string token)12482     json_pointer& operator/=(std::string token)
12483     {
12484         push_back(std::move(token));
12485         return *this;
12486     }
12487 
12488     /*!
12489     @brief append an array index at the end of this JSON pointer
12490 
12491     @param[in] array_idx  array index to append
12492     @return JSON pointer with @a array_idx appended
12493 
12494     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12495 
12496     @complexity Amortized constant.
12497 
12498     @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12499     @sa see @ref operator/=(std::string) to append a reference token
12500     @sa see @ref operator/(const json_pointer&, std::string) for a binary operator
12501 
12502     @since version 3.6.0
12503     */
operator /=(std::size_t array_idx)12504     json_pointer& operator/=(std::size_t array_idx)
12505     {
12506         return *this /= std::to_string(array_idx);
12507     }
12508 
12509     /*!
12510     @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
12511 
12512     @param[in] lhs  JSON pointer
12513     @param[in] rhs  JSON pointer
12514     @return a new JSON pointer with @a rhs appended to @a lhs
12515 
12516     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12517 
12518     @complexity Linear in the length of @a lhs and @a rhs.
12519 
12520     @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12521 
12522     @since version 3.6.0
12523     */
operator /(const json_pointer & lhs,const json_pointer & rhs)12524     friend json_pointer operator/(const json_pointer& lhs,
12525                                   const json_pointer& rhs)
12526     {
12527         return json_pointer(lhs) /= rhs;
12528     }
12529 
12530     /*!
12531     @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
12532 
12533     @param[in] ptr  JSON pointer
12534     @param[in] token  reference token
12535     @return a new JSON pointer with unescaped @a token appended to @a ptr
12536 
12537     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12538 
12539     @complexity Linear in the length of @a ptr.
12540 
12541     @sa see @ref operator/=(std::string) to append a reference token
12542 
12543     @since version 3.6.0
12544     */
operator /(const json_pointer & ptr,std::string token)12545     friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param)
12546     {
12547         return json_pointer(ptr) /= std::move(token);
12548     }
12549 
12550     /*!
12551     @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
12552 
12553     @param[in] ptr  JSON pointer
12554     @param[in] array_idx  array index
12555     @return a new JSON pointer with @a array_idx appended to @a ptr
12556 
12557     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12558 
12559     @complexity Linear in the length of @a ptr.
12560 
12561     @sa see @ref operator/=(std::size_t) to append an array index
12562 
12563     @since version 3.6.0
12564     */
operator /(const json_pointer & ptr,std::size_t array_idx)12565     friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
12566     {
12567         return json_pointer(ptr) /= array_idx;
12568     }
12569 
12570     /*!
12571     @brief returns the parent of this JSON pointer
12572 
12573     @return parent of this JSON pointer; in case this JSON pointer is the root,
12574             the root itself is returned
12575 
12576     @complexity Linear in the length of the JSON pointer.
12577 
12578     @liveexample{The example shows the result of `parent_pointer` for different
12579     JSON Pointers.,json_pointer__parent_pointer}
12580 
12581     @since version 3.6.0
12582     */
parent_pointer() const12583     json_pointer parent_pointer() const
12584     {
12585         if (empty())
12586         {
12587             return *this;
12588         }
12589 
12590         json_pointer res = *this;
12591         res.pop_back();
12592         return res;
12593     }
12594 
12595     /*!
12596     @brief remove last reference token
12597 
12598     @pre not `empty()`
12599 
12600     @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
12601 
12602     @complexity Constant.
12603 
12604     @throw out_of_range.405 if JSON pointer has no parent
12605 
12606     @since version 3.6.0
12607     */
pop_back()12608     void pop_back()
12609     {
12610         if (JSON_HEDLEY_UNLIKELY(empty()))
12611         {
12612             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12613         }
12614 
12615         reference_tokens.pop_back();
12616     }
12617 
12618     /*!
12619     @brief return last reference token
12620 
12621     @pre not `empty()`
12622     @return last reference token
12623 
12624     @liveexample{The example shows the usage of `back`.,json_pointer__back}
12625 
12626     @complexity Constant.
12627 
12628     @throw out_of_range.405 if JSON pointer has no parent
12629 
12630     @since version 3.6.0
12631     */
back() const12632     const std::string& back() const
12633     {
12634         if (JSON_HEDLEY_UNLIKELY(empty()))
12635         {
12636             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12637         }
12638 
12639         return reference_tokens.back();
12640     }
12641 
12642     /*!
12643     @brief append an unescaped token at the end of the reference pointer
12644 
12645     @param[in] token  token to add
12646 
12647     @complexity Amortized constant.
12648 
12649     @liveexample{The example shows the result of `push_back` for different
12650     JSON Pointers.,json_pointer__push_back}
12651 
12652     @since version 3.6.0
12653     */
push_back(const std::string & token)12654     void push_back(const std::string& token)
12655     {
12656         reference_tokens.push_back(token);
12657     }
12658 
12659     /// @copydoc push_back(const std::string&)
push_back(std::string && token)12660     void push_back(std::string&& token)
12661     {
12662         reference_tokens.push_back(std::move(token));
12663     }
12664 
12665     /*!
12666     @brief return whether pointer points to the root document
12667 
12668     @return true iff the JSON pointer points to the root document
12669 
12670     @complexity Constant.
12671 
12672     @exceptionsafety No-throw guarantee: this function never throws exceptions.
12673 
12674     @liveexample{The example shows the result of `empty` for different JSON
12675     Pointers.,json_pointer__empty}
12676 
12677     @since version 3.6.0
12678     */
empty() const12679     bool empty() const noexcept
12680     {
12681         return reference_tokens.empty();
12682     }
12683 
12684   private:
12685     /*!
12686     @param[in] s  reference token to be converted into an array index
12687 
12688     @return integer representation of @a s
12689 
12690     @throw parse_error.106  if an array index begins with '0'
12691     @throw parse_error.109  if an array index begins not with a digit
12692     @throw out_of_range.404 if string @a s could not be converted to an integer
12693     @throw out_of_range.410 if an array index exceeds size_type
12694     */
array_index(const std::string & s)12695     static typename BasicJsonType::size_type array_index(const std::string& s)
12696     {
12697         using size_type = typename BasicJsonType::size_type;
12698 
12699         // error condition (cf. RFC 6901, Sect. 4)
12700         if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
12701         {
12702             JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
12703         }
12704 
12705         // error condition (cf. RFC 6901, Sect. 4)
12706         if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
12707         {
12708             JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
12709         }
12710 
12711         std::size_t processed_chars = 0;
12712         unsigned long long res = 0;  // NOLINT(runtime/int)
12713         JSON_TRY
12714         {
12715             res = std::stoull(s, &processed_chars);
12716         }
12717         JSON_CATCH(std::out_of_range&)
12718         {
12719             JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12720         }
12721 
12722         // check if the string was completely read
12723         if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
12724         {
12725             JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12726         }
12727 
12728         // only triggered on special platforms (like 32bit), see also
12729         // https://github.com/nlohmann/json/pull/2203
12730         if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))  // NOLINT(runtime/int)
12731         {
12732             JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
12733         }
12734 
12735         return static_cast<size_type>(res);
12736     }
12737 
12738   JSON_PRIVATE_UNLESS_TESTED:
12739     json_pointer top() const
12740     {
12741         if (JSON_HEDLEY_UNLIKELY(empty()))
12742         {
12743             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12744         }
12745 
12746         json_pointer result = *this;
12747         result.reference_tokens = {reference_tokens[0]};
12748         return result;
12749     }
12750 
12751   private:
12752     /*!
12753     @brief create and return a reference to the pointed to value
12754 
12755     @complexity Linear in the number of reference tokens.
12756 
12757     @throw parse_error.109 if array index is not a number
12758     @throw type_error.313 if value cannot be unflattened
12759     */
get_and_create(BasicJsonType & j) const12760     BasicJsonType& get_and_create(BasicJsonType& j) const
12761     {
12762         auto* result = &j;
12763 
12764         // in case no reference tokens exist, return a reference to the JSON value
12765         // j which will be overwritten by a primitive value
12766         for (const auto& reference_token : reference_tokens)
12767         {
12768             switch (result->type())
12769             {
12770                 case detail::value_t::null:
12771                 {
12772                     if (reference_token == "0")
12773                     {
12774                         // start a new array if reference token is 0
12775                         result = &result->operator[](0);
12776                     }
12777                     else
12778                     {
12779                         // start a new object otherwise
12780                         result = &result->operator[](reference_token);
12781                     }
12782                     break;
12783                 }
12784 
12785                 case detail::value_t::object:
12786                 {
12787                     // create an entry in the object
12788                     result = &result->operator[](reference_token);
12789                     break;
12790                 }
12791 
12792                 case detail::value_t::array:
12793                 {
12794                     // create an entry in the array
12795                     result = &result->operator[](array_index(reference_token));
12796                     break;
12797                 }
12798 
12799                 /*
12800                 The following code is only reached if there exists a reference
12801                 token _and_ the current value is primitive. In this case, we have
12802                 an error situation, because primitive values may only occur as
12803                 single value; that is, with an empty list of reference tokens.
12804                 */
12805                 case detail::value_t::string:
12806                 case detail::value_t::boolean:
12807                 case detail::value_t::number_integer:
12808                 case detail::value_t::number_unsigned:
12809                 case detail::value_t::number_float:
12810                 case detail::value_t::binary:
12811                 case detail::value_t::discarded:
12812                 default:
12813                     JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
12814             }
12815         }
12816 
12817         return *result;
12818     }
12819 
12820     /*!
12821     @brief return a reference to the pointed to value
12822 
12823     @note This version does not throw if a value is not present, but tries to
12824           create nested values instead. For instance, calling this function
12825           with pointer `"/this/that"` on a null value is equivalent to calling
12826           `operator[]("this").operator[]("that")` on that value, effectively
12827           changing the null value to an object.
12828 
12829     @param[in] ptr  a JSON value
12830 
12831     @return reference to the JSON value pointed to by the JSON pointer
12832 
12833     @complexity Linear in the length of the JSON pointer.
12834 
12835     @throw parse_error.106   if an array index begins with '0'
12836     @throw parse_error.109   if an array index was not a number
12837     @throw out_of_range.404  if the JSON pointer can not be resolved
12838     */
get_unchecked(BasicJsonType * ptr) const12839     BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12840     {
12841         for (const auto& reference_token : reference_tokens)
12842         {
12843             // convert null values to arrays or objects before continuing
12844             if (ptr->is_null())
12845             {
12846                 // check if reference token is a number
12847                 const bool nums =
12848                     std::all_of(reference_token.begin(), reference_token.end(),
12849                                 [](const unsigned char x)
12850                 {
12851                     return std::isdigit(x);
12852                 });
12853 
12854                 // change value to array for numbers or "-" or to object otherwise
12855                 *ptr = (nums || reference_token == "-")
12856                        ? detail::value_t::array
12857                        : detail::value_t::object;
12858             }
12859 
12860             switch (ptr->type())
12861             {
12862                 case detail::value_t::object:
12863                 {
12864                     // use unchecked object access
12865                     ptr = &ptr->operator[](reference_token);
12866                     break;
12867                 }
12868 
12869                 case detail::value_t::array:
12870                 {
12871                     if (reference_token == "-")
12872                     {
12873                         // explicitly treat "-" as index beyond the end
12874                         ptr = &ptr->operator[](ptr->m_value.array->size());
12875                     }
12876                     else
12877                     {
12878                         // convert array index to number; unchecked access
12879                         ptr = &ptr->operator[](array_index(reference_token));
12880                     }
12881                     break;
12882                 }
12883 
12884                 case detail::value_t::null:
12885                 case detail::value_t::string:
12886                 case detail::value_t::boolean:
12887                 case detail::value_t::number_integer:
12888                 case detail::value_t::number_unsigned:
12889                 case detail::value_t::number_float:
12890                 case detail::value_t::binary:
12891                 case detail::value_t::discarded:
12892                 default:
12893                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12894             }
12895         }
12896 
12897         return *ptr;
12898     }
12899 
12900     /*!
12901     @throw parse_error.106   if an array index begins with '0'
12902     @throw parse_error.109   if an array index was not a number
12903     @throw out_of_range.402  if the array index '-' is used
12904     @throw out_of_range.404  if the JSON pointer can not be resolved
12905     */
get_checked(BasicJsonType * ptr) const12906     BasicJsonType& get_checked(BasicJsonType* ptr) const
12907     {
12908         for (const auto& reference_token : reference_tokens)
12909         {
12910             switch (ptr->type())
12911             {
12912                 case detail::value_t::object:
12913                 {
12914                     // note: at performs range check
12915                     ptr = &ptr->at(reference_token);
12916                     break;
12917                 }
12918 
12919                 case detail::value_t::array:
12920                 {
12921                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12922                     {
12923                         // "-" always fails the range check
12924                         JSON_THROW(detail::out_of_range::create(402,
12925                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12926                                                                 ") is out of range", *ptr));
12927                     }
12928 
12929                     // note: at performs range check
12930                     ptr = &ptr->at(array_index(reference_token));
12931                     break;
12932                 }
12933 
12934                 case detail::value_t::null:
12935                 case detail::value_t::string:
12936                 case detail::value_t::boolean:
12937                 case detail::value_t::number_integer:
12938                 case detail::value_t::number_unsigned:
12939                 case detail::value_t::number_float:
12940                 case detail::value_t::binary:
12941                 case detail::value_t::discarded:
12942                 default:
12943                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12944             }
12945         }
12946 
12947         return *ptr;
12948     }
12949 
12950     /*!
12951     @brief return a const reference to the pointed to value
12952 
12953     @param[in] ptr  a JSON value
12954 
12955     @return const reference to the JSON value pointed to by the JSON
12956     pointer
12957 
12958     @throw parse_error.106   if an array index begins with '0'
12959     @throw parse_error.109   if an array index was not a number
12960     @throw out_of_range.402  if the array index '-' is used
12961     @throw out_of_range.404  if the JSON pointer can not be resolved
12962     */
get_unchecked(const BasicJsonType * ptr) const12963     const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
12964     {
12965         for (const auto& reference_token : reference_tokens)
12966         {
12967             switch (ptr->type())
12968             {
12969                 case detail::value_t::object:
12970                 {
12971                     // use unchecked object access
12972                     ptr = &ptr->operator[](reference_token);
12973                     break;
12974                 }
12975 
12976                 case detail::value_t::array:
12977                 {
12978                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12979                     {
12980                         // "-" cannot be used for const access
12981                         JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
12982                     }
12983 
12984                     // use unchecked array access
12985                     ptr = &ptr->operator[](array_index(reference_token));
12986                     break;
12987                 }
12988 
12989                 case detail::value_t::null:
12990                 case detail::value_t::string:
12991                 case detail::value_t::boolean:
12992                 case detail::value_t::number_integer:
12993                 case detail::value_t::number_unsigned:
12994                 case detail::value_t::number_float:
12995                 case detail::value_t::binary:
12996                 case detail::value_t::discarded:
12997                 default:
12998                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12999             }
13000         }
13001 
13002         return *ptr;
13003     }
13004 
13005     /*!
13006     @throw parse_error.106   if an array index begins with '0'
13007     @throw parse_error.109   if an array index was not a number
13008     @throw out_of_range.402  if the array index '-' is used
13009     @throw out_of_range.404  if the JSON pointer can not be resolved
13010     */
get_checked(const BasicJsonType * ptr) const13011     const BasicJsonType& get_checked(const BasicJsonType* ptr) const
13012     {
13013         for (const auto& reference_token : reference_tokens)
13014         {
13015             switch (ptr->type())
13016             {
13017                 case detail::value_t::object:
13018                 {
13019                     // note: at performs range check
13020                     ptr = &ptr->at(reference_token);
13021                     break;
13022                 }
13023 
13024                 case detail::value_t::array:
13025                 {
13026                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13027                     {
13028                         // "-" always fails the range check
13029                         JSON_THROW(detail::out_of_range::create(402,
13030                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13031                                                                 ") is out of range", *ptr));
13032                     }
13033 
13034                     // note: at performs range check
13035                     ptr = &ptr->at(array_index(reference_token));
13036                     break;
13037                 }
13038 
13039                 case detail::value_t::null:
13040                 case detail::value_t::string:
13041                 case detail::value_t::boolean:
13042                 case detail::value_t::number_integer:
13043                 case detail::value_t::number_unsigned:
13044                 case detail::value_t::number_float:
13045                 case detail::value_t::binary:
13046                 case detail::value_t::discarded:
13047                 default:
13048                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13049             }
13050         }
13051 
13052         return *ptr;
13053     }
13054 
13055     /*!
13056     @throw parse_error.106   if an array index begins with '0'
13057     @throw parse_error.109   if an array index was not a number
13058     */
contains(const BasicJsonType * ptr) const13059     bool contains(const BasicJsonType* ptr) const
13060     {
13061         for (const auto& reference_token : reference_tokens)
13062         {
13063             switch (ptr->type())
13064             {
13065                 case detail::value_t::object:
13066                 {
13067                     if (!ptr->contains(reference_token))
13068                     {
13069                         // we did not find the key in the object
13070                         return false;
13071                     }
13072 
13073                     ptr = &ptr->operator[](reference_token);
13074                     break;
13075                 }
13076 
13077                 case detail::value_t::array:
13078                 {
13079                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13080                     {
13081                         // "-" always fails the range check
13082                         return false;
13083                     }
13084                     if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13085                     {
13086                         // invalid char
13087                         return false;
13088                     }
13089                     if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
13090                     {
13091                         if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13092                         {
13093                             // first char should be between '1' and '9'
13094                             return false;
13095                         }
13096                         for (std::size_t i = 1; i < reference_token.size(); i++)
13097                         {
13098                             if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13099                             {
13100                                 // other char should be between '0' and '9'
13101                                 return false;
13102                             }
13103                         }
13104                     }
13105 
13106                     const auto idx = array_index(reference_token);
13107                     if (idx >= ptr->size())
13108                     {
13109                         // index out of range
13110                         return false;
13111                     }
13112 
13113                     ptr = &ptr->operator[](idx);
13114                     break;
13115                 }
13116 
13117                 case detail::value_t::null:
13118                 case detail::value_t::string:
13119                 case detail::value_t::boolean:
13120                 case detail::value_t::number_integer:
13121                 case detail::value_t::number_unsigned:
13122                 case detail::value_t::number_float:
13123                 case detail::value_t::binary:
13124                 case detail::value_t::discarded:
13125                 default:
13126                 {
13127                     // we do not expect primitive values if there is still a
13128                     // reference token to process
13129                     return false;
13130                 }
13131             }
13132         }
13133 
13134         // no reference token left means we found a primitive value
13135         return true;
13136     }
13137 
13138     /*!
13139     @brief split the string input to reference tokens
13140 
13141     @note This function is only called by the json_pointer constructor.
13142           All exceptions below are documented there.
13143 
13144     @throw parse_error.107  if the pointer is not empty or begins with '/'
13145     @throw parse_error.108  if character '~' is not followed by '0' or '1'
13146     */
split(const std::string & reference_string)13147     static std::vector<std::string> split(const std::string& reference_string)
13148     {
13149         std::vector<std::string> result;
13150 
13151         // special case: empty reference string -> no reference tokens
13152         if (reference_string.empty())
13153         {
13154             return result;
13155         }
13156 
13157         // check if nonempty reference string begins with slash
13158         if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
13159         {
13160             JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
13161         }
13162 
13163         // extract the reference tokens:
13164         // - slash: position of the last read slash (or end of string)
13165         // - start: position after the previous slash
13166         for (
13167             // search for the first slash after the first character
13168             std::size_t slash = reference_string.find_first_of('/', 1),
13169             // set the beginning of the first reference token
13170             start = 1;
13171             // we can stop if start == 0 (if slash == std::string::npos)
13172             start != 0;
13173             // set the beginning of the next reference token
13174             // (will eventually be 0 if slash == std::string::npos)
13175             start = (slash == std::string::npos) ? 0 : slash + 1,
13176             // find next slash
13177             slash = reference_string.find_first_of('/', start))
13178         {
13179             // use the text between the beginning of the reference token
13180             // (start) and the last slash (slash).
13181             auto reference_token = reference_string.substr(start, slash - start);
13182 
13183             // check reference tokens are properly escaped
13184             for (std::size_t pos = reference_token.find_first_of('~');
13185                     pos != std::string::npos;
13186                     pos = reference_token.find_first_of('~', pos + 1))
13187             {
13188                 JSON_ASSERT(reference_token[pos] == '~');
13189 
13190                 // ~ must be followed by 0 or 1
13191                 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
13192                                          (reference_token[pos + 1] != '0' &&
13193                                           reference_token[pos + 1] != '1')))
13194                 {
13195                     JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
13196                 }
13197             }
13198 
13199             // finally, store the reference token
13200             detail::unescape(reference_token);
13201             result.push_back(reference_token);
13202         }
13203 
13204         return result;
13205     }
13206 
13207   private:
13208     /*!
13209     @param[in] reference_string  the reference string to the current value
13210     @param[in] value             the value to consider
13211     @param[in,out] result        the result object to insert values to
13212 
13213     @note Empty objects or arrays are flattened to `null`.
13214     */
flatten(const std::string & reference_string,const BasicJsonType & value,BasicJsonType & result)13215     static void flatten(const std::string& reference_string,
13216                         const BasicJsonType& value,
13217                         BasicJsonType& result)
13218     {
13219         switch (value.type())
13220         {
13221             case detail::value_t::array:
13222             {
13223                 if (value.m_value.array->empty())
13224                 {
13225                     // flatten empty array as null
13226                     result[reference_string] = nullptr;
13227                 }
13228                 else
13229                 {
13230                     // iterate array and use index as reference string
13231                     for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13232                     {
13233                         flatten(reference_string + "/" + std::to_string(i),
13234                                 value.m_value.array->operator[](i), result);
13235                     }
13236                 }
13237                 break;
13238             }
13239 
13240             case detail::value_t::object:
13241             {
13242                 if (value.m_value.object->empty())
13243                 {
13244                     // flatten empty object as null
13245                     result[reference_string] = nullptr;
13246                 }
13247                 else
13248                 {
13249                     // iterate object and use keys as reference string
13250                     for (const auto& element : *value.m_value.object)
13251                     {
13252                         flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
13253                     }
13254                 }
13255                 break;
13256             }
13257 
13258             case detail::value_t::null:
13259             case detail::value_t::string:
13260             case detail::value_t::boolean:
13261             case detail::value_t::number_integer:
13262             case detail::value_t::number_unsigned:
13263             case detail::value_t::number_float:
13264             case detail::value_t::binary:
13265             case detail::value_t::discarded:
13266             default:
13267             {
13268                 // add primitive value with its reference string
13269                 result[reference_string] = value;
13270                 break;
13271             }
13272         }
13273     }
13274 
13275     /*!
13276     @param[in] value  flattened JSON
13277 
13278     @return unflattened JSON
13279 
13280     @throw parse_error.109 if array index is not a number
13281     @throw type_error.314  if value is not an object
13282     @throw type_error.315  if object values are not primitive
13283     @throw type_error.313  if value cannot be unflattened
13284     */
13285     static BasicJsonType
unflatten(const BasicJsonType & value)13286     unflatten(const BasicJsonType& value)
13287     {
13288         if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
13289         {
13290             JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
13291         }
13292 
13293         BasicJsonType result;
13294 
13295         // iterate the JSON object values
13296         for (const auto& element : *value.m_value.object)
13297         {
13298             if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
13299             {
13300                 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
13301             }
13302 
13303             // assign value to reference pointed to by JSON pointer; Note that if
13304             // the JSON pointer is "" (i.e., points to the whole value), function
13305             // get_and_create returns a reference to result itself. An assignment
13306             // will then create a primitive value.
13307             json_pointer(element.first).get_and_create(result) = element.second;
13308         }
13309 
13310         return result;
13311     }
13312 
13313     /*!
13314     @brief compares two JSON pointers for equality
13315 
13316     @param[in] lhs  JSON pointer to compare
13317     @param[in] rhs  JSON pointer to compare
13318     @return whether @a lhs is equal to @a rhs
13319 
13320     @complexity Linear in the length of the JSON pointer
13321 
13322     @exceptionsafety No-throw guarantee: this function never throws exceptions.
13323     */
operator ==(json_pointer const & lhs,json_pointer const & rhs)13324     friend bool operator==(json_pointer const& lhs,
13325                            json_pointer const& rhs) noexcept
13326     {
13327         return lhs.reference_tokens == rhs.reference_tokens;
13328     }
13329 
13330     /*!
13331     @brief compares two JSON pointers for inequality
13332 
13333     @param[in] lhs  JSON pointer to compare
13334     @param[in] rhs  JSON pointer to compare
13335     @return whether @a lhs is not equal @a rhs
13336 
13337     @complexity Linear in the length of the JSON pointer
13338 
13339     @exceptionsafety No-throw guarantee: this function never throws exceptions.
13340     */
operator !=(json_pointer const & lhs,json_pointer const & rhs)13341     friend bool operator!=(json_pointer const& lhs,
13342                            json_pointer const& rhs) noexcept
13343     {
13344         return !(lhs == rhs);
13345     }
13346 
13347     /// the reference tokens
13348     std::vector<std::string> reference_tokens;
13349 };
13350 }  // namespace nlohmann
13351 
13352 // #include <nlohmann/detail/json_ref.hpp>
13353 
13354 
13355 #include <initializer_list>
13356 #include <utility>
13357 
13358 // #include <nlohmann/detail/meta/type_traits.hpp>
13359 
13360 
13361 namespace nlohmann
13362 {
13363 namespace detail
13364 {
13365 template<typename BasicJsonType>
13366 class json_ref
13367 {
13368   public:
13369     using value_type = BasicJsonType;
13370 
json_ref(value_type && value)13371     json_ref(value_type&& value)
13372         : owned_value(std::move(value))
13373     {}
13374 
json_ref(const value_type & value)13375     json_ref(const value_type& value)
13376         : value_ref(&value)
13377     {}
13378 
json_ref(std::initializer_list<json_ref> init)13379     json_ref(std::initializer_list<json_ref> init)
13380         : owned_value(init)
13381     {}
13382 
13383     template <
13384         class... Args,
13385         enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
json_ref(Args &&...args)13386     json_ref(Args && ... args)
13387         : owned_value(std::forward<Args>(args)...)
13388     {}
13389 
13390     // class should be movable only
13391     json_ref(json_ref&&) noexcept = default;
13392     json_ref(const json_ref&) = delete;
13393     json_ref& operator=(const json_ref&) = delete;
13394     json_ref& operator=(json_ref&&) = delete;
13395     ~json_ref() = default;
13396 
moved_or_copied() const13397     value_type moved_or_copied() const
13398     {
13399         if (value_ref == nullptr)
13400         {
13401             return std::move(owned_value);
13402         }
13403         return *value_ref;
13404     }
13405 
operator *() const13406     value_type const& operator*() const
13407     {
13408         return value_ref ? *value_ref : owned_value;
13409     }
13410 
operator ->() const13411     value_type const* operator->() const
13412     {
13413         return &** this;
13414     }
13415 
13416   private:
13417     mutable value_type owned_value = nullptr;
13418     value_type const* value_ref = nullptr;
13419 };
13420 }  // namespace detail
13421 }  // namespace nlohmann
13422 
13423 // #include <nlohmann/detail/macro_scope.hpp>
13424 
13425 // #include <nlohmann/detail/string_escape.hpp>
13426 
13427 // #include <nlohmann/detail/meta/cpp_future.hpp>
13428 
13429 // #include <nlohmann/detail/meta/type_traits.hpp>
13430 
13431 // #include <nlohmann/detail/output/binary_writer.hpp>
13432 
13433 
13434 #include <algorithm> // reverse
13435 #include <array> // array
13436 #include <cmath> // isnan, isinf
13437 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13438 #include <cstring> // memcpy
13439 #include <limits> // numeric_limits
13440 #include <string> // string
13441 #include <utility> // move
13442 
13443 // #include <nlohmann/detail/input/binary_reader.hpp>
13444 
13445 // #include <nlohmann/detail/macro_scope.hpp>
13446 
13447 // #include <nlohmann/detail/output/output_adapters.hpp>
13448 
13449 
13450 #include <algorithm> // copy
13451 #include <cstddef> // size_t
13452 #include <iterator> // back_inserter
13453 #include <memory> // shared_ptr, make_shared
13454 #include <string> // basic_string
13455 #include <vector> // vector
13456 
13457 #ifndef JSON_NO_IO
13458     #include <ios>      // streamsize
13459     #include <ostream>  // basic_ostream
13460 #endif  // JSON_NO_IO
13461 
13462 // #include <nlohmann/detail/macro_scope.hpp>
13463 
13464 
13465 namespace nlohmann
13466 {
13467 namespace detail
13468 {
13469 /// abstract output adapter interface
13470 template<typename CharType> struct output_adapter_protocol
13471 {
13472     virtual void write_character(CharType c) = 0;
13473     virtual void write_characters(const CharType* s, std::size_t length) = 0;
13474     virtual ~output_adapter_protocol() = default;
13475 
13476     output_adapter_protocol() = default;
13477     output_adapter_protocol(const output_adapter_protocol&) = default;
13478     output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
13479     output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
13480     output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
13481 };
13482 
13483 /// a type to simplify interfaces
13484 template<typename CharType>
13485 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13486 
13487 /// output adapter for byte vectors
13488 template<typename CharType>
13489 class output_vector_adapter : public output_adapter_protocol<CharType>
13490 {
13491   public:
output_vector_adapter(std::vector<CharType> & vec)13492     explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
13493         : v(vec)
13494     {}
13495 
write_character(CharType c)13496     void write_character(CharType c) override
13497     {
13498         v.push_back(c);
13499     }
13500 
13501     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)13502     void write_characters(const CharType* s, std::size_t length) override
13503     {
13504         std::copy(s, s + length, std::back_inserter(v));
13505     }
13506 
13507   private:
13508     std::vector<CharType>& v;
13509 };
13510 
13511 #ifndef JSON_NO_IO
13512 /// output adapter for output streams
13513 template<typename CharType>
13514 class output_stream_adapter : public output_adapter_protocol<CharType>
13515 {
13516   public:
output_stream_adapter(std::basic_ostream<CharType> & s)13517     explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13518         : stream(s)
13519     {}
13520 
write_character(CharType c)13521     void write_character(CharType c) override
13522     {
13523         stream.put(c);
13524     }
13525 
13526     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)13527     void write_characters(const CharType* s, std::size_t length) override
13528     {
13529         stream.write(s, static_cast<std::streamsize>(length));
13530     }
13531 
13532   private:
13533     std::basic_ostream<CharType>& stream;
13534 };
13535 #endif  // JSON_NO_IO
13536 
13537 /// output adapter for basic_string
13538 template<typename CharType, typename StringType = std::basic_string<CharType>>
13539 class output_string_adapter : public output_adapter_protocol<CharType>
13540 {
13541   public:
output_string_adapter(StringType & s)13542     explicit output_string_adapter(StringType& s) noexcept
13543         : str(s)
13544     {}
13545 
write_character(CharType c)13546     void write_character(CharType c) override
13547     {
13548         str.push_back(c);
13549     }
13550 
13551     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)13552     void write_characters(const CharType* s, std::size_t length) override
13553     {
13554         str.append(s, length);
13555     }
13556 
13557   private:
13558     StringType& str;
13559 };
13560 
13561 template<typename CharType, typename StringType = std::basic_string<CharType>>
13562 class output_adapter
13563 {
13564   public:
output_adapter(std::vector<CharType> & vec)13565     output_adapter(std::vector<CharType>& vec)
13566         : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
13567 
13568 #ifndef JSON_NO_IO
output_adapter(std::basic_ostream<CharType> & s)13569     output_adapter(std::basic_ostream<CharType>& s)
13570         : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
13571 #endif  // JSON_NO_IO
13572 
output_adapter(StringType & s)13573     output_adapter(StringType& s)
13574         : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
13575 
operator output_adapter_t<CharType>()13576     operator output_adapter_t<CharType>()
13577     {
13578         return oa;
13579     }
13580 
13581   private:
13582     output_adapter_t<CharType> oa = nullptr;
13583 };
13584 }  // namespace detail
13585 }  // namespace nlohmann
13586 
13587 
13588 namespace nlohmann
13589 {
13590 namespace detail
13591 {
13592 ///////////////////
13593 // binary writer //
13594 ///////////////////
13595 
13596 /*!
13597 @brief serialization to CBOR and MessagePack values
13598 */
13599 template<typename BasicJsonType, typename CharType>
13600 class binary_writer
13601 {
13602     using string_t = typename BasicJsonType::string_t;
13603     using binary_t = typename BasicJsonType::binary_t;
13604     using number_float_t = typename BasicJsonType::number_float_t;
13605 
13606   public:
13607     /*!
13608     @brief create a binary writer
13609 
13610     @param[in] adapter  output adapter to write to
13611     */
binary_writer(output_adapter_t<CharType> adapter)13612     explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
13613     {
13614         JSON_ASSERT(oa);
13615     }
13616 
13617     /*!
13618     @param[in] j  JSON value to serialize
13619     @pre       j.type() == value_t::object
13620     */
write_bson(const BasicJsonType & j)13621     void write_bson(const BasicJsonType& j)
13622     {
13623         switch (j.type())
13624         {
13625             case value_t::object:
13626             {
13627                 write_bson_object(*j.m_value.object);
13628                 break;
13629             }
13630 
13631             case value_t::null:
13632             case value_t::array:
13633             case value_t::string:
13634             case value_t::boolean:
13635             case value_t::number_integer:
13636             case value_t::number_unsigned:
13637             case value_t::number_float:
13638             case value_t::binary:
13639             case value_t::discarded:
13640             default:
13641             {
13642                 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));
13643             }
13644         }
13645     }
13646 
13647     /*!
13648     @param[in] j  JSON value to serialize
13649     */
write_cbor(const BasicJsonType & j)13650     void write_cbor(const BasicJsonType& j)
13651     {
13652         switch (j.type())
13653         {
13654             case value_t::null:
13655             {
13656                 oa->write_character(to_char_type(0xF6));
13657                 break;
13658             }
13659 
13660             case value_t::boolean:
13661             {
13662                 oa->write_character(j.m_value.boolean
13663                                     ? to_char_type(0xF5)
13664                                     : to_char_type(0xF4));
13665                 break;
13666             }
13667 
13668             case value_t::number_integer:
13669             {
13670                 if (j.m_value.number_integer >= 0)
13671                 {
13672                     // CBOR does not differentiate between positive signed
13673                     // integers and unsigned integers. Therefore, we used the
13674                     // code from the value_t::number_unsigned case here.
13675                     if (j.m_value.number_integer <= 0x17)
13676                     {
13677                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13678                     }
13679                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13680                     {
13681                         oa->write_character(to_char_type(0x18));
13682                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13683                     }
13684                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
13685                     {
13686                         oa->write_character(to_char_type(0x19));
13687                         write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13688                     }
13689                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
13690                     {
13691                         oa->write_character(to_char_type(0x1A));
13692                         write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13693                     }
13694                     else
13695                     {
13696                         oa->write_character(to_char_type(0x1B));
13697                         write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13698                     }
13699                 }
13700                 else
13701                 {
13702                     // The conversions below encode the sign in the first
13703                     // byte, and the value is converted to a positive number.
13704                     const auto positive_number = -1 - j.m_value.number_integer;
13705                     if (j.m_value.number_integer >= -24)
13706                     {
13707                         write_number(static_cast<std::uint8_t>(0x20 + positive_number));
13708                     }
13709                     else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
13710                     {
13711                         oa->write_character(to_char_type(0x38));
13712                         write_number(static_cast<std::uint8_t>(positive_number));
13713                     }
13714                     else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
13715                     {
13716                         oa->write_character(to_char_type(0x39));
13717                         write_number(static_cast<std::uint16_t>(positive_number));
13718                     }
13719                     else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
13720                     {
13721                         oa->write_character(to_char_type(0x3A));
13722                         write_number(static_cast<std::uint32_t>(positive_number));
13723                     }
13724                     else
13725                     {
13726                         oa->write_character(to_char_type(0x3B));
13727                         write_number(static_cast<std::uint64_t>(positive_number));
13728                     }
13729                 }
13730                 break;
13731             }
13732 
13733             case value_t::number_unsigned:
13734             {
13735                 if (j.m_value.number_unsigned <= 0x17)
13736                 {
13737                     write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13738                 }
13739                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13740                 {
13741                     oa->write_character(to_char_type(0x18));
13742                     write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13743                 }
13744                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13745                 {
13746                     oa->write_character(to_char_type(0x19));
13747                     write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
13748                 }
13749                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13750                 {
13751                     oa->write_character(to_char_type(0x1A));
13752                     write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
13753                 }
13754                 else
13755                 {
13756                     oa->write_character(to_char_type(0x1B));
13757                     write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
13758                 }
13759                 break;
13760             }
13761 
13762             case value_t::number_float:
13763             {
13764                 if (std::isnan(j.m_value.number_float))
13765                 {
13766                     // NaN is 0xf97e00 in CBOR
13767                     oa->write_character(to_char_type(0xF9));
13768                     oa->write_character(to_char_type(0x7E));
13769                     oa->write_character(to_char_type(0x00));
13770                 }
13771                 else if (std::isinf(j.m_value.number_float))
13772                 {
13773                     // Infinity is 0xf97c00, -Infinity is 0xf9fc00
13774                     oa->write_character(to_char_type(0xf9));
13775                     oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
13776                     oa->write_character(to_char_type(0x00));
13777                 }
13778                 else
13779                 {
13780                     write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
13781                 }
13782                 break;
13783             }
13784 
13785             case value_t::string:
13786             {
13787                 // step 1: write control byte and the string length
13788                 const auto N = j.m_value.string->size();
13789                 if (N <= 0x17)
13790                 {
13791                     write_number(static_cast<std::uint8_t>(0x60 + N));
13792                 }
13793                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13794                 {
13795                     oa->write_character(to_char_type(0x78));
13796                     write_number(static_cast<std::uint8_t>(N));
13797                 }
13798                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13799                 {
13800                     oa->write_character(to_char_type(0x79));
13801                     write_number(static_cast<std::uint16_t>(N));
13802                 }
13803                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13804                 {
13805                     oa->write_character(to_char_type(0x7A));
13806                     write_number(static_cast<std::uint32_t>(N));
13807                 }
13808                 // LCOV_EXCL_START
13809                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13810                 {
13811                     oa->write_character(to_char_type(0x7B));
13812                     write_number(static_cast<std::uint64_t>(N));
13813                 }
13814                 // LCOV_EXCL_STOP
13815 
13816                 // step 2: write the string
13817                 oa->write_characters(
13818                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13819                     j.m_value.string->size());
13820                 break;
13821             }
13822 
13823             case value_t::array:
13824             {
13825                 // step 1: write control byte and the array size
13826                 const auto N = j.m_value.array->size();
13827                 if (N <= 0x17)
13828                 {
13829                     write_number(static_cast<std::uint8_t>(0x80 + N));
13830                 }
13831                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13832                 {
13833                     oa->write_character(to_char_type(0x98));
13834                     write_number(static_cast<std::uint8_t>(N));
13835                 }
13836                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13837                 {
13838                     oa->write_character(to_char_type(0x99));
13839                     write_number(static_cast<std::uint16_t>(N));
13840                 }
13841                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13842                 {
13843                     oa->write_character(to_char_type(0x9A));
13844                     write_number(static_cast<std::uint32_t>(N));
13845                 }
13846                 // LCOV_EXCL_START
13847                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13848                 {
13849                     oa->write_character(to_char_type(0x9B));
13850                     write_number(static_cast<std::uint64_t>(N));
13851                 }
13852                 // LCOV_EXCL_STOP
13853 
13854                 // step 2: write each element
13855                 for (const auto& el : *j.m_value.array)
13856                 {
13857                     write_cbor(el);
13858                 }
13859                 break;
13860             }
13861 
13862             case value_t::binary:
13863             {
13864                 if (j.m_value.binary->has_subtype())
13865                 {
13866                     if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
13867                     {
13868                         write_number(static_cast<std::uint8_t>(0xd8));
13869                         write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
13870                     }
13871                     else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
13872                     {
13873                         write_number(static_cast<std::uint8_t>(0xd9));
13874                         write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
13875                     }
13876                     else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
13877                     {
13878                         write_number(static_cast<std::uint8_t>(0xda));
13879                         write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
13880                     }
13881                     else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
13882                     {
13883                         write_number(static_cast<std::uint8_t>(0xdb));
13884                         write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
13885                     }
13886                 }
13887 
13888                 // step 1: write control byte and the binary array size
13889                 const auto N = j.m_value.binary->size();
13890                 if (N <= 0x17)
13891                 {
13892                     write_number(static_cast<std::uint8_t>(0x40 + N));
13893                 }
13894                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13895                 {
13896                     oa->write_character(to_char_type(0x58));
13897                     write_number(static_cast<std::uint8_t>(N));
13898                 }
13899                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13900                 {
13901                     oa->write_character(to_char_type(0x59));
13902                     write_number(static_cast<std::uint16_t>(N));
13903                 }
13904                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13905                 {
13906                     oa->write_character(to_char_type(0x5A));
13907                     write_number(static_cast<std::uint32_t>(N));
13908                 }
13909                 // LCOV_EXCL_START
13910                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13911                 {
13912                     oa->write_character(to_char_type(0x5B));
13913                     write_number(static_cast<std::uint64_t>(N));
13914                 }
13915                 // LCOV_EXCL_STOP
13916 
13917                 // step 2: write each element
13918                 oa->write_characters(
13919                     reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13920                     N);
13921 
13922                 break;
13923             }
13924 
13925             case value_t::object:
13926             {
13927                 // step 1: write control byte and the object size
13928                 const auto N = j.m_value.object->size();
13929                 if (N <= 0x17)
13930                 {
13931                     write_number(static_cast<std::uint8_t>(0xA0 + N));
13932                 }
13933                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13934                 {
13935                     oa->write_character(to_char_type(0xB8));
13936                     write_number(static_cast<std::uint8_t>(N));
13937                 }
13938                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13939                 {
13940                     oa->write_character(to_char_type(0xB9));
13941                     write_number(static_cast<std::uint16_t>(N));
13942                 }
13943                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13944                 {
13945                     oa->write_character(to_char_type(0xBA));
13946                     write_number(static_cast<std::uint32_t>(N));
13947                 }
13948                 // LCOV_EXCL_START
13949                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13950                 {
13951                     oa->write_character(to_char_type(0xBB));
13952                     write_number(static_cast<std::uint64_t>(N));
13953                 }
13954                 // LCOV_EXCL_STOP
13955 
13956                 // step 2: write each element
13957                 for (const auto& el : *j.m_value.object)
13958                 {
13959                     write_cbor(el.first);
13960                     write_cbor(el.second);
13961                 }
13962                 break;
13963             }
13964 
13965             case value_t::discarded:
13966             default:
13967                 break;
13968         }
13969     }
13970 
13971     /*!
13972     @param[in] j  JSON value to serialize
13973     */
write_msgpack(const BasicJsonType & j)13974     void write_msgpack(const BasicJsonType& j)
13975     {
13976         switch (j.type())
13977         {
13978             case value_t::null: // nil
13979             {
13980                 oa->write_character(to_char_type(0xC0));
13981                 break;
13982             }
13983 
13984             case value_t::boolean: // true and false
13985             {
13986                 oa->write_character(j.m_value.boolean
13987                                     ? to_char_type(0xC3)
13988                                     : to_char_type(0xC2));
13989                 break;
13990             }
13991 
13992             case value_t::number_integer:
13993             {
13994                 if (j.m_value.number_integer >= 0)
13995                 {
13996                     // MessagePack does not differentiate between positive
13997                     // signed integers and unsigned integers. Therefore, we used
13998                     // the code from the value_t::number_unsigned case here.
13999                     if (j.m_value.number_unsigned < 128)
14000                     {
14001                         // positive fixnum
14002                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14003                     }
14004                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14005                     {
14006                         // uint 8
14007                         oa->write_character(to_char_type(0xCC));
14008                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14009                     }
14010                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14011                     {
14012                         // uint 16
14013                         oa->write_character(to_char_type(0xCD));
14014                         write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14015                     }
14016                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14017                     {
14018                         // uint 32
14019                         oa->write_character(to_char_type(0xCE));
14020                         write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14021                     }
14022                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14023                     {
14024                         // uint 64
14025                         oa->write_character(to_char_type(0xCF));
14026                         write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14027                     }
14028                 }
14029                 else
14030                 {
14031                     if (j.m_value.number_integer >= -32)
14032                     {
14033                         // negative fixnum
14034                         write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14035                     }
14036                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14037                              j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14038                     {
14039                         // int 8
14040                         oa->write_character(to_char_type(0xD0));
14041                         write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14042                     }
14043                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14044                              j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14045                     {
14046                         // int 16
14047                         oa->write_character(to_char_type(0xD1));
14048                         write_number(static_cast<std::int16_t>(j.m_value.number_integer));
14049                     }
14050                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14051                              j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14052                     {
14053                         // int 32
14054                         oa->write_character(to_char_type(0xD2));
14055                         write_number(static_cast<std::int32_t>(j.m_value.number_integer));
14056                     }
14057                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14058                              j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14059                     {
14060                         // int 64
14061                         oa->write_character(to_char_type(0xD3));
14062                         write_number(static_cast<std::int64_t>(j.m_value.number_integer));
14063                     }
14064                 }
14065                 break;
14066             }
14067 
14068             case value_t::number_unsigned:
14069             {
14070                 if (j.m_value.number_unsigned < 128)
14071                 {
14072                     // positive fixnum
14073                     write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14074                 }
14075                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14076                 {
14077                     // uint 8
14078                     oa->write_character(to_char_type(0xCC));
14079                     write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14080                 }
14081                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14082                 {
14083                     // uint 16
14084                     oa->write_character(to_char_type(0xCD));
14085                     write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14086                 }
14087                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14088                 {
14089                     // uint 32
14090                     oa->write_character(to_char_type(0xCE));
14091                     write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14092                 }
14093                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14094                 {
14095                     // uint 64
14096                     oa->write_character(to_char_type(0xCF));
14097                     write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14098                 }
14099                 break;
14100             }
14101 
14102             case value_t::number_float:
14103             {
14104                 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
14105                 break;
14106             }
14107 
14108             case value_t::string:
14109             {
14110                 // step 1: write control byte and the string length
14111                 const auto N = j.m_value.string->size();
14112                 if (N <= 31)
14113                 {
14114                     // fixstr
14115                     write_number(static_cast<std::uint8_t>(0xA0 | N));
14116                 }
14117                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14118                 {
14119                     // str 8
14120                     oa->write_character(to_char_type(0xD9));
14121                     write_number(static_cast<std::uint8_t>(N));
14122                 }
14123                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14124                 {
14125                     // str 16
14126                     oa->write_character(to_char_type(0xDA));
14127                     write_number(static_cast<std::uint16_t>(N));
14128                 }
14129                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14130                 {
14131                     // str 32
14132                     oa->write_character(to_char_type(0xDB));
14133                     write_number(static_cast<std::uint32_t>(N));
14134                 }
14135 
14136                 // step 2: write the string
14137                 oa->write_characters(
14138                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14139                     j.m_value.string->size());
14140                 break;
14141             }
14142 
14143             case value_t::array:
14144             {
14145                 // step 1: write control byte and the array size
14146                 const auto N = j.m_value.array->size();
14147                 if (N <= 15)
14148                 {
14149                     // fixarray
14150                     write_number(static_cast<std::uint8_t>(0x90 | N));
14151                 }
14152                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14153                 {
14154                     // array 16
14155                     oa->write_character(to_char_type(0xDC));
14156                     write_number(static_cast<std::uint16_t>(N));
14157                 }
14158                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14159                 {
14160                     // array 32
14161                     oa->write_character(to_char_type(0xDD));
14162                     write_number(static_cast<std::uint32_t>(N));
14163                 }
14164 
14165                 // step 2: write each element
14166                 for (const auto& el : *j.m_value.array)
14167                 {
14168                     write_msgpack(el);
14169                 }
14170                 break;
14171             }
14172 
14173             case value_t::binary:
14174             {
14175                 // step 0: determine if the binary type has a set subtype to
14176                 // determine whether or not to use the ext or fixext types
14177                 const bool use_ext = j.m_value.binary->has_subtype();
14178 
14179                 // step 1: write control byte and the byte string length
14180                 const auto N = j.m_value.binary->size();
14181                 if (N <= (std::numeric_limits<std::uint8_t>::max)())
14182                 {
14183                     std::uint8_t output_type{};
14184                     bool fixed = true;
14185                     if (use_ext)
14186                     {
14187                         switch (N)
14188                         {
14189                             case 1:
14190                                 output_type = 0xD4; // fixext 1
14191                                 break;
14192                             case 2:
14193                                 output_type = 0xD5; // fixext 2
14194                                 break;
14195                             case 4:
14196                                 output_type = 0xD6; // fixext 4
14197                                 break;
14198                             case 8:
14199                                 output_type = 0xD7; // fixext 8
14200                                 break;
14201                             case 16:
14202                                 output_type = 0xD8; // fixext 16
14203                                 break;
14204                             default:
14205                                 output_type = 0xC7; // ext 8
14206                                 fixed = false;
14207                                 break;
14208                         }
14209 
14210                     }
14211                     else
14212                     {
14213                         output_type = 0xC4; // bin 8
14214                         fixed = false;
14215                     }
14216 
14217                     oa->write_character(to_char_type(output_type));
14218                     if (!fixed)
14219                     {
14220                         write_number(static_cast<std::uint8_t>(N));
14221                     }
14222                 }
14223                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14224                 {
14225                     std::uint8_t output_type = use_ext
14226                                                ? 0xC8 // ext 16
14227                                                : 0xC5; // bin 16
14228 
14229                     oa->write_character(to_char_type(output_type));
14230                     write_number(static_cast<std::uint16_t>(N));
14231                 }
14232                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14233                 {
14234                     std::uint8_t output_type = use_ext
14235                                                ? 0xC9 // ext 32
14236                                                : 0xC6; // bin 32
14237 
14238                     oa->write_character(to_char_type(output_type));
14239                     write_number(static_cast<std::uint32_t>(N));
14240                 }
14241 
14242                 // step 1.5: if this is an ext type, write the subtype
14243                 if (use_ext)
14244                 {
14245                     write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14246                 }
14247 
14248                 // step 2: write the byte string
14249                 oa->write_characters(
14250                     reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14251                     N);
14252 
14253                 break;
14254             }
14255 
14256             case value_t::object:
14257             {
14258                 // step 1: write control byte and the object size
14259                 const auto N = j.m_value.object->size();
14260                 if (N <= 15)
14261                 {
14262                     // fixmap
14263                     write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
14264                 }
14265                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14266                 {
14267                     // map 16
14268                     oa->write_character(to_char_type(0xDE));
14269                     write_number(static_cast<std::uint16_t>(N));
14270                 }
14271                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14272                 {
14273                     // map 32
14274                     oa->write_character(to_char_type(0xDF));
14275                     write_number(static_cast<std::uint32_t>(N));
14276                 }
14277 
14278                 // step 2: write each element
14279                 for (const auto& el : *j.m_value.object)
14280                 {
14281                     write_msgpack(el.first);
14282                     write_msgpack(el.second);
14283                 }
14284                 break;
14285             }
14286 
14287             case value_t::discarded:
14288             default:
14289                 break;
14290         }
14291     }
14292 
14293     /*!
14294     @param[in] j  JSON value to serialize
14295     @param[in] use_count   whether to use '#' prefixes (optimized format)
14296     @param[in] use_type    whether to use '$' prefixes (optimized format)
14297     @param[in] add_prefix  whether prefixes need to be used for this value
14298     */
write_ubjson(const BasicJsonType & j,const bool use_count,const bool use_type,const bool add_prefix=true)14299     void write_ubjson(const BasicJsonType& j, const bool use_count,
14300                       const bool use_type, const bool add_prefix = true)
14301     {
14302         switch (j.type())
14303         {
14304             case value_t::null:
14305             {
14306                 if (add_prefix)
14307                 {
14308                     oa->write_character(to_char_type('Z'));
14309                 }
14310                 break;
14311             }
14312 
14313             case value_t::boolean:
14314             {
14315                 if (add_prefix)
14316                 {
14317                     oa->write_character(j.m_value.boolean
14318                                         ? to_char_type('T')
14319                                         : to_char_type('F'));
14320                 }
14321                 break;
14322             }
14323 
14324             case value_t::number_integer:
14325             {
14326                 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
14327                 break;
14328             }
14329 
14330             case value_t::number_unsigned:
14331             {
14332                 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
14333                 break;
14334             }
14335 
14336             case value_t::number_float:
14337             {
14338                 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
14339                 break;
14340             }
14341 
14342             case value_t::string:
14343             {
14344                 if (add_prefix)
14345                 {
14346                     oa->write_character(to_char_type('S'));
14347                 }
14348                 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
14349                 oa->write_characters(
14350                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14351                     j.m_value.string->size());
14352                 break;
14353             }
14354 
14355             case value_t::array:
14356             {
14357                 if (add_prefix)
14358                 {
14359                     oa->write_character(to_char_type('['));
14360                 }
14361 
14362                 bool prefix_required = true;
14363                 if (use_type && !j.m_value.array->empty())
14364                 {
14365                     JSON_ASSERT(use_count);
14366                     const CharType first_prefix = ubjson_prefix(j.front());
14367                     const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14368                                                          [this, first_prefix](const BasicJsonType & v)
14369                     {
14370                         return ubjson_prefix(v) == first_prefix;
14371                     });
14372 
14373                     if (same_prefix)
14374                     {
14375                         prefix_required = false;
14376                         oa->write_character(to_char_type('$'));
14377                         oa->write_character(first_prefix);
14378                     }
14379                 }
14380 
14381                 if (use_count)
14382                 {
14383                     oa->write_character(to_char_type('#'));
14384                     write_number_with_ubjson_prefix(j.m_value.array->size(), true);
14385                 }
14386 
14387                 for (const auto& el : *j.m_value.array)
14388                 {
14389                     write_ubjson(el, use_count, use_type, prefix_required);
14390                 }
14391 
14392                 if (!use_count)
14393                 {
14394                     oa->write_character(to_char_type(']'));
14395                 }
14396 
14397                 break;
14398             }
14399 
14400             case value_t::binary:
14401             {
14402                 if (add_prefix)
14403                 {
14404                     oa->write_character(to_char_type('['));
14405                 }
14406 
14407                 if (use_type && !j.m_value.binary->empty())
14408                 {
14409                     JSON_ASSERT(use_count);
14410                     oa->write_character(to_char_type('$'));
14411                     oa->write_character('U');
14412                 }
14413 
14414                 if (use_count)
14415                 {
14416                     oa->write_character(to_char_type('#'));
14417                     write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
14418                 }
14419 
14420                 if (use_type)
14421                 {
14422                     oa->write_characters(
14423                         reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14424                         j.m_value.binary->size());
14425                 }
14426                 else
14427                 {
14428                     for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14429                     {
14430                         oa->write_character(to_char_type('U'));
14431                         oa->write_character(j.m_value.binary->data()[i]);
14432                     }
14433                 }
14434 
14435                 if (!use_count)
14436                 {
14437                     oa->write_character(to_char_type(']'));
14438                 }
14439 
14440                 break;
14441             }
14442 
14443             case value_t::object:
14444             {
14445                 if (add_prefix)
14446                 {
14447                     oa->write_character(to_char_type('{'));
14448                 }
14449 
14450                 bool prefix_required = true;
14451                 if (use_type && !j.m_value.object->empty())
14452                 {
14453                     JSON_ASSERT(use_count);
14454                     const CharType first_prefix = ubjson_prefix(j.front());
14455                     const bool same_prefix = std::all_of(j.begin(), j.end(),
14456                                                          [this, first_prefix](const BasicJsonType & v)
14457                     {
14458                         return ubjson_prefix(v) == first_prefix;
14459                     });
14460 
14461                     if (same_prefix)
14462                     {
14463                         prefix_required = false;
14464                         oa->write_character(to_char_type('$'));
14465                         oa->write_character(first_prefix);
14466                     }
14467                 }
14468 
14469                 if (use_count)
14470                 {
14471                     oa->write_character(to_char_type('#'));
14472                     write_number_with_ubjson_prefix(j.m_value.object->size(), true);
14473                 }
14474 
14475                 for (const auto& el : *j.m_value.object)
14476                 {
14477                     write_number_with_ubjson_prefix(el.first.size(), true);
14478                     oa->write_characters(
14479                         reinterpret_cast<const CharType*>(el.first.c_str()),
14480                         el.first.size());
14481                     write_ubjson(el.second, use_count, use_type, prefix_required);
14482                 }
14483 
14484                 if (!use_count)
14485                 {
14486                     oa->write_character(to_char_type('}'));
14487                 }
14488 
14489                 break;
14490             }
14491 
14492             case value_t::discarded:
14493             default:
14494                 break;
14495         }
14496     }
14497 
14498   private:
14499     //////////
14500     // BSON //
14501     //////////
14502 
14503     /*!
14504     @return The size of a BSON document entry header, including the id marker
14505             and the entry name size (and its null-terminator).
14506     */
calc_bson_entry_header_size(const string_t & name,const BasicJsonType & j)14507     static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14508     {
14509         const auto it = name.find(static_cast<typename string_t::value_type>(0));
14510         if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14511         {
14512             JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
14513             static_cast<void>(j);
14514         }
14515 
14516         return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14517     }
14518 
14519     /*!
14520     @brief Writes the given @a element_type and @a name to the output adapter
14521     */
write_bson_entry_header(const string_t & name,const std::uint8_t element_type)14522     void write_bson_entry_header(const string_t& name,
14523                                  const std::uint8_t element_type)
14524     {
14525         oa->write_character(to_char_type(element_type)); // boolean
14526         oa->write_characters(
14527             reinterpret_cast<const CharType*>(name.c_str()),
14528             name.size() + 1u);
14529     }
14530 
14531     /*!
14532     @brief Writes a BSON element with key @a name and boolean value @a value
14533     */
write_bson_boolean(const string_t & name,const bool value)14534     void write_bson_boolean(const string_t& name,
14535                             const bool value)
14536     {
14537         write_bson_entry_header(name, 0x08);
14538         oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
14539     }
14540 
14541     /*!
14542     @brief Writes a BSON element with key @a name and double value @a value
14543     */
write_bson_double(const string_t & name,const double value)14544     void write_bson_double(const string_t& name,
14545                            const double value)
14546     {
14547         write_bson_entry_header(name, 0x01);
14548         write_number<double, true>(value);
14549     }
14550 
14551     /*!
14552     @return The size of the BSON-encoded string in @a value
14553     */
calc_bson_string_size(const string_t & value)14554     static std::size_t calc_bson_string_size(const string_t& value)
14555     {
14556         return sizeof(std::int32_t) + value.size() + 1ul;
14557     }
14558 
14559     /*!
14560     @brief Writes a BSON element with key @a name and string value @a value
14561     */
write_bson_string(const string_t & name,const string_t & value)14562     void write_bson_string(const string_t& name,
14563                            const string_t& value)
14564     {
14565         write_bson_entry_header(name, 0x02);
14566 
14567         write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
14568         oa->write_characters(
14569             reinterpret_cast<const CharType*>(value.c_str()),
14570             value.size() + 1);
14571     }
14572 
14573     /*!
14574     @brief Writes a BSON element with key @a name and null value
14575     */
write_bson_null(const string_t & name)14576     void write_bson_null(const string_t& name)
14577     {
14578         write_bson_entry_header(name, 0x0A);
14579     }
14580 
14581     /*!
14582     @return The size of the BSON-encoded integer @a value
14583     */
calc_bson_integer_size(const std::int64_t value)14584     static std::size_t calc_bson_integer_size(const std::int64_t value)
14585     {
14586         return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
14587                ? sizeof(std::int32_t)
14588                : sizeof(std::int64_t);
14589     }
14590 
14591     /*!
14592     @brief Writes a BSON element with key @a name and integer @a value
14593     */
write_bson_integer(const string_t & name,const std::int64_t value)14594     void write_bson_integer(const string_t& name,
14595                             const std::int64_t value)
14596     {
14597         if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
14598         {
14599             write_bson_entry_header(name, 0x10); // int32
14600             write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
14601         }
14602         else
14603         {
14604             write_bson_entry_header(name, 0x12); // int64
14605             write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
14606         }
14607     }
14608 
14609     /*!
14610     @return The size of the BSON-encoded unsigned integer in @a j
14611     */
calc_bson_unsigned_size(const std::uint64_t value)14612     static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
14613     {
14614         return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14615                ? sizeof(std::int32_t)
14616                : sizeof(std::int64_t);
14617     }
14618 
14619     /*!
14620     @brief Writes a BSON element with key @a name and unsigned @a value
14621     */
write_bson_unsigned(const string_t & name,const BasicJsonType & j)14622     void write_bson_unsigned(const string_t& name,
14623                              const BasicJsonType& j)
14624     {
14625         if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14626         {
14627             write_bson_entry_header(name, 0x10 /* int32 */);
14628             write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
14629         }
14630         else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14631         {
14632             write_bson_entry_header(name, 0x12 /* int64 */);
14633             write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
14634         }
14635         else
14636         {
14637             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));
14638         }
14639     }
14640 
14641     /*!
14642     @brief Writes a BSON element with key @a name and object @a value
14643     */
write_bson_object_entry(const string_t & name,const typename BasicJsonType::object_t & value)14644     void write_bson_object_entry(const string_t& name,
14645                                  const typename BasicJsonType::object_t& value)
14646     {
14647         write_bson_entry_header(name, 0x03); // object
14648         write_bson_object(value);
14649     }
14650 
14651     /*!
14652     @return The size of the BSON-encoded array @a value
14653     */
calc_bson_array_size(const typename BasicJsonType::array_t & value)14654     static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
14655     {
14656         std::size_t array_index = 0ul;
14657 
14658         const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
14659         {
14660             return result + calc_bson_element_size(std::to_string(array_index++), el);
14661         });
14662 
14663         return sizeof(std::int32_t) + embedded_document_size + 1ul;
14664     }
14665 
14666     /*!
14667     @return The size of the BSON-encoded binary array @a value
14668     */
calc_bson_binary_size(const typename BasicJsonType::binary_t & value)14669     static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
14670     {
14671         return sizeof(std::int32_t) + value.size() + 1ul;
14672     }
14673 
14674     /*!
14675     @brief Writes a BSON element with key @a name and array @a value
14676     */
write_bson_array(const string_t & name,const typename BasicJsonType::array_t & value)14677     void write_bson_array(const string_t& name,
14678                           const typename BasicJsonType::array_t& value)
14679     {
14680         write_bson_entry_header(name, 0x04); // array
14681         write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
14682 
14683         std::size_t array_index = 0ul;
14684 
14685         for (const auto& el : value)
14686         {
14687             write_bson_element(std::to_string(array_index++), el);
14688         }
14689 
14690         oa->write_character(to_char_type(0x00));
14691     }
14692 
14693     /*!
14694     @brief Writes a BSON element with key @a name and binary value @a value
14695     */
write_bson_binary(const string_t & name,const binary_t & value)14696     void write_bson_binary(const string_t& name,
14697                            const binary_t& value)
14698     {
14699         write_bson_entry_header(name, 0x05);
14700 
14701         write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
14702         write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : std::uint8_t(0x00));
14703 
14704         oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
14705     }
14706 
14707     /*!
14708     @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
14709     @return The calculated size for the BSON document entry for @a j with the given @a name.
14710     */
calc_bson_element_size(const string_t & name,const BasicJsonType & j)14711     static std::size_t calc_bson_element_size(const string_t& name,
14712             const BasicJsonType& j)
14713     {
14714         const auto header_size = calc_bson_entry_header_size(name, j);
14715         switch (j.type())
14716         {
14717             case value_t::object:
14718                 return header_size + calc_bson_object_size(*j.m_value.object);
14719 
14720             case value_t::array:
14721                 return header_size + calc_bson_array_size(*j.m_value.array);
14722 
14723             case value_t::binary:
14724                 return header_size + calc_bson_binary_size(*j.m_value.binary);
14725 
14726             case value_t::boolean:
14727                 return header_size + 1ul;
14728 
14729             case value_t::number_float:
14730                 return header_size + 8ul;
14731 
14732             case value_t::number_integer:
14733                 return header_size + calc_bson_integer_size(j.m_value.number_integer);
14734 
14735             case value_t::number_unsigned:
14736                 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
14737 
14738             case value_t::string:
14739                 return header_size + calc_bson_string_size(*j.m_value.string);
14740 
14741             case value_t::null:
14742                 return header_size + 0ul;
14743 
14744             // LCOV_EXCL_START
14745             case value_t::discarded:
14746             default:
14747                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14748                 return 0ul;
14749                 // LCOV_EXCL_STOP
14750         }
14751     }
14752 
14753     /*!
14754     @brief Serializes the JSON value @a j to BSON and associates it with the
14755            key @a name.
14756     @param name The name to associate with the JSON entity @a j within the
14757                 current BSON document
14758     */
write_bson_element(const string_t & name,const BasicJsonType & j)14759     void write_bson_element(const string_t& name,
14760                             const BasicJsonType& j)
14761     {
14762         switch (j.type())
14763         {
14764             case value_t::object:
14765                 return write_bson_object_entry(name, *j.m_value.object);
14766 
14767             case value_t::array:
14768                 return write_bson_array(name, *j.m_value.array);
14769 
14770             case value_t::binary:
14771                 return write_bson_binary(name, *j.m_value.binary);
14772 
14773             case value_t::boolean:
14774                 return write_bson_boolean(name, j.m_value.boolean);
14775 
14776             case value_t::number_float:
14777                 return write_bson_double(name, j.m_value.number_float);
14778 
14779             case value_t::number_integer:
14780                 return write_bson_integer(name, j.m_value.number_integer);
14781 
14782             case value_t::number_unsigned:
14783                 return write_bson_unsigned(name, j);
14784 
14785             case value_t::string:
14786                 return write_bson_string(name, *j.m_value.string);
14787 
14788             case value_t::null:
14789                 return write_bson_null(name);
14790 
14791             // LCOV_EXCL_START
14792             case value_t::discarded:
14793             default:
14794                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14795                 return;
14796                 // LCOV_EXCL_STOP
14797         }
14798     }
14799 
14800     /*!
14801     @brief Calculates the size of the BSON serialization of the given
14802            JSON-object @a j.
14803     @param[in] value  JSON value to serialize
14804     @pre       value.type() == value_t::object
14805     */
calc_bson_object_size(const typename BasicJsonType::object_t & value)14806     static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14807     {
14808         std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
14809                                     [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14810         {
14811             return result += calc_bson_element_size(el.first, el.second);
14812         });
14813 
14814         return sizeof(std::int32_t) + document_size + 1ul;
14815     }
14816 
14817     /*!
14818     @param[in] value  JSON value to serialize
14819     @pre       value.type() == value_t::object
14820     */
write_bson_object(const typename BasicJsonType::object_t & value)14821     void write_bson_object(const typename BasicJsonType::object_t& value)
14822     {
14823         write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14824 
14825         for (const auto& el : value)
14826         {
14827             write_bson_element(el.first, el.second);
14828         }
14829 
14830         oa->write_character(to_char_type(0x00));
14831     }
14832 
14833     //////////
14834     // CBOR //
14835     //////////
14836 
get_cbor_float_prefix(float)14837     static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14838     {
14839         return to_char_type(0xFA);  // Single-Precision Float
14840     }
14841 
get_cbor_float_prefix(double)14842     static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14843     {
14844         return to_char_type(0xFB);  // Double-Precision Float
14845     }
14846 
14847     /////////////
14848     // MsgPack //
14849     /////////////
14850 
get_msgpack_float_prefix(float)14851     static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14852     {
14853         return to_char_type(0xCA);  // float 32
14854     }
14855 
get_msgpack_float_prefix(double)14856     static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14857     {
14858         return to_char_type(0xCB);  // float 64
14859     }
14860 
14861     ////////////
14862     // UBJSON //
14863     ////////////
14864 
14865     // UBJSON: write number (floating point)
14866     template<typename NumberType, typename std::enable_if<
14867                  std::is_floating_point<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)14868     void write_number_with_ubjson_prefix(const NumberType n,
14869                                          const bool add_prefix)
14870     {
14871         if (add_prefix)
14872         {
14873             oa->write_character(get_ubjson_float_prefix(n));
14874         }
14875         write_number(n);
14876     }
14877 
14878     // UBJSON: write number (unsigned integer)
14879     template<typename NumberType, typename std::enable_if<
14880                  std::is_unsigned<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)14881     void write_number_with_ubjson_prefix(const NumberType n,
14882                                          const bool add_prefix)
14883     {
14884         if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14885         {
14886             if (add_prefix)
14887             {
14888                 oa->write_character(to_char_type('i'));  // int8
14889             }
14890             write_number(static_cast<std::uint8_t>(n));
14891         }
14892         else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14893         {
14894             if (add_prefix)
14895             {
14896                 oa->write_character(to_char_type('U'));  // uint8
14897             }
14898             write_number(static_cast<std::uint8_t>(n));
14899         }
14900         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14901         {
14902             if (add_prefix)
14903             {
14904                 oa->write_character(to_char_type('I'));  // int16
14905             }
14906             write_number(static_cast<std::int16_t>(n));
14907         }
14908         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14909         {
14910             if (add_prefix)
14911             {
14912                 oa->write_character(to_char_type('l'));  // int32
14913             }
14914             write_number(static_cast<std::int32_t>(n));
14915         }
14916         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14917         {
14918             if (add_prefix)
14919             {
14920                 oa->write_character(to_char_type('L'));  // int64
14921             }
14922             write_number(static_cast<std::int64_t>(n));
14923         }
14924         else
14925         {
14926             if (add_prefix)
14927             {
14928                 oa->write_character(to_char_type('H'));  // high-precision number
14929             }
14930 
14931             const auto number = BasicJsonType(n).dump();
14932             write_number_with_ubjson_prefix(number.size(), true);
14933             for (std::size_t i = 0; i < number.size(); ++i)
14934             {
14935                 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14936             }
14937         }
14938     }
14939 
14940     // UBJSON: write number (signed integer)
14941     template < typename NumberType, typename std::enable_if <
14942                    std::is_signed<NumberType>::value&&
14943                    !std::is_floating_point<NumberType>::value, int >::type = 0 >
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)14944     void write_number_with_ubjson_prefix(const NumberType n,
14945                                          const bool add_prefix)
14946     {
14947         if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
14948         {
14949             if (add_prefix)
14950             {
14951                 oa->write_character(to_char_type('i'));  // int8
14952             }
14953             write_number(static_cast<std::int8_t>(n));
14954         }
14955         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)()))
14956         {
14957             if (add_prefix)
14958             {
14959                 oa->write_character(to_char_type('U'));  // uint8
14960             }
14961             write_number(static_cast<std::uint8_t>(n));
14962         }
14963         else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
14964         {
14965             if (add_prefix)
14966             {
14967                 oa->write_character(to_char_type('I'));  // int16
14968             }
14969             write_number(static_cast<std::int16_t>(n));
14970         }
14971         else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
14972         {
14973             if (add_prefix)
14974             {
14975                 oa->write_character(to_char_type('l'));  // int32
14976             }
14977             write_number(static_cast<std::int32_t>(n));
14978         }
14979         else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
14980         {
14981             if (add_prefix)
14982             {
14983                 oa->write_character(to_char_type('L'));  // int64
14984             }
14985             write_number(static_cast<std::int64_t>(n));
14986         }
14987         // LCOV_EXCL_START
14988         else
14989         {
14990             if (add_prefix)
14991             {
14992                 oa->write_character(to_char_type('H'));  // high-precision number
14993             }
14994 
14995             const auto number = BasicJsonType(n).dump();
14996             write_number_with_ubjson_prefix(number.size(), true);
14997             for (std::size_t i = 0; i < number.size(); ++i)
14998             {
14999                 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15000             }
15001         }
15002         // LCOV_EXCL_STOP
15003     }
15004 
15005     /*!
15006     @brief determine the type prefix of container values
15007     */
ubjson_prefix(const BasicJsonType & j) const15008     CharType ubjson_prefix(const BasicJsonType& j) const noexcept
15009     {
15010         switch (j.type())
15011         {
15012             case value_t::null:
15013                 return 'Z';
15014 
15015             case value_t::boolean:
15016                 return j.m_value.boolean ? 'T' : 'F';
15017 
15018             case value_t::number_integer:
15019             {
15020                 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15021                 {
15022                     return 'i';
15023                 }
15024                 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15025                 {
15026                     return 'U';
15027                 }
15028                 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15029                 {
15030                     return 'I';
15031                 }
15032                 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15033                 {
15034                     return 'l';
15035                 }
15036                 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15037                 {
15038                     return 'L';
15039                 }
15040                 // anything else is treated as high-precision number
15041                 return 'H'; // LCOV_EXCL_LINE
15042             }
15043 
15044             case value_t::number_unsigned:
15045             {
15046                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15047                 {
15048                     return 'i';
15049                 }
15050                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15051                 {
15052                     return 'U';
15053                 }
15054                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15055                 {
15056                     return 'I';
15057                 }
15058                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15059                 {
15060                     return 'l';
15061                 }
15062                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15063                 {
15064                     return 'L';
15065                 }
15066                 // anything else is treated as high-precision number
15067                 return 'H'; // LCOV_EXCL_LINE
15068             }
15069 
15070             case value_t::number_float:
15071                 return get_ubjson_float_prefix(j.m_value.number_float);
15072 
15073             case value_t::string:
15074                 return 'S';
15075 
15076             case value_t::array: // fallthrough
15077             case value_t::binary:
15078                 return '[';
15079 
15080             case value_t::object:
15081                 return '{';
15082 
15083             case value_t::discarded:
15084             default:  // discarded values
15085                 return 'N';
15086         }
15087     }
15088 
get_ubjson_float_prefix(float)15089     static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15090     {
15091         return 'd';  // float 32
15092     }
15093 
get_ubjson_float_prefix(double)15094     static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15095     {
15096         return 'D';  // float 64
15097     }
15098 
15099     ///////////////////////
15100     // Utility functions //
15101     ///////////////////////
15102 
15103     /*
15104     @brief write a number to output input
15105     @param[in] n number of type @a NumberType
15106     @tparam NumberType the type of the number
15107     @tparam OutputIsLittleEndian Set to true if output data is
15108                                  required to be little endian
15109 
15110     @note This function needs to respect the system's endianess, because bytes
15111           in CBOR, MessagePack, and UBJSON are stored in network order (big
15112           endian) and therefore need reordering on little endian systems.
15113     */
15114     template<typename NumberType, bool OutputIsLittleEndian = false>
write_number(const NumberType n)15115     void write_number(const NumberType n)
15116     {
15117         // step 1: write number to array of length NumberType
15118         std::array<CharType, sizeof(NumberType)> vec{};
15119         std::memcpy(vec.data(), &n, sizeof(NumberType));
15120 
15121         // step 2: write array to output (with possible reordering)
15122         if (is_little_endian != OutputIsLittleEndian)
15123         {
15124             // reverse byte order prior to conversion if necessary
15125             std::reverse(vec.begin(), vec.end());
15126         }
15127 
15128         oa->write_characters(vec.data(), sizeof(NumberType));
15129     }
15130 
write_compact_float(const number_float_t n,detail::input_format_t format)15131     void write_compact_float(const number_float_t n, detail::input_format_t format)
15132     {
15133 #ifdef __GNUC__
15134 #pragma GCC diagnostic push
15135 #pragma GCC diagnostic ignored "-Wfloat-equal"
15136 #endif
15137         if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
15138                 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
15139                 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
15140         {
15141             oa->write_character(format == detail::input_format_t::cbor
15142                                 ? get_cbor_float_prefix(static_cast<float>(n))
15143                                 : get_msgpack_float_prefix(static_cast<float>(n)));
15144             write_number(static_cast<float>(n));
15145         }
15146         else
15147         {
15148             oa->write_character(format == detail::input_format_t::cbor
15149                                 ? get_cbor_float_prefix(n)
15150                                 : get_msgpack_float_prefix(n));
15151             write_number(n);
15152         }
15153 #ifdef __GNUC__
15154 #pragma GCC diagnostic pop
15155 #endif
15156     }
15157 
15158   public:
15159     // The following to_char_type functions are implement the conversion
15160     // between uint8_t and CharType. In case CharType is not unsigned,
15161     // such a conversion is required to allow values greater than 128.
15162     // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
15163     template < typename C = CharType,
15164                enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
to_char_type(std::uint8_t x)15165     static constexpr CharType to_char_type(std::uint8_t x) noexcept
15166     {
15167         return *reinterpret_cast<char*>(&x);
15168     }
15169 
15170     template < typename C = CharType,
15171                enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
to_char_type(std::uint8_t x)15172     static CharType to_char_type(std::uint8_t x) noexcept
15173     {
15174         static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
15175         static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
15176         CharType result;
15177         std::memcpy(&result, &x, sizeof(x));
15178         return result;
15179     }
15180 
15181     template<typename C = CharType,
15182              enable_if_t<std::is_unsigned<C>::value>* = nullptr>
to_char_type(std::uint8_t x)15183     static constexpr CharType to_char_type(std::uint8_t x) noexcept
15184     {
15185         return x;
15186     }
15187 
15188     template < typename InputCharType, typename C = CharType,
15189                enable_if_t <
15190                    std::is_signed<C>::value &&
15191                    std::is_signed<char>::value &&
15192                    std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
15193                    > * = nullptr >
to_char_type(InputCharType x)15194     static constexpr CharType to_char_type(InputCharType x) noexcept
15195     {
15196         return x;
15197     }
15198 
15199   private:
15200     /// whether we can assume little endianess
15201     const bool is_little_endian = little_endianess();
15202 
15203     /// the output
15204     output_adapter_t<CharType> oa = nullptr;
15205 };
15206 }  // namespace detail
15207 }  // namespace nlohmann
15208 
15209 // #include <nlohmann/detail/output/output_adapters.hpp>
15210 
15211 // #include <nlohmann/detail/output/serializer.hpp>
15212 
15213 
15214 #include <algorithm> // reverse, remove, fill, find, none_of
15215 #include <array> // array
15216 #include <clocale> // localeconv, lconv
15217 #include <cmath> // labs, isfinite, isnan, signbit
15218 #include <cstddef> // size_t, ptrdiff_t
15219 #include <cstdint> // uint8_t
15220 #include <cstdio> // snprintf
15221 #include <limits> // numeric_limits
15222 #include <string> // string, char_traits
15223 #include <type_traits> // is_same
15224 #include <utility> // move
15225 
15226 // #include <nlohmann/detail/conversions/to_chars.hpp>
15227 
15228 
15229 #include <array> // array
15230 #include <cmath>   // signbit, isfinite
15231 #include <cstdint> // intN_t, uintN_t
15232 #include <cstring> // memcpy, memmove
15233 #include <limits> // numeric_limits
15234 #include <type_traits> // conditional
15235 
15236 // #include <nlohmann/detail/macro_scope.hpp>
15237 
15238 
15239 namespace nlohmann
15240 {
15241 namespace detail
15242 {
15243 
15244 /*!
15245 @brief implements the Grisu2 algorithm for binary to decimal floating-point
15246 conversion.
15247 
15248 This implementation is a slightly modified version of the reference
15249 implementation which may be obtained from
15250 http://florian.loitsch.com/publications (bench.tar.gz).
15251 
15252 The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
15253 
15254 For a detailed description of the algorithm see:
15255 
15256 [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
15257     Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
15258     Language Design and Implementation, PLDI 2010
15259 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
15260     Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
15261     Design and Implementation, PLDI 1996
15262 */
15263 namespace dtoa_impl
15264 {
15265 
15266 template<typename Target, typename Source>
15267 Target reinterpret_bits(const Source source)
15268 {
15269     static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
15270 
15271     Target target;
15272     std::memcpy(&target, &source, sizeof(Source));
15273     return target;
15274 }
15275 
15276 struct diyfp // f * 2^e
15277 {
15278     static constexpr int kPrecision = 64; // = q
15279 
15280     std::uint64_t f = 0;
15281     int e = 0;
15282 
diyfpnlohmann::detail::dtoa_impl::diyfp15283     constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
15284 
15285     /*!
15286     @brief returns x - y
15287     @pre x.e == y.e and x.f >= y.f
15288     */
subnlohmann::detail::dtoa_impl::diyfp15289     static diyfp sub(const diyfp& x, const diyfp& y) noexcept
15290     {
15291         JSON_ASSERT(x.e == y.e);
15292         JSON_ASSERT(x.f >= y.f);
15293 
15294         return {x.f - y.f, x.e};
15295     }
15296 
15297     /*!
15298     @brief returns x * y
15299     @note The result is rounded. (Only the upper q bits are returned.)
15300     */
mulnlohmann::detail::dtoa_impl::diyfp15301     static diyfp mul(const diyfp& x, const diyfp& y) noexcept
15302     {
15303         static_assert(kPrecision == 64, "internal error");
15304 
15305         // Computes:
15306         //  f = round((x.f * y.f) / 2^q)
15307         //  e = x.e + y.e + q
15308 
15309         // Emulate the 64-bit * 64-bit multiplication:
15310         //
15311         // p = u * v
15312         //   = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15313         //   = (u_lo v_lo         ) + 2^32 ((u_lo v_hi         ) + (u_hi v_lo         )) + 2^64 (u_hi v_hi         )
15314         //   = (p0                ) + 2^32 ((p1                ) + (p2                )) + 2^64 (p3                )
15315         //   = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3                )
15316         //   = (p0_lo             ) + 2^32 (p0_hi + p1_lo + p2_lo                      ) + 2^64 (p1_hi + p2_hi + p3)
15317         //   = (p0_lo             ) + 2^32 (Q                                          ) + 2^64 (H                 )
15318         //   = (p0_lo             ) + 2^32 (Q_lo + 2^32 Q_hi                           ) + 2^64 (H                 )
15319         //
15320         // (Since Q might be larger than 2^32 - 1)
15321         //
15322         //   = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15323         //
15324         // (Q_hi + H does not overflow a 64-bit int)
15325         //
15326         //   = p_lo + 2^64 p_hi
15327 
15328         const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15329         const std::uint64_t u_hi = x.f >> 32u;
15330         const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15331         const std::uint64_t v_hi = y.f >> 32u;
15332 
15333         const std::uint64_t p0 = u_lo * v_lo;
15334         const std::uint64_t p1 = u_lo * v_hi;
15335         const std::uint64_t p2 = u_hi * v_lo;
15336         const std::uint64_t p3 = u_hi * v_hi;
15337 
15338         const std::uint64_t p0_hi = p0 >> 32u;
15339         const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15340         const std::uint64_t p1_hi = p1 >> 32u;
15341         const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15342         const std::uint64_t p2_hi = p2 >> 32u;
15343 
15344         std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15345 
15346         // The full product might now be computed as
15347         //
15348         // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
15349         // p_lo = p0_lo + (Q << 32)
15350         //
15351         // But in this particular case here, the full p_lo is not required.
15352         // Effectively we only need to add the highest bit in p_lo to p_hi (and
15353         // Q_hi + 1 does not overflow).
15354 
15355         Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
15356 
15357         const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15358 
15359         return {h, x.e + y.e + 64};
15360     }
15361 
15362     /*!
15363     @brief normalize x such that the significand is >= 2^(q-1)
15364     @pre x.f != 0
15365     */
normalizenlohmann::detail::dtoa_impl::diyfp15366     static diyfp normalize(diyfp x) noexcept
15367     {
15368         JSON_ASSERT(x.f != 0);
15369 
15370         while ((x.f >> 63u) == 0)
15371         {
15372             x.f <<= 1u;
15373             x.e--;
15374         }
15375 
15376         return x;
15377     }
15378 
15379     /*!
15380     @brief normalize x such that the result has the exponent E
15381     @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
15382     */
normalize_tonlohmann::detail::dtoa_impl::diyfp15383     static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
15384     {
15385         const int delta = x.e - target_exponent;
15386 
15387         JSON_ASSERT(delta >= 0);
15388         JSON_ASSERT(((x.f << delta) >> delta) == x.f);
15389 
15390         return {x.f << delta, target_exponent};
15391     }
15392 };
15393 
15394 struct boundaries
15395 {
15396     diyfp w;
15397     diyfp minus;
15398     diyfp plus;
15399 };
15400 
15401 /*!
15402 Compute the (normalized) diyfp representing the input number 'value' and its
15403 boundaries.
15404 
15405 @pre value must be finite and positive
15406 */
15407 template<typename FloatType>
compute_boundaries(FloatType value)15408 boundaries compute_boundaries(FloatType value)
15409 {
15410     JSON_ASSERT(std::isfinite(value));
15411     JSON_ASSERT(value > 0);
15412 
15413     // Convert the IEEE representation into a diyfp.
15414     //
15415     // If v is denormal:
15416     //      value = 0.F * 2^(1 - bias) = (          F) * 2^(1 - bias - (p-1))
15417     // If v is normalized:
15418     //      value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
15419 
15420     static_assert(std::numeric_limits<FloatType>::is_iec559,
15421                   "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
15422 
15423     constexpr int      kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
15424     constexpr int      kBias      = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
15425     constexpr int      kMinExp    = 1 - kBias;
15426     constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
15427 
15428     using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
15429 
15430     const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
15431     const std::uint64_t E = bits >> (kPrecision - 1);
15432     const std::uint64_t F = bits & (kHiddenBit - 1);
15433 
15434     const bool is_denormal = E == 0;
15435     const diyfp v = is_denormal
15436                     ? diyfp(F, kMinExp)
15437                     : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
15438 
15439     // Compute the boundaries m- and m+ of the floating-point value
15440     // v = f * 2^e.
15441     //
15442     // Determine v- and v+, the floating-point predecessor and successor if v,
15443     // respectively.
15444     //
15445     //      v- = v - 2^e        if f != 2^(p-1) or e == e_min                (A)
15446     //         = v - 2^(e-1)    if f == 2^(p-1) and e > e_min                (B)
15447     //
15448     //      v+ = v + 2^e
15449     //
15450     // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
15451     // between m- and m+ round to v, regardless of how the input rounding
15452     // algorithm breaks ties.
15453     //
15454     //      ---+-------------+-------------+-------------+-------------+---  (A)
15455     //         v-            m-            v             m+            v+
15456     //
15457     //      -----------------+------+------+-------------+-------------+---  (B)
15458     //                       v-     m-     v             m+            v+
15459 
15460     const bool lower_boundary_is_closer = F == 0 && E > 1;
15461     const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
15462     const diyfp m_minus = lower_boundary_is_closer
15463                           ? diyfp(4 * v.f - 1, v.e - 2)  // (B)
15464                           : diyfp(2 * v.f - 1, v.e - 1); // (A)
15465 
15466     // Determine the normalized w+ = m+.
15467     const diyfp w_plus = diyfp::normalize(m_plus);
15468 
15469     // Determine w- = m- such that e_(w-) = e_(w+).
15470     const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
15471 
15472     return {diyfp::normalize(v), w_minus, w_plus};
15473 }
15474 
15475 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
15476 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
15477 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
15478 //
15479 //      alpha <= e = e_c + e_w + q <= gamma
15480 //
15481 // or
15482 //
15483 //      f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
15484 //                          <= f_c * f_w * 2^gamma
15485 //
15486 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
15487 //
15488 //      2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
15489 //
15490 // or
15491 //
15492 //      2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
15493 //
15494 // The choice of (alpha,gamma) determines the size of the table and the form of
15495 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
15496 // in practice:
15497 //
15498 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
15499 // processed independently: An integral part p1, and a fractional part p2:
15500 //
15501 //      f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
15502 //              = (f div 2^-e) + (f mod 2^-e) * 2^e
15503 //              = p1 + p2 * 2^e
15504 //
15505 // The conversion of p1 into decimal form requires a series of divisions and
15506 // modulos by (a power of) 10. These operations are faster for 32-bit than for
15507 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
15508 // achieved by choosing
15509 //
15510 //      -e >= 32   or   e <= -32 := gamma
15511 //
15512 // In order to convert the fractional part
15513 //
15514 //      p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
15515 //
15516 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
15517 // d[-i] are extracted in order:
15518 //
15519 //      (10 * p2) div 2^-e = d[-1]
15520 //      (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
15521 //
15522 // The multiplication by 10 must not overflow. It is sufficient to choose
15523 //
15524 //      10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
15525 //
15526 // Since p2 = f mod 2^-e < 2^-e,
15527 //
15528 //      -e <= 60   or   e >= -60 := alpha
15529 
15530 constexpr int kAlpha = -60;
15531 constexpr int kGamma = -32;
15532 
15533 struct cached_power // c = f * 2^e ~= 10^k
15534 {
15535     std::uint64_t f;
15536     int e;
15537     int k;
15538 };
15539 
15540 /*!
15541 For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
15542 power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
15543 satisfies (Definition 3.2 from [1])
15544 
15545      alpha <= e_c + e + q <= gamma.
15546 */
get_cached_power_for_binary_exponent(int e)15547 inline cached_power get_cached_power_for_binary_exponent(int e)
15548 {
15549     // Now
15550     //
15551     //      alpha <= e_c + e + q <= gamma                                    (1)
15552     //      ==> f_c * 2^alpha <= c * 2^e * 2^q
15553     //
15554     // and since the c's are normalized, 2^(q-1) <= f_c,
15555     //
15556     //      ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
15557     //      ==> 2^(alpha - e - 1) <= c
15558     //
15559     // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
15560     //
15561     //      k = ceil( log_10( 2^(alpha - e - 1) ) )
15562     //        = ceil( (alpha - e - 1) * log_10(2) )
15563     //
15564     // From the paper:
15565     // "In theory the result of the procedure could be wrong since c is rounded,
15566     //  and the computation itself is approximated [...]. In practice, however,
15567     //  this simple function is sufficient."
15568     //
15569     // For IEEE double precision floating-point numbers converted into
15570     // normalized diyfp's w = f * 2^e, with q = 64,
15571     //
15572     //      e >= -1022      (min IEEE exponent)
15573     //           -52        (p - 1)
15574     //           -52        (p - 1, possibly normalize denormal IEEE numbers)
15575     //           -11        (normalize the diyfp)
15576     //         = -1137
15577     //
15578     // and
15579     //
15580     //      e <= +1023      (max IEEE exponent)
15581     //           -52        (p - 1)
15582     //           -11        (normalize the diyfp)
15583     //         = 960
15584     //
15585     // This binary exponent range [-1137,960] results in a decimal exponent
15586     // range [-307,324]. One does not need to store a cached power for each
15587     // k in this range. For each such k it suffices to find a cached power
15588     // such that the exponent of the product lies in [alpha,gamma].
15589     // This implies that the difference of the decimal exponents of adjacent
15590     // table entries must be less than or equal to
15591     //
15592     //      floor( (gamma - alpha) * log_10(2) ) = 8.
15593     //
15594     // (A smaller distance gamma-alpha would require a larger table.)
15595 
15596     // NB:
15597     // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
15598 
15599     constexpr int kCachedPowersMinDecExp = -300;
15600     constexpr int kCachedPowersDecStep = 8;
15601 
15602     static constexpr std::array<cached_power, 79> kCachedPowers =
15603     {
15604         {
15605             { 0xAB70FE17C79AC6CA, -1060, -300 },
15606             { 0xFF77B1FCBEBCDC4F, -1034, -292 },
15607             { 0xBE5691EF416BD60C, -1007, -284 },
15608             { 0x8DD01FAD907FFC3C,  -980, -276 },
15609             { 0xD3515C2831559A83,  -954, -268 },
15610             { 0x9D71AC8FADA6C9B5,  -927, -260 },
15611             { 0xEA9C227723EE8BCB,  -901, -252 },
15612             { 0xAECC49914078536D,  -874, -244 },
15613             { 0x823C12795DB6CE57,  -847, -236 },
15614             { 0xC21094364DFB5637,  -821, -228 },
15615             { 0x9096EA6F3848984F,  -794, -220 },
15616             { 0xD77485CB25823AC7,  -768, -212 },
15617             { 0xA086CFCD97BF97F4,  -741, -204 },
15618             { 0xEF340A98172AACE5,  -715, -196 },
15619             { 0xB23867FB2A35B28E,  -688, -188 },
15620             { 0x84C8D4DFD2C63F3B,  -661, -180 },
15621             { 0xC5DD44271AD3CDBA,  -635, -172 },
15622             { 0x936B9FCEBB25C996,  -608, -164 },
15623             { 0xDBAC6C247D62A584,  -582, -156 },
15624             { 0xA3AB66580D5FDAF6,  -555, -148 },
15625             { 0xF3E2F893DEC3F126,  -529, -140 },
15626             { 0xB5B5ADA8AAFF80B8,  -502, -132 },
15627             { 0x87625F056C7C4A8B,  -475, -124 },
15628             { 0xC9BCFF6034C13053,  -449, -116 },
15629             { 0x964E858C91BA2655,  -422, -108 },
15630             { 0xDFF9772470297EBD,  -396, -100 },
15631             { 0xA6DFBD9FB8E5B88F,  -369,  -92 },
15632             { 0xF8A95FCF88747D94,  -343,  -84 },
15633             { 0xB94470938FA89BCF,  -316,  -76 },
15634             { 0x8A08F0F8BF0F156B,  -289,  -68 },
15635             { 0xCDB02555653131B6,  -263,  -60 },
15636             { 0x993FE2C6D07B7FAC,  -236,  -52 },
15637             { 0xE45C10C42A2B3B06,  -210,  -44 },
15638             { 0xAA242499697392D3,  -183,  -36 },
15639             { 0xFD87B5F28300CA0E,  -157,  -28 },
15640             { 0xBCE5086492111AEB,  -130,  -20 },
15641             { 0x8CBCCC096F5088CC,  -103,  -12 },
15642             { 0xD1B71758E219652C,   -77,   -4 },
15643             { 0x9C40000000000000,   -50,    4 },
15644             { 0xE8D4A51000000000,   -24,   12 },
15645             { 0xAD78EBC5AC620000,     3,   20 },
15646             { 0x813F3978F8940984,    30,   28 },
15647             { 0xC097CE7BC90715B3,    56,   36 },
15648             { 0x8F7E32CE7BEA5C70,    83,   44 },
15649             { 0xD5D238A4ABE98068,   109,   52 },
15650             { 0x9F4F2726179A2245,   136,   60 },
15651             { 0xED63A231D4C4FB27,   162,   68 },
15652             { 0xB0DE65388CC8ADA8,   189,   76 },
15653             { 0x83C7088E1AAB65DB,   216,   84 },
15654             { 0xC45D1DF942711D9A,   242,   92 },
15655             { 0x924D692CA61BE758,   269,  100 },
15656             { 0xDA01EE641A708DEA,   295,  108 },
15657             { 0xA26DA3999AEF774A,   322,  116 },
15658             { 0xF209787BB47D6B85,   348,  124 },
15659             { 0xB454E4A179DD1877,   375,  132 },
15660             { 0x865B86925B9BC5C2,   402,  140 },
15661             { 0xC83553C5C8965D3D,   428,  148 },
15662             { 0x952AB45CFA97A0B3,   455,  156 },
15663             { 0xDE469FBD99A05FE3,   481,  164 },
15664             { 0xA59BC234DB398C25,   508,  172 },
15665             { 0xF6C69A72A3989F5C,   534,  180 },
15666             { 0xB7DCBF5354E9BECE,   561,  188 },
15667             { 0x88FCF317F22241E2,   588,  196 },
15668             { 0xCC20CE9BD35C78A5,   614,  204 },
15669             { 0x98165AF37B2153DF,   641,  212 },
15670             { 0xE2A0B5DC971F303A,   667,  220 },
15671             { 0xA8D9D1535CE3B396,   694,  228 },
15672             { 0xFB9B7CD9A4A7443C,   720,  236 },
15673             { 0xBB764C4CA7A44410,   747,  244 },
15674             { 0x8BAB8EEFB6409C1A,   774,  252 },
15675             { 0xD01FEF10A657842C,   800,  260 },
15676             { 0x9B10A4E5E9913129,   827,  268 },
15677             { 0xE7109BFBA19C0C9D,   853,  276 },
15678             { 0xAC2820D9623BF429,   880,  284 },
15679             { 0x80444B5E7AA7CF85,   907,  292 },
15680             { 0xBF21E44003ACDD2D,   933,  300 },
15681             { 0x8E679C2F5E44FF8F,   960,  308 },
15682             { 0xD433179D9C8CB841,   986,  316 },
15683             { 0x9E19DB92B4E31BA9,  1013,  324 },
15684         }
15685     };
15686 
15687     // This computation gives exactly the same results for k as
15688     //      k = ceil((kAlpha - e - 1) * 0.30102999566398114)
15689     // for |e| <= 1500, but doesn't require floating-point operations.
15690     // NB: log_10(2) ~= 78913 / 2^18
15691     JSON_ASSERT(e >= -1500);
15692     JSON_ASSERT(e <=  1500);
15693     const int f = kAlpha - e - 1;
15694     const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
15695 
15696     const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
15697     JSON_ASSERT(index >= 0);
15698     JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
15699 
15700     const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
15701     JSON_ASSERT(kAlpha <= cached.e + e + 64);
15702     JSON_ASSERT(kGamma >= cached.e + e + 64);
15703 
15704     return cached;
15705 }
15706 
15707 /*!
15708 For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
15709 For n == 0, returns 1 and sets pow10 := 1.
15710 */
find_largest_pow10(const std::uint32_t n,std::uint32_t & pow10)15711 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
15712 {
15713     // LCOV_EXCL_START
15714     if (n >= 1000000000)
15715     {
15716         pow10 = 1000000000;
15717         return 10;
15718     }
15719     // LCOV_EXCL_STOP
15720     if (n >= 100000000)
15721     {
15722         pow10 = 100000000;
15723         return  9;
15724     }
15725     if (n >= 10000000)
15726     {
15727         pow10 = 10000000;
15728         return  8;
15729     }
15730     if (n >= 1000000)
15731     {
15732         pow10 = 1000000;
15733         return  7;
15734     }
15735     if (n >= 100000)
15736     {
15737         pow10 = 100000;
15738         return  6;
15739     }
15740     if (n >= 10000)
15741     {
15742         pow10 = 10000;
15743         return  5;
15744     }
15745     if (n >= 1000)
15746     {
15747         pow10 = 1000;
15748         return  4;
15749     }
15750     if (n >= 100)
15751     {
15752         pow10 = 100;
15753         return  3;
15754     }
15755     if (n >= 10)
15756     {
15757         pow10 = 10;
15758         return  2;
15759     }
15760 
15761     pow10 = 1;
15762     return 1;
15763 }
15764 
grisu2_round(char * buf,int len,std::uint64_t dist,std::uint64_t delta,std::uint64_t rest,std::uint64_t ten_k)15765 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
15766                          std::uint64_t rest, std::uint64_t ten_k)
15767 {
15768     JSON_ASSERT(len >= 1);
15769     JSON_ASSERT(dist <= delta);
15770     JSON_ASSERT(rest <= delta);
15771     JSON_ASSERT(ten_k > 0);
15772 
15773     //               <--------------------------- delta ---->
15774     //                                  <---- dist --------->
15775     // --------------[------------------+-------------------]--------------
15776     //               M-                 w                   M+
15777     //
15778     //                                  ten_k
15779     //                                <------>
15780     //                                       <---- rest ---->
15781     // --------------[------------------+----+--------------]--------------
15782     //                                  w    V
15783     //                                       = buf * 10^k
15784     //
15785     // ten_k represents a unit-in-the-last-place in the decimal representation
15786     // stored in buf.
15787     // Decrement buf by ten_k while this takes buf closer to w.
15788 
15789     // The tests are written in this order to avoid overflow in unsigned
15790     // integer arithmetic.
15791 
15792     while (rest < dist
15793             && delta - rest >= ten_k
15794             && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
15795     {
15796         JSON_ASSERT(buf[len - 1] != '0');
15797         buf[len - 1]--;
15798         rest += ten_k;
15799     }
15800 }
15801 
15802 /*!
15803 Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
15804 M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
15805 */
grisu2_digit_gen(char * buffer,int & length,int & decimal_exponent,diyfp M_minus,diyfp w,diyfp M_plus)15806 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
15807                              diyfp M_minus, diyfp w, diyfp M_plus)
15808 {
15809     static_assert(kAlpha >= -60, "internal error");
15810     static_assert(kGamma <= -32, "internal error");
15811 
15812     // Generates the digits (and the exponent) of a decimal floating-point
15813     // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15814     // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15815     //
15816     //               <--------------------------- delta ---->
15817     //                                  <---- dist --------->
15818     // --------------[------------------+-------------------]--------------
15819     //               M-                 w                   M+
15820     //
15821     // Grisu2 generates the digits of M+ from left to right and stops as soon as
15822     // V is in [M-,M+].
15823 
15824     JSON_ASSERT(M_plus.e >= kAlpha);
15825     JSON_ASSERT(M_plus.e <= kGamma);
15826 
15827     std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15828     std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)
15829 
15830     // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15831     //
15832     //      M+ = f * 2^e
15833     //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15834     //         = ((p1        ) * 2^-e + (p2        )) * 2^e
15835     //         = p1 + p2 * 2^e
15836 
15837     const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15838 
15839     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.)
15840     std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e
15841 
15842     // 1)
15843     //
15844     // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15845 
15846     JSON_ASSERT(p1 > 0);
15847 
15848     std::uint32_t pow10{};
15849     const int k = find_largest_pow10(p1, pow10);
15850 
15851     //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15852     //
15853     //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15854     //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))
15855     //
15856     //      M+ = p1                                             + p2 * 2^e
15857     //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e
15858     //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15859     //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e
15860     //
15861     // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15862     //
15863     //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15864     //
15865     // but stop as soon as
15866     //
15867     //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15868 
15869     int n = k;
15870     while (n > 0)
15871     {
15872         // Invariants:
15873         //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)
15874         //      pow10 = 10^(n-1) <= p1 < 10^n
15875         //
15876         const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)
15877         const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)
15878         //
15879         //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15880         //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15881         //
15882         JSON_ASSERT(d <= 9);
15883         buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15884         //
15885         //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15886         //
15887         p1 = r;
15888         n--;
15889         //
15890         //      M+ = buffer * 10^n + (p1 + p2 * 2^e)
15891         //      pow10 = 10^n
15892         //
15893 
15894         // Now check if enough digits have been generated.
15895         // Compute
15896         //
15897         //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15898         //
15899         // Note:
15900         // Since rest and delta share the same exponent e, it suffices to
15901         // compare the significands.
15902         const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15903         if (rest <= delta)
15904         {
15905             // V = buffer * 10^n, with M- <= V <= M+.
15906 
15907             decimal_exponent += n;
15908 
15909             // We may now just stop. But instead look if the buffer could be
15910             // decremented to bring V closer to w.
15911             //
15912             // pow10 = 10^n is now 1 ulp in the decimal representation V.
15913             // The rounding procedure works with diyfp's with an implicit
15914             // exponent of e.
15915             //
15916             //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15917             //
15918             const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
15919             grisu2_round(buffer, length, dist, delta, rest, ten_n);
15920 
15921             return;
15922         }
15923 
15924         pow10 /= 10;
15925         //
15926         //      pow10 = 10^(n-1) <= p1 < 10^n
15927         // Invariants restored.
15928     }
15929 
15930     // 2)
15931     //
15932     // The digits of the integral part have been generated:
15933     //
15934     //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15935     //         = buffer            + p2 * 2^e
15936     //
15937     // Now generate the digits of the fractional part p2 * 2^e.
15938     //
15939     // Note:
15940     // No decimal point is generated: the exponent is adjusted instead.
15941     //
15942     // p2 actually represents the fraction
15943     //
15944     //      p2 * 2^e
15945     //          = p2 / 2^-e
15946     //          = d[-1] / 10^1 + d[-2] / 10^2 + ...
15947     //
15948     // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15949     //
15950     //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15951     //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15952     //
15953     // using
15954     //
15955     //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15956     //                = (                   d) * 2^-e + (                   r)
15957     //
15958     // or
15959     //      10^m * p2 * 2^e = d + r * 2^e
15960     //
15961     // i.e.
15962     //
15963     //      M+ = buffer + p2 * 2^e
15964     //         = buffer + 10^-m * (d + r * 2^e)
15965     //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15966     //
15967     // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15968 
15969     JSON_ASSERT(p2 > delta);
15970 
15971     int m = 0;
15972     for (;;)
15973     {
15974         // Invariant:
15975         //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15976         //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e
15977         //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e
15978         //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15979         //
15980         JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
15981         p2 *= 10;
15982         const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e
15983         const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15984         //
15985         //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15986         //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15987         //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15988         //
15989         JSON_ASSERT(d <= 9);
15990         buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15991         //
15992         //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15993         //
15994         p2 = r;
15995         m++;
15996         //
15997         //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15998         // Invariant restored.
15999 
16000         // Check if enough digits have been generated.
16001         //
16002         //      10^-m * p2 * 2^e <= delta * 2^e
16003         //              p2 * 2^e <= 10^m * delta * 2^e
16004         //                    p2 <= 10^m * delta
16005         delta *= 10;
16006         dist  *= 10;
16007         if (p2 <= delta)
16008         {
16009             break;
16010         }
16011     }
16012 
16013     // V = buffer * 10^-m, with M- <= V <= M+.
16014 
16015     decimal_exponent -= m;
16016 
16017     // 1 ulp in the decimal representation is now 10^-m.
16018     // Since delta and dist are now scaled by 10^m, we need to do the
16019     // same with ulp in order to keep the units in sync.
16020     //
16021     //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16022     //
16023     const std::uint64_t ten_m = one.f;
16024     grisu2_round(buffer, length, dist, delta, p2, ten_m);
16025 
16026     // By construction this algorithm generates the shortest possible decimal
16027     // number (Loitsch, Theorem 6.2) which rounds back to w.
16028     // For an input number of precision p, at least
16029     //
16030     //      N = 1 + ceil(p * log_10(2))
16031     //
16032     // decimal digits are sufficient to identify all binary floating-point
16033     // numbers (Matula, "In-and-Out conversions").
16034     // This implies that the algorithm does not produce more than N decimal
16035     // digits.
16036     //
16037     //      N = 17 for p = 53 (IEEE double precision)
16038     //      N = 9  for p = 24 (IEEE single precision)
16039 }
16040 
16041 /*!
16042 v = buf * 10^decimal_exponent
16043 len is the length of the buffer (number of decimal digits)
16044 The buffer must be large enough, i.e. >= max_digits10.
16045 */
16046 JSON_HEDLEY_NON_NULL(1)
grisu2(char * buf,int & len,int & decimal_exponent,diyfp m_minus,diyfp v,diyfp m_plus)16047 inline void grisu2(char* buf, int& len, int& decimal_exponent,
16048                    diyfp m_minus, diyfp v, diyfp m_plus)
16049 {
16050     JSON_ASSERT(m_plus.e == m_minus.e);
16051     JSON_ASSERT(m_plus.e == v.e);
16052 
16053     //  --------(-----------------------+-----------------------)--------    (A)
16054     //          m-                      v                       m+
16055     //
16056     //  --------------------(-----------+-----------------------)--------    (B)
16057     //                      m-          v                       m+
16058     //
16059     // First scale v (and m- and m+) such that the exponent is in the range
16060     // [alpha, gamma].
16061 
16062     const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
16063 
16064     const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
16065 
16066     // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
16067     const diyfp w       = diyfp::mul(v,       c_minus_k);
16068     const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
16069     const diyfp w_plus  = diyfp::mul(m_plus,  c_minus_k);
16070 
16071     //  ----(---+---)---------------(---+---)---------------(---+---)----
16072     //          w-                      w                       w+
16073     //          = c*m-                  = c*v                   = c*m+
16074     //
16075     // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
16076     // w+ are now off by a small amount.
16077     // In fact:
16078     //
16079     //      w - v * 10^k < 1 ulp
16080     //
16081     // To account for this inaccuracy, add resp. subtract 1 ulp.
16082     //
16083     //  --------+---[---------------(---+---)---------------]---+--------
16084     //          w-  M-                  w                   M+  w+
16085     //
16086     // Now any number in [M-, M+] (bounds included) will round to w when input,
16087     // regardless of how the input rounding algorithm breaks ties.
16088     //
16089     // And digit_gen generates the shortest possible such number in [M-, M+].
16090     // Note that this does not mean that Grisu2 always generates the shortest
16091     // possible number in the interval (m-, m+).
16092     const diyfp M_minus(w_minus.f + 1, w_minus.e);
16093     const diyfp M_plus (w_plus.f  - 1, w_plus.e );
16094 
16095     decimal_exponent = -cached.k; // = -(-k) = k
16096 
16097     grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
16098 }
16099 
16100 /*!
16101 v = buf * 10^decimal_exponent
16102 len is the length of the buffer (number of decimal digits)
16103 The buffer must be large enough, i.e. >= max_digits10.
16104 */
16105 template<typename FloatType>
16106 JSON_HEDLEY_NON_NULL(1)
grisu2(char * buf,int & len,int & decimal_exponent,FloatType value)16107 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
16108 {
16109     static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
16110                   "internal error: not enough precision");
16111 
16112     JSON_ASSERT(std::isfinite(value));
16113     JSON_ASSERT(value > 0);
16114 
16115     // If the neighbors (and boundaries) of 'value' are always computed for double-precision
16116     // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
16117     // decimal representations are not exactly "short".
16118     //
16119     // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
16120     // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
16121     // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
16122     // does.
16123     // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
16124     // representation using the corresponding std::from_chars function recovers value exactly". That
16125     // indicates that single precision floating-point numbers should be recovered using
16126     // 'std::strtof'.
16127     //
16128     // NB: If the neighbors are computed for single-precision numbers, there is a single float
16129     //     (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
16130     //     value is off by 1 ulp.
16131 #if 0
16132     const boundaries w = compute_boundaries(static_cast<double>(value));
16133 #else
16134     const boundaries w = compute_boundaries(value);
16135 #endif
16136 
16137     grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
16138 }
16139 
16140 /*!
16141 @brief appends a decimal representation of e to buf
16142 @return a pointer to the element following the exponent.
16143 @pre -1000 < e < 1000
16144 */
16145 JSON_HEDLEY_NON_NULL(1)
16146 JSON_HEDLEY_RETURNS_NON_NULL
append_exponent(char * buf,int e)16147 inline char* append_exponent(char* buf, int e)
16148 {
16149     JSON_ASSERT(e > -1000);
16150     JSON_ASSERT(e <  1000);
16151 
16152     if (e < 0)
16153     {
16154         e = -e;
16155         *buf++ = '-';
16156     }
16157     else
16158     {
16159         *buf++ = '+';
16160     }
16161 
16162     auto k = static_cast<std::uint32_t>(e);
16163     if (k < 10)
16164     {
16165         // Always print at least two digits in the exponent.
16166         // This is for compatibility with printf("%g").
16167         *buf++ = '0';
16168         *buf++ = static_cast<char>('0' + k);
16169     }
16170     else if (k < 100)
16171     {
16172         *buf++ = static_cast<char>('0' + k / 10);
16173         k %= 10;
16174         *buf++ = static_cast<char>('0' + k);
16175     }
16176     else
16177     {
16178         *buf++ = static_cast<char>('0' + k / 100);
16179         k %= 100;
16180         *buf++ = static_cast<char>('0' + k / 10);
16181         k %= 10;
16182         *buf++ = static_cast<char>('0' + k);
16183     }
16184 
16185     return buf;
16186 }
16187 
16188 /*!
16189 @brief prettify v = buf * 10^decimal_exponent
16190 
16191 If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
16192 notation. Otherwise it will be printed in exponential notation.
16193 
16194 @pre min_exp < 0
16195 @pre max_exp > 0
16196 */
16197 JSON_HEDLEY_NON_NULL(1)
16198 JSON_HEDLEY_RETURNS_NON_NULL
format_buffer(char * buf,int len,int decimal_exponent,int min_exp,int max_exp)16199 inline char* format_buffer(char* buf, int len, int decimal_exponent,
16200                            int min_exp, int max_exp)
16201 {
16202     JSON_ASSERT(min_exp < 0);
16203     JSON_ASSERT(max_exp > 0);
16204 
16205     const int k = len;
16206     const int n = len + decimal_exponent;
16207 
16208     // v = buf * 10^(n-k)
16209     // k is the length of the buffer (number of decimal digits)
16210     // n is the position of the decimal point relative to the start of the buffer.
16211 
16212     if (k <= n && n <= max_exp)
16213     {
16214         // digits[000]
16215         // len <= max_exp + 2
16216 
16217         std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
16218         // Make it look like a floating-point number (#362, #378)
16219         buf[n + 0] = '.';
16220         buf[n + 1] = '0';
16221         return buf + (static_cast<size_t>(n) + 2);
16222     }
16223 
16224     if (0 < n && n <= max_exp)
16225     {
16226         // dig.its
16227         // len <= max_digits10 + 1
16228 
16229         JSON_ASSERT(k > n);
16230 
16231         std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
16232         buf[n] = '.';
16233         return buf + (static_cast<size_t>(k) + 1U);
16234     }
16235 
16236     if (min_exp < n && n <= 0)
16237     {
16238         // 0.[000]digits
16239         // len <= 2 + (-min_exp - 1) + max_digits10
16240 
16241         std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
16242         buf[0] = '0';
16243         buf[1] = '.';
16244         std::memset(buf + 2, '0', static_cast<size_t>(-n));
16245         return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
16246     }
16247 
16248     if (k == 1)
16249     {
16250         // dE+123
16251         // len <= 1 + 5
16252 
16253         buf += 1;
16254     }
16255     else
16256     {
16257         // d.igitsE+123
16258         // len <= max_digits10 + 1 + 5
16259 
16260         std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
16261         buf[1] = '.';
16262         buf += 1 + static_cast<size_t>(k);
16263     }
16264 
16265     *buf++ = 'e';
16266     return append_exponent(buf, n - 1);
16267 }
16268 
16269 } // namespace dtoa_impl
16270 
16271 /*!
16272 @brief generates a decimal representation of the floating-point number value in [first, last).
16273 
16274 The format of the resulting decimal representation is similar to printf's %g
16275 format. Returns an iterator pointing past-the-end of the decimal representation.
16276 
16277 @note The input number must be finite, i.e. NaN's and Inf's are not supported.
16278 @note The buffer must be large enough.
16279 @note The result is NOT null-terminated.
16280 */
16281 template<typename FloatType>
16282 JSON_HEDLEY_NON_NULL(1, 2)
16283 JSON_HEDLEY_RETURNS_NON_NULL
to_chars(char * first,const char * last,FloatType value)16284 char* to_chars(char* first, const char* last, FloatType value)
16285 {
16286     static_cast<void>(last); // maybe unused - fix warning
16287     JSON_ASSERT(std::isfinite(value));
16288 
16289     // Use signbit(value) instead of (value < 0) since signbit works for -0.
16290     if (std::signbit(value))
16291     {
16292         value = -value;
16293         *first++ = '-';
16294     }
16295 
16296 #ifdef __GNUC__
16297 #pragma GCC diagnostic push
16298 #pragma GCC diagnostic ignored "-Wfloat-equal"
16299 #endif
16300     if (value == 0) // +-0
16301     {
16302         *first++ = '0';
16303         // Make it look like a floating-point number (#362, #378)
16304         *first++ = '.';
16305         *first++ = '0';
16306         return first;
16307     }
16308 #ifdef __GNUC__
16309 #pragma GCC diagnostic pop
16310 #endif
16311 
16312     JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
16313 
16314     // Compute v = buffer * 10^decimal_exponent.
16315     // The decimal digits are stored in the buffer, which needs to be interpreted
16316     // as an unsigned decimal integer.
16317     // len is the length of the buffer, i.e. the number of decimal digits.
16318     int len = 0;
16319     int decimal_exponent = 0;
16320     dtoa_impl::grisu2(first, len, decimal_exponent, value);
16321 
16322     JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
16323 
16324     // Format the buffer like printf("%.*g", prec, value)
16325     constexpr int kMinExp = -4;
16326     // Use digits10 here to increase compatibility with version 2.
16327     constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
16328 
16329     JSON_ASSERT(last - first >= kMaxExp + 2);
16330     JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
16331     JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
16332 
16333     return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
16334 }
16335 
16336 } // namespace detail
16337 } // namespace nlohmann
16338 
16339 // #include <nlohmann/detail/exceptions.hpp>
16340 
16341 // #include <nlohmann/detail/macro_scope.hpp>
16342 
16343 // #include <nlohmann/detail/meta/cpp_future.hpp>
16344 
16345 // #include <nlohmann/detail/output/binary_writer.hpp>
16346 
16347 // #include <nlohmann/detail/output/output_adapters.hpp>
16348 
16349 // #include <nlohmann/detail/value_t.hpp>
16350 
16351 
16352 namespace nlohmann
16353 {
16354 namespace detail
16355 {
16356 ///////////////////
16357 // serialization //
16358 ///////////////////
16359 
16360 /// how to treat decoding errors
16361 enum class error_handler_t
16362 {
16363     strict,  ///< throw a type_error exception in case of invalid UTF-8
16364     replace, ///< replace invalid UTF-8 sequences with U+FFFD
16365     ignore   ///< ignore invalid UTF-8 sequences
16366 };
16367 
16368 template<typename BasicJsonType>
16369 class serializer
16370 {
16371     using string_t = typename BasicJsonType::string_t;
16372     using number_float_t = typename BasicJsonType::number_float_t;
16373     using number_integer_t = typename BasicJsonType::number_integer_t;
16374     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
16375     using binary_char_t = typename BasicJsonType::binary_t::value_type;
16376     static constexpr std::uint8_t UTF8_ACCEPT = 0;
16377     static constexpr std::uint8_t UTF8_REJECT = 1;
16378 
16379   public:
16380     /*!
16381     @param[in] s  output stream to serialize to
16382     @param[in] ichar  indentation character to use
16383     @param[in] error_handler_  how to react on decoding errors
16384     */
serializer(output_adapter_t<char> s,const char ichar,error_handler_t error_handler_=error_handler_t::strict)16385     serializer(output_adapter_t<char> s, const char ichar,
16386                error_handler_t error_handler_ = error_handler_t::strict)
16387         : o(std::move(s))
16388         , loc(std::localeconv())
16389         , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
16390         , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
16391         , indent_char(ichar)
16392         , indent_string(512, indent_char)
16393         , error_handler(error_handler_)
16394     {}
16395 
16396     // delete because of pointer members
16397     serializer(const serializer&) = delete;
16398     serializer& operator=(const serializer&) = delete;
16399     serializer(serializer&&) = delete;
16400     serializer& operator=(serializer&&) = delete;
16401     ~serializer() = default;
16402 
16403     /*!
16404     @brief internal implementation of the serialization function
16405 
16406     This function is called by the public member function dump and organizes
16407     the serialization internally. The indentation level is propagated as
16408     additional parameter. In case of arrays and objects, the function is
16409     called recursively.
16410 
16411     - strings and object keys are escaped using `escape_string()`
16412     - integer numbers are converted implicitly via `operator<<`
16413     - floating-point numbers are converted to a string using `"%g"` format
16414     - binary values are serialized as objects containing the subtype and the
16415       byte array
16416 
16417     @param[in] val               value to serialize
16418     @param[in] pretty_print      whether the output shall be pretty-printed
16419     @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
16420     in the output are escaped with `\uXXXX` sequences, and the result consists
16421     of ASCII characters only.
16422     @param[in] indent_step       the indent level
16423     @param[in] current_indent    the current indent level (only used internally)
16424     */
dump(const BasicJsonType & val,const bool pretty_print,const bool ensure_ascii,const unsigned int indent_step,const unsigned int current_indent=0)16425     void dump(const BasicJsonType& val,
16426               const bool pretty_print,
16427               const bool ensure_ascii,
16428               const unsigned int indent_step,
16429               const unsigned int current_indent = 0)
16430     {
16431         switch (val.m_type)
16432         {
16433             case value_t::object:
16434             {
16435                 if (val.m_value.object->empty())
16436                 {
16437                     o->write_characters("{}", 2);
16438                     return;
16439                 }
16440 
16441                 if (pretty_print)
16442                 {
16443                     o->write_characters("{\n", 2);
16444 
16445                     // variable to hold indentation for recursive calls
16446                     const auto new_indent = current_indent + indent_step;
16447                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16448                     {
16449                         indent_string.resize(indent_string.size() * 2, ' ');
16450                     }
16451 
16452                     // first n-1 elements
16453                     auto i = val.m_value.object->cbegin();
16454                     for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16455                     {
16456                         o->write_characters(indent_string.c_str(), new_indent);
16457                         o->write_character('\"');
16458                         dump_escaped(i->first, ensure_ascii);
16459                         o->write_characters("\": ", 3);
16460                         dump(i->second, true, ensure_ascii, indent_step, new_indent);
16461                         o->write_characters(",\n", 2);
16462                     }
16463 
16464                     // last element
16465                     JSON_ASSERT(i != val.m_value.object->cend());
16466                     JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16467                     o->write_characters(indent_string.c_str(), new_indent);
16468                     o->write_character('\"');
16469                     dump_escaped(i->first, ensure_ascii);
16470                     o->write_characters("\": ", 3);
16471                     dump(i->second, true, ensure_ascii, indent_step, new_indent);
16472 
16473                     o->write_character('\n');
16474                     o->write_characters(indent_string.c_str(), current_indent);
16475                     o->write_character('}');
16476                 }
16477                 else
16478                 {
16479                     o->write_character('{');
16480 
16481                     // first n-1 elements
16482                     auto i = val.m_value.object->cbegin();
16483                     for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16484                     {
16485                         o->write_character('\"');
16486                         dump_escaped(i->first, ensure_ascii);
16487                         o->write_characters("\":", 2);
16488                         dump(i->second, false, ensure_ascii, indent_step, current_indent);
16489                         o->write_character(',');
16490                     }
16491 
16492                     // last element
16493                     JSON_ASSERT(i != val.m_value.object->cend());
16494                     JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16495                     o->write_character('\"');
16496                     dump_escaped(i->first, ensure_ascii);
16497                     o->write_characters("\":", 2);
16498                     dump(i->second, false, ensure_ascii, indent_step, current_indent);
16499 
16500                     o->write_character('}');
16501                 }
16502 
16503                 return;
16504             }
16505 
16506             case value_t::array:
16507             {
16508                 if (val.m_value.array->empty())
16509                 {
16510                     o->write_characters("[]", 2);
16511                     return;
16512                 }
16513 
16514                 if (pretty_print)
16515                 {
16516                     o->write_characters("[\n", 2);
16517 
16518                     // variable to hold indentation for recursive calls
16519                     const auto new_indent = current_indent + indent_step;
16520                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16521                     {
16522                         indent_string.resize(indent_string.size() * 2, ' ');
16523                     }
16524 
16525                     // first n-1 elements
16526                     for (auto i = val.m_value.array->cbegin();
16527                             i != val.m_value.array->cend() - 1; ++i)
16528                     {
16529                         o->write_characters(indent_string.c_str(), new_indent);
16530                         dump(*i, true, ensure_ascii, indent_step, new_indent);
16531                         o->write_characters(",\n", 2);
16532                     }
16533 
16534                     // last element
16535                     JSON_ASSERT(!val.m_value.array->empty());
16536                     o->write_characters(indent_string.c_str(), new_indent);
16537                     dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
16538 
16539                     o->write_character('\n');
16540                     o->write_characters(indent_string.c_str(), current_indent);
16541                     o->write_character(']');
16542                 }
16543                 else
16544                 {
16545                     o->write_character('[');
16546 
16547                     // first n-1 elements
16548                     for (auto i = val.m_value.array->cbegin();
16549                             i != val.m_value.array->cend() - 1; ++i)
16550                     {
16551                         dump(*i, false, ensure_ascii, indent_step, current_indent);
16552                         o->write_character(',');
16553                     }
16554 
16555                     // last element
16556                     JSON_ASSERT(!val.m_value.array->empty());
16557                     dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
16558 
16559                     o->write_character(']');
16560                 }
16561 
16562                 return;
16563             }
16564 
16565             case value_t::string:
16566             {
16567                 o->write_character('\"');
16568                 dump_escaped(*val.m_value.string, ensure_ascii);
16569                 o->write_character('\"');
16570                 return;
16571             }
16572 
16573             case value_t::binary:
16574             {
16575                 if (pretty_print)
16576                 {
16577                     o->write_characters("{\n", 2);
16578 
16579                     // variable to hold indentation for recursive calls
16580                     const auto new_indent = current_indent + indent_step;
16581                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16582                     {
16583                         indent_string.resize(indent_string.size() * 2, ' ');
16584                     }
16585 
16586                     o->write_characters(indent_string.c_str(), new_indent);
16587 
16588                     o->write_characters("\"bytes\": [", 10);
16589 
16590                     if (!val.m_value.binary->empty())
16591                     {
16592                         for (auto i = val.m_value.binary->cbegin();
16593                                 i != val.m_value.binary->cend() - 1; ++i)
16594                         {
16595                             dump_integer(*i);
16596                             o->write_characters(", ", 2);
16597                         }
16598                         dump_integer(val.m_value.binary->back());
16599                     }
16600 
16601                     o->write_characters("],\n", 3);
16602                     o->write_characters(indent_string.c_str(), new_indent);
16603 
16604                     o->write_characters("\"subtype\": ", 11);
16605                     if (val.m_value.binary->has_subtype())
16606                     {
16607                         dump_integer(val.m_value.binary->subtype());
16608                     }
16609                     else
16610                     {
16611                         o->write_characters("null", 4);
16612                     }
16613                     o->write_character('\n');
16614                     o->write_characters(indent_string.c_str(), current_indent);
16615                     o->write_character('}');
16616                 }
16617                 else
16618                 {
16619                     o->write_characters("{\"bytes\":[", 10);
16620 
16621                     if (!val.m_value.binary->empty())
16622                     {
16623                         for (auto i = val.m_value.binary->cbegin();
16624                                 i != val.m_value.binary->cend() - 1; ++i)
16625                         {
16626                             dump_integer(*i);
16627                             o->write_character(',');
16628                         }
16629                         dump_integer(val.m_value.binary->back());
16630                     }
16631 
16632                     o->write_characters("],\"subtype\":", 12);
16633                     if (val.m_value.binary->has_subtype())
16634                     {
16635                         dump_integer(val.m_value.binary->subtype());
16636                         o->write_character('}');
16637                     }
16638                     else
16639                     {
16640                         o->write_characters("null}", 5);
16641                     }
16642                 }
16643                 return;
16644             }
16645 
16646             case value_t::boolean:
16647             {
16648                 if (val.m_value.boolean)
16649                 {
16650                     o->write_characters("true", 4);
16651                 }
16652                 else
16653                 {
16654                     o->write_characters("false", 5);
16655                 }
16656                 return;
16657             }
16658 
16659             case value_t::number_integer:
16660             {
16661                 dump_integer(val.m_value.number_integer);
16662                 return;
16663             }
16664 
16665             case value_t::number_unsigned:
16666             {
16667                 dump_integer(val.m_value.number_unsigned);
16668                 return;
16669             }
16670 
16671             case value_t::number_float:
16672             {
16673                 dump_float(val.m_value.number_float);
16674                 return;
16675             }
16676 
16677             case value_t::discarded:
16678             {
16679                 o->write_characters("<discarded>", 11);
16680                 return;
16681             }
16682 
16683             case value_t::null:
16684             {
16685                 o->write_characters("null", 4);
16686                 return;
16687             }
16688 
16689             default:            // LCOV_EXCL_LINE
16690                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16691         }
16692     }
16693 
16694   JSON_PRIVATE_UNLESS_TESTED:
16695     /*!
16696     @brief dump escaped string
16697 
16698     Escape a string by replacing certain special characters by a sequence of an
16699     escape character (backslash) and another character and other control
16700     characters by a sequence of "\u" followed by a four-digit hex
16701     representation. The escaped string is written to output stream @a o.
16702 
16703     @param[in] s  the string to escape
16704     @param[in] ensure_ascii  whether to escape non-ASCII characters with
16705                              \uXXXX sequences
16706 
16707     @complexity Linear in the length of string @a s.
16708     */
16709     void dump_escaped(const string_t& s, const bool ensure_ascii)
16710     {
16711         std::uint32_t codepoint{};
16712         std::uint8_t state = UTF8_ACCEPT;
16713         std::size_t bytes = 0;  // number of bytes written to string_buffer
16714 
16715         // number of bytes written at the point of the last valid byte
16716         std::size_t bytes_after_last_accept = 0;
16717         std::size_t undumped_chars = 0;
16718 
16719         for (std::size_t i = 0; i < s.size(); ++i)
16720         {
16721             const auto byte = static_cast<std::uint8_t>(s[i]);
16722 
16723             switch (decode(state, codepoint, byte))
16724             {
16725                 case UTF8_ACCEPT:  // decode found a new code point
16726                 {
16727                     switch (codepoint)
16728                     {
16729                         case 0x08: // backspace
16730                         {
16731                             string_buffer[bytes++] = '\\';
16732                             string_buffer[bytes++] = 'b';
16733                             break;
16734                         }
16735 
16736                         case 0x09: // horizontal tab
16737                         {
16738                             string_buffer[bytes++] = '\\';
16739                             string_buffer[bytes++] = 't';
16740                             break;
16741                         }
16742 
16743                         case 0x0A: // newline
16744                         {
16745                             string_buffer[bytes++] = '\\';
16746                             string_buffer[bytes++] = 'n';
16747                             break;
16748                         }
16749 
16750                         case 0x0C: // formfeed
16751                         {
16752                             string_buffer[bytes++] = '\\';
16753                             string_buffer[bytes++] = 'f';
16754                             break;
16755                         }
16756 
16757                         case 0x0D: // carriage return
16758                         {
16759                             string_buffer[bytes++] = '\\';
16760                             string_buffer[bytes++] = 'r';
16761                             break;
16762                         }
16763 
16764                         case 0x22: // quotation mark
16765                         {
16766                             string_buffer[bytes++] = '\\';
16767                             string_buffer[bytes++] = '\"';
16768                             break;
16769                         }
16770 
16771                         case 0x5C: // reverse solidus
16772                         {
16773                             string_buffer[bytes++] = '\\';
16774                             string_buffer[bytes++] = '\\';
16775                             break;
16776                         }
16777 
16778                         default:
16779                         {
16780                             // escape control characters (0x00..0x1F) or, if
16781                             // ensure_ascii parameter is used, non-ASCII characters
16782                             if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
16783                             {
16784                                 if (codepoint <= 0xFFFF)
16785                                 {
16786                                     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16787                                     (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
16788                                                     static_cast<std::uint16_t>(codepoint));
16789                                     bytes += 6;
16790                                 }
16791                                 else
16792                                 {
16793                                     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16794                                     (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
16795                                                     static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
16796                                                     static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
16797                                     bytes += 12;
16798                                 }
16799                             }
16800                             else
16801                             {
16802                                 // copy byte to buffer (all previous bytes
16803                                 // been copied have in default case above)
16804                                 string_buffer[bytes++] = s[i];
16805                             }
16806                             break;
16807                         }
16808                     }
16809 
16810                     // write buffer and reset index; there must be 13 bytes
16811                     // left, as this is the maximal number of bytes to be
16812                     // written ("\uxxxx\uxxxx\0") for one code point
16813                     if (string_buffer.size() - bytes < 13)
16814                     {
16815                         o->write_characters(string_buffer.data(), bytes);
16816                         bytes = 0;
16817                     }
16818 
16819                     // remember the byte position of this accept
16820                     bytes_after_last_accept = bytes;
16821                     undumped_chars = 0;
16822                     break;
16823                 }
16824 
16825                 case UTF8_REJECT:  // decode found invalid UTF-8 byte
16826                 {
16827                     switch (error_handler)
16828                     {
16829                         case error_handler_t::strict:
16830                         {
16831                             std::string sn(9, '\0');
16832                             // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16833                             (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
16834                             JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType()));
16835                         }
16836 
16837                         case error_handler_t::ignore:
16838                         case error_handler_t::replace:
16839                         {
16840                             // in case we saw this character the first time, we
16841                             // would like to read it again, because the byte
16842                             // may be OK for itself, but just not OK for the
16843                             // previous sequence
16844                             if (undumped_chars > 0)
16845                             {
16846                                 --i;
16847                             }
16848 
16849                             // reset length buffer to the last accepted index;
16850                             // thus removing/ignoring the invalid characters
16851                             bytes = bytes_after_last_accept;
16852 
16853                             if (error_handler == error_handler_t::replace)
16854                             {
16855                                 // add a replacement character
16856                                 if (ensure_ascii)
16857                                 {
16858                                     string_buffer[bytes++] = '\\';
16859                                     string_buffer[bytes++] = 'u';
16860                                     string_buffer[bytes++] = 'f';
16861                                     string_buffer[bytes++] = 'f';
16862                                     string_buffer[bytes++] = 'f';
16863                                     string_buffer[bytes++] = 'd';
16864                                 }
16865                                 else
16866                                 {
16867                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
16868                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
16869                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
16870                                 }
16871 
16872                                 // write buffer and reset index; there must be 13 bytes
16873                                 // left, as this is the maximal number of bytes to be
16874                                 // written ("\uxxxx\uxxxx\0") for one code point
16875                                 if (string_buffer.size() - bytes < 13)
16876                                 {
16877                                     o->write_characters(string_buffer.data(), bytes);
16878                                     bytes = 0;
16879                                 }
16880 
16881                                 bytes_after_last_accept = bytes;
16882                             }
16883 
16884                             undumped_chars = 0;
16885 
16886                             // continue processing the string
16887                             state = UTF8_ACCEPT;
16888                             break;
16889                         }
16890 
16891                         default:            // LCOV_EXCL_LINE
16892                             JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16893                     }
16894                     break;
16895                 }
16896 
16897                 default:  // decode found yet incomplete multi-byte code point
16898                 {
16899                     if (!ensure_ascii)
16900                     {
16901                         // code point will not be escaped - copy byte to buffer
16902                         string_buffer[bytes++] = s[i];
16903                     }
16904                     ++undumped_chars;
16905                     break;
16906                 }
16907             }
16908         }
16909 
16910         // we finished processing the string
16911         if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
16912         {
16913             // write buffer
16914             if (bytes > 0)
16915             {
16916                 o->write_characters(string_buffer.data(), bytes);
16917             }
16918         }
16919         else
16920         {
16921             // we finish reading, but do not accept: string was incomplete
16922             switch (error_handler)
16923             {
16924                 case error_handler_t::strict:
16925                 {
16926                     std::string sn(9, '\0');
16927                     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16928                     (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
16929                     JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType()));
16930                 }
16931 
16932                 case error_handler_t::ignore:
16933                 {
16934                     // write all accepted bytes
16935                     o->write_characters(string_buffer.data(), bytes_after_last_accept);
16936                     break;
16937                 }
16938 
16939                 case error_handler_t::replace:
16940                 {
16941                     // write all accepted bytes
16942                     o->write_characters(string_buffer.data(), bytes_after_last_accept);
16943                     // add a replacement character
16944                     if (ensure_ascii)
16945                     {
16946                         o->write_characters("\\ufffd", 6);
16947                     }
16948                     else
16949                     {
16950                         o->write_characters("\xEF\xBF\xBD", 3);
16951                     }
16952                     break;
16953                 }
16954 
16955                 default:            // LCOV_EXCL_LINE
16956                     JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16957             }
16958         }
16959     }
16960 
16961   private:
16962     /*!
16963     @brief count digits
16964 
16965     Count the number of decimal (base 10) digits for an input unsigned integer.
16966 
16967     @param[in] x  unsigned integer number to count its digits
16968     @return    number of decimal digits
16969     */
count_digits(number_unsigned_t x)16970     inline unsigned int count_digits(number_unsigned_t x) noexcept
16971     {
16972         unsigned int n_digits = 1;
16973         for (;;)
16974         {
16975             if (x < 10)
16976             {
16977                 return n_digits;
16978             }
16979             if (x < 100)
16980             {
16981                 return n_digits + 1;
16982             }
16983             if (x < 1000)
16984             {
16985                 return n_digits + 2;
16986             }
16987             if (x < 10000)
16988             {
16989                 return n_digits + 3;
16990             }
16991             x = x / 10000u;
16992             n_digits += 4;
16993         }
16994     }
16995 
16996     /*!
16997     @brief dump an integer
16998 
16999     Dump a given integer to output stream @a o. Works internally with
17000     @a number_buffer.
17001 
17002     @param[in] x  integer number (signed or unsigned) to dump
17003     @tparam NumberType either @a number_integer_t or @a number_unsigned_t
17004     */
17005     template < typename NumberType, detail::enable_if_t <
17006                    std::is_integral<NumberType>::value ||
17007                    std::is_same<NumberType, number_unsigned_t>::value ||
17008                    std::is_same<NumberType, number_integer_t>::value ||
17009                    std::is_same<NumberType, binary_char_t>::value,
17010                    int > = 0 >
dump_integer(NumberType x)17011     void dump_integer(NumberType x)
17012     {
17013         static constexpr std::array<std::array<char, 2>, 100> digits_to_99
17014         {
17015             {
17016                 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
17017                 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
17018                 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
17019                 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
17020                 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
17021                 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17022                 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17023                 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17024                 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17025                 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17026             }
17027         };
17028 
17029         // special case for "0"
17030         if (x == 0)
17031         {
17032             o->write_character('0');
17033             return;
17034         }
17035 
17036         // use a pointer to fill the buffer
17037         auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17038 
17039         const bool is_negative = std::is_signed<NumberType>::value && !(x >= 0); // see issue #755
17040         number_unsigned_t abs_value;
17041 
17042         unsigned int n_chars{};
17043 
17044         if (is_negative)
17045         {
17046             *buffer_ptr = '-';
17047             abs_value = remove_sign(static_cast<number_integer_t>(x));
17048 
17049             // account one more byte for the minus sign
17050             n_chars = 1 + count_digits(abs_value);
17051         }
17052         else
17053         {
17054             abs_value = static_cast<number_unsigned_t>(x);
17055             n_chars = count_digits(abs_value);
17056         }
17057 
17058         // spare 1 byte for '\0'
17059         JSON_ASSERT(n_chars < number_buffer.size() - 1);
17060 
17061         // jump to the end to generate the string from backward
17062         // so we later avoid reversing the result
17063         buffer_ptr += n_chars;
17064 
17065         // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
17066         // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
17067         while (abs_value >= 100)
17068         {
17069             const auto digits_index = static_cast<unsigned>((abs_value % 100));
17070             abs_value /= 100;
17071             *(--buffer_ptr) = digits_to_99[digits_index][1];
17072             *(--buffer_ptr) = digits_to_99[digits_index][0];
17073         }
17074 
17075         if (abs_value >= 10)
17076         {
17077             const auto digits_index = static_cast<unsigned>(abs_value);
17078             *(--buffer_ptr) = digits_to_99[digits_index][1];
17079             *(--buffer_ptr) = digits_to_99[digits_index][0];
17080         }
17081         else
17082         {
17083             *(--buffer_ptr) = static_cast<char>('0' + abs_value);
17084         }
17085 
17086         o->write_characters(number_buffer.data(), n_chars);
17087     }
17088 
17089     /*!
17090     @brief dump a floating-point number
17091 
17092     Dump a given floating-point number to output stream @a o. Works internally
17093     with @a number_buffer.
17094 
17095     @param[in] x  floating-point number to dump
17096     */
dump_float(number_float_t x)17097     void dump_float(number_float_t x)
17098     {
17099         // NaN / inf
17100         if (!std::isfinite(x))
17101         {
17102             o->write_characters("null", 4);
17103             return;
17104         }
17105 
17106         // If number_float_t is an IEEE-754 single or double precision number,
17107         // use the Grisu2 algorithm to produce short numbers which are
17108         // guaranteed to round-trip, using strtof and strtod, resp.
17109         //
17110         // NB: The test below works if <long double> == <double>.
17111         static constexpr bool is_ieee_single_or_double
17112             = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
17113               (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
17114 
17115         dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
17116     }
17117 
dump_float(number_float_t x,std::true_type)17118     void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
17119     {
17120         auto* begin = number_buffer.data();
17121         auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
17122 
17123         o->write_characters(begin, static_cast<size_t>(end - begin));
17124     }
17125 
dump_float(number_float_t x,std::false_type)17126     void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
17127     {
17128         // get number of digits for a float -> text -> float round-trip
17129         static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
17130 
17131         // the actual conversion
17132         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17133         std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
17134 
17135         // negative value indicates an error
17136         JSON_ASSERT(len > 0);
17137         // check if buffer was large enough
17138         JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
17139 
17140         // erase thousands separator
17141         if (thousands_sep != '\0')
17142         {
17143             auto* const end = std::remove(number_buffer.begin(),
17144                                           number_buffer.begin() + len, thousands_sep);
17145             std::fill(end, number_buffer.end(), '\0');
17146             JSON_ASSERT((end - number_buffer.begin()) <= len);
17147             len = (end - number_buffer.begin());
17148         }
17149 
17150         // convert decimal point to '.'
17151         if (decimal_point != '\0' && decimal_point != '.')
17152         {
17153             auto* const dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
17154             if (dec_pos != number_buffer.end())
17155             {
17156                 *dec_pos = '.';
17157             }
17158         }
17159 
17160         o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
17161 
17162         // determine if need to append ".0"
17163         const bool value_is_int_like =
17164             std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
17165                          [](char c)
17166         {
17167             return c == '.' || c == 'e';
17168         });
17169 
17170         if (value_is_int_like)
17171         {
17172             o->write_characters(".0", 2);
17173         }
17174     }
17175 
17176     /*!
17177     @brief check whether a string is UTF-8 encoded
17178 
17179     The function checks each byte of a string whether it is UTF-8 encoded. The
17180     result of the check is stored in the @a state parameter. The function must
17181     be called initially with state 0 (accept). State 1 means the string must
17182     be rejected, because the current byte is not allowed. If the string is
17183     completely processed, but the state is non-zero, the string ended
17184     prematurely; that is, the last byte indicated more bytes should have
17185     followed.
17186 
17187     @param[in,out] state  the state of the decoding
17188     @param[in,out] codep  codepoint (valid only if resulting state is UTF8_ACCEPT)
17189     @param[in] byte       next byte to decode
17190     @return               new state
17191 
17192     @note The function has been edited: a std::array is used.
17193 
17194     @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
17195     @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
17196     */
decode(std::uint8_t & state,std::uint32_t & codep,const std::uint8_t byte)17197     static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
17198     {
17199         static const std::array<std::uint8_t, 400> utf8d =
17200         {
17201             {
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, // 00..1F
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, // 20..3F
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, // 40..5F
17205                 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
17206                 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
17207                 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
17208                 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
17209                 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
17210                 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
17211                 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
17212                 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
17213                 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
17214                 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
17215                 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
17216             }
17217         };
17218 
17219         JSON_ASSERT(byte < utf8d.size());
17220         const std::uint8_t type = utf8d[byte];
17221 
17222         codep = (state != UTF8_ACCEPT)
17223                 ? (byte & 0x3fu) | (codep << 6u)
17224                 : (0xFFu >> type) & (byte);
17225 
17226         std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
17227         JSON_ASSERT(index < 400);
17228         state = utf8d[index];
17229         return state;
17230     }
17231 
17232     /*
17233      * Overload to make the compiler happy while it is instantiating
17234      * dump_integer for number_unsigned_t.
17235      * Must never be called.
17236      */
remove_sign(number_unsigned_t x)17237     number_unsigned_t remove_sign(number_unsigned_t x)
17238     {
17239         JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17240         return x; // LCOV_EXCL_LINE
17241     }
17242 
17243     /*
17244      * Helper function for dump_integer
17245      *
17246      * This function takes a negative signed integer and returns its absolute
17247      * value as unsigned integer. The plus/minus shuffling is necessary as we can
17248      * not directly remove the sign of an arbitrary signed integer as the
17249      * absolute values of INT_MIN and INT_MAX are usually not the same. See
17250      * #1708 for details.
17251      */
remove_sign(number_integer_t x)17252     inline number_unsigned_t remove_sign(number_integer_t x) noexcept
17253     {
17254         JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
17255         return static_cast<number_unsigned_t>(-(x + 1)) + 1;
17256     }
17257 
17258   private:
17259     /// the output of the serializer
17260     output_adapter_t<char> o = nullptr;
17261 
17262     /// a (hopefully) large enough character buffer
17263     std::array<char, 64> number_buffer{{}};
17264 
17265     /// the locale
17266     const std::lconv* loc = nullptr;
17267     /// the locale's thousand separator character
17268     const char thousands_sep = '\0';
17269     /// the locale's decimal point character
17270     const char decimal_point = '\0';
17271 
17272     /// string buffer
17273     std::array<char, 512> string_buffer{{}};
17274 
17275     /// the indentation character
17276     const char indent_char;
17277     /// the indentation string
17278     string_t indent_string;
17279 
17280     /// error_handler how to react on decoding errors
17281     const error_handler_t error_handler;
17282 };
17283 }  // namespace detail
17284 }  // namespace nlohmann
17285 
17286 // #include <nlohmann/detail/value_t.hpp>
17287 
17288 // #include <nlohmann/json_fwd.hpp>
17289 
17290 // #include <nlohmann/ordered_map.hpp>
17291 
17292 
17293 #include <functional> // less
17294 #include <initializer_list> // initializer_list
17295 #include <iterator> // input_iterator_tag, iterator_traits
17296 #include <memory> // allocator
17297 #include <stdexcept> // for out_of_range
17298 #include <type_traits> // enable_if, is_convertible
17299 #include <utility> // pair
17300 #include <vector> // vector
17301 
17302 // #include <nlohmann/detail/macro_scope.hpp>
17303 
17304 
17305 namespace nlohmann
17306 {
17307 
17308 /// ordered_map: a minimal map-like container that preserves insertion order
17309 /// for use within nlohmann::basic_json<ordered_map>
17310 template <class Key, class T, class IgnoredLess = std::less<Key>,
17311           class Allocator = std::allocator<std::pair<const Key, T>>>
17312                   struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
17313 {
17314     using key_type = Key;
17315     using mapped_type = T;
17316     using Container = std::vector<std::pair<const Key, T>, Allocator>;
17317     using typename Container::iterator;
17318     using typename Container::const_iterator;
17319     using typename Container::size_type;
17320     using typename Container::value_type;
17321 
17322     // Explicit constructors instead of `using Container::Container`
17323     // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
ordered_mapnlohmann::ordered_map17324     ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
17325     template <class It>
ordered_mapnlohmann::ordered_map17326     ordered_map(It first, It last, const Allocator& alloc = Allocator())
17327         : Container{first, last, alloc} {}
ordered_mapnlohmann::ordered_map17328     ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
17329         : Container{init, alloc} {}
17330 
emplacenlohmann::ordered_map17331     std::pair<iterator, bool> emplace(const key_type& key, T&& t)
17332     {
17333         for (auto it = this->begin(); it != this->end(); ++it)
17334         {
17335             if (it->first == key)
17336             {
17337                 return {it, false};
17338             }
17339         }
17340         Container::emplace_back(key, t);
17341         return {--this->end(), true};
17342     }
17343 
operator []nlohmann::ordered_map17344     T& operator[](const Key& key)
17345     {
17346         return emplace(key, T{}).first->second;
17347     }
17348 
operator []nlohmann::ordered_map17349     const T& operator[](const Key& key) const
17350     {
17351         return at(key);
17352     }
17353 
atnlohmann::ordered_map17354     T& at(const Key& key)
17355     {
17356         for (auto it = this->begin(); it != this->end(); ++it)
17357         {
17358             if (it->first == key)
17359             {
17360                 return it->second;
17361             }
17362         }
17363 
17364         JSON_THROW(std::out_of_range("key not found"));
17365     }
17366 
atnlohmann::ordered_map17367     const T& at(const Key& key) const
17368     {
17369         for (auto it = this->begin(); it != this->end(); ++it)
17370         {
17371             if (it->first == key)
17372             {
17373                 return it->second;
17374             }
17375         }
17376 
17377         JSON_THROW(std::out_of_range("key not found"));
17378     }
17379 
erasenlohmann::ordered_map17380     size_type erase(const Key& key)
17381     {
17382         for (auto it = this->begin(); it != this->end(); ++it)
17383         {
17384             if (it->first == key)
17385             {
17386                 // Since we cannot move const Keys, re-construct them in place
17387                 for (auto next = it; ++next != this->end(); ++it)
17388                 {
17389                     it->~value_type(); // Destroy but keep allocation
17390                     new (&*it) value_type{std::move(*next)};
17391                 }
17392                 Container::pop_back();
17393                 return 1;
17394             }
17395         }
17396         return 0;
17397     }
17398 
erasenlohmann::ordered_map17399     iterator erase(iterator pos)
17400     {
17401         auto it = pos;
17402 
17403         // Since we cannot move const Keys, re-construct them in place
17404         for (auto next = it; ++next != this->end(); ++it)
17405         {
17406             it->~value_type(); // Destroy but keep allocation
17407             new (&*it) value_type{std::move(*next)};
17408         }
17409         Container::pop_back();
17410         return pos;
17411     }
17412 
countnlohmann::ordered_map17413     size_type count(const Key& key) const
17414     {
17415         for (auto it = this->begin(); it != this->end(); ++it)
17416         {
17417             if (it->first == key)
17418             {
17419                 return 1;
17420             }
17421         }
17422         return 0;
17423     }
17424 
findnlohmann::ordered_map17425     iterator find(const Key& key)
17426     {
17427         for (auto it = this->begin(); it != this->end(); ++it)
17428         {
17429             if (it->first == key)
17430             {
17431                 return it;
17432             }
17433         }
17434         return Container::end();
17435     }
17436 
findnlohmann::ordered_map17437     const_iterator find(const Key& key) const
17438     {
17439         for (auto it = this->begin(); it != this->end(); ++it)
17440         {
17441             if (it->first == key)
17442             {
17443                 return it;
17444             }
17445         }
17446         return Container::end();
17447     }
17448 
insertnlohmann::ordered_map17449     std::pair<iterator, bool> insert( value_type&& value )
17450     {
17451         return emplace(value.first, std::move(value.second));
17452     }
17453 
insertnlohmann::ordered_map17454     std::pair<iterator, bool> insert( const value_type& value )
17455     {
17456         for (auto it = this->begin(); it != this->end(); ++it)
17457         {
17458             if (it->first == value.first)
17459             {
17460                 return {it, false};
17461             }
17462         }
17463         Container::push_back(value);
17464         return {--this->end(), true};
17465     }
17466 
17467     template<typename InputIt>
17468     using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
17469             std::input_iterator_tag>::value>::type;
17470 
17471     template<typename InputIt, typename = require_input_iter<InputIt>>
insertnlohmann::ordered_map17472     void insert(InputIt first, InputIt last)
17473     {
17474         for (auto it = first; it != last; ++it)
17475         {
17476             insert(*it);
17477         }
17478     }
17479 };
17480 
17481 }  // namespace nlohmann
17482 
17483 
17484 #if defined(JSON_HAS_CPP_17)
17485     #include <string_view>
17486 #endif
17487 
17488 /*!
17489 @brief namespace for Niels Lohmann
17490 @see https://github.com/nlohmann
17491 @since version 1.0.0
17492 */
17493 namespace nlohmann
17494 {
17495 
17496 /*!
17497 @brief a class to store JSON values
17498 
17499 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
17500 in @ref object_t)
17501 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
17502 in @ref array_t)
17503 @tparam StringType type for JSON strings and object keys (`std::string` by
17504 default; will be used in @ref string_t)
17505 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
17506 in @ref boolean_t)
17507 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
17508 default; will be used in @ref number_integer_t)
17509 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
17510 `uint64_t` by default; will be used in @ref number_unsigned_t)
17511 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
17512 default; will be used in @ref number_float_t)
17513 @tparam BinaryType type for packed binary data for compatibility with binary
17514 serialization formats (`std::vector<std::uint8_t>` by default; will be used in
17515 @ref binary_t)
17516 @tparam AllocatorType type of the allocator to use (`std::allocator` by
17517 default)
17518 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
17519 and `from_json()` (@ref adl_serializer by default)
17520 
17521 @requirement The class satisfies the following concept requirements:
17522 - Basic
17523  - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
17524    JSON values can be default constructed. The result will be a JSON null
17525    value.
17526  - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
17527    A JSON value can be constructed from an rvalue argument.
17528  - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
17529    A JSON value can be copy-constructed from an lvalue expression.
17530  - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
17531    A JSON value van be assigned from an rvalue argument.
17532  - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
17533    A JSON value can be copy-assigned from an lvalue expression.
17534  - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
17535    JSON values can be destructed.
17536 - Layout
17537  - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
17538    JSON values have
17539    [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
17540    All non-static data members are private and standard layout types, the
17541    class has no virtual functions or (virtual) base classes.
17542 - Library-wide
17543  - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
17544    JSON values can be compared with `==`, see @ref
17545    operator==(const_reference,const_reference).
17546  - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
17547    JSON values can be compared with `<`, see @ref
17548    operator<(const_reference,const_reference).
17549  - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
17550    Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
17551    other compatible types, using unqualified function call @ref swap().
17552  - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
17553    JSON values can be compared against `std::nullptr_t` objects which are used
17554    to model the `null` value.
17555 - Container
17556  - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
17557    JSON values can be used like STL containers and provide iterator access.
17558  - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
17559    JSON values can be used like STL containers and provide reverse iterator
17560    access.
17561 
17562 @invariant The member variables @a m_value and @a m_type have the following
17563 relationship:
17564 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
17565 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
17566 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
17567 The invariants are checked by member function assert_invariant().
17568 
17569 @internal
17570 @note ObjectType trick from https://stackoverflow.com/a/9860911
17571 @endinternal
17572 
17573 @see [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange
17574 Format](https://tools.ietf.org/html/rfc8259)
17575 
17576 @since version 1.0.0
17577 
17578 @nosubgrouping
17579 */
17580 NLOHMANN_BASIC_JSON_TPL_DECLARATION
17581 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
17582 {
17583   private:
17584     template<detail::value_t> friend struct detail::external_constructor;
17585     friend ::nlohmann::json_pointer<basic_json>;
17586 
17587     template<typename BasicJsonType, typename InputType>
17588     friend class ::nlohmann::detail::parser;
17589     friend ::nlohmann::detail::serializer<basic_json>;
17590     template<typename BasicJsonType>
17591     friend class ::nlohmann::detail::iter_impl;
17592     template<typename BasicJsonType, typename CharType>
17593     friend class ::nlohmann::detail::binary_writer;
17594     template<typename BasicJsonType, typename InputType, typename SAX>
17595     friend class ::nlohmann::detail::binary_reader;
17596     template<typename BasicJsonType>
17597     friend class ::nlohmann::detail::json_sax_dom_parser;
17598     template<typename BasicJsonType>
17599     friend class ::nlohmann::detail::json_sax_dom_callback_parser;
17600     friend class ::nlohmann::detail::exception;
17601 
17602     /// workaround type for MSVC
17603     using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
17604 
17605   JSON_PRIVATE_UNLESS_TESTED:
17606     // convenience aliases for types residing in namespace detail;
17607     using lexer = ::nlohmann::detail::lexer_base<basic_json>;
17608 
17609     template<typename InputAdapterType>
parser(InputAdapterType adapter,detail::parser_callback_t<basic_json> cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)17610     static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
17611         InputAdapterType adapter,
17612         detail::parser_callback_t<basic_json>cb = nullptr,
17613         const bool allow_exceptions = true,
17614         const bool ignore_comments = false
17615                                  )
17616     {
17617         return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
17618                 std::move(cb), allow_exceptions, ignore_comments);
17619     }
17620 
17621   private:
17622     using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
17623     template<typename BasicJsonType>
17624     using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
17625     template<typename BasicJsonType>
17626     using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
17627     template<typename Iterator>
17628     using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
17629     template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
17630 
17631     template<typename CharType>
17632     using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
17633 
17634     template<typename InputType>
17635     using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
17636     template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
17637 
17638   JSON_PRIVATE_UNLESS_TESTED:
17639     using serializer = ::nlohmann::detail::serializer<basic_json>;
17640 
17641   public:
17642     using value_t = detail::value_t;
17643     /// JSON Pointer, see @ref nlohmann::json_pointer
17644     using json_pointer = ::nlohmann::json_pointer<basic_json>;
17645     template<typename T, typename SFINAE>
17646     using json_serializer = JSONSerializer<T, SFINAE>;
17647     /// how to treat decoding errors
17648     using error_handler_t = detail::error_handler_t;
17649     /// how to treat CBOR tags
17650     using cbor_tag_handler_t = detail::cbor_tag_handler_t;
17651     /// helper type for initializer lists of basic_json values
17652     using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
17653 
17654     using input_format_t = detail::input_format_t;
17655     /// SAX interface type, see @ref nlohmann::json_sax
17656     using json_sax_t = json_sax<basic_json>;
17657 
17658     ////////////////
17659     // exceptions //
17660     ////////////////
17661 
17662     /// @name exceptions
17663     /// Classes to implement user-defined exceptions.
17664     /// @{
17665 
17666     /// @copydoc detail::exception
17667     using exception = detail::exception;
17668     /// @copydoc detail::parse_error
17669     using parse_error = detail::parse_error;
17670     /// @copydoc detail::invalid_iterator
17671     using invalid_iterator = detail::invalid_iterator;
17672     /// @copydoc detail::type_error
17673     using type_error = detail::type_error;
17674     /// @copydoc detail::out_of_range
17675     using out_of_range = detail::out_of_range;
17676     /// @copydoc detail::other_error
17677     using other_error = detail::other_error;
17678 
17679     /// @}
17680 
17681 
17682     /////////////////////
17683     // container types //
17684     /////////////////////
17685 
17686     /// @name container types
17687     /// The canonic container types to use @ref basic_json like any other STL
17688     /// container.
17689     /// @{
17690 
17691     /// the type of elements in a basic_json container
17692     using value_type = basic_json;
17693 
17694     /// the type of an element reference
17695     using reference = value_type&;
17696     /// the type of an element const reference
17697     using const_reference = const value_type&;
17698 
17699     /// a type to represent differences between iterators
17700     using difference_type = std::ptrdiff_t;
17701     /// a type to represent container sizes
17702     using size_type = std::size_t;
17703 
17704     /// the allocator type
17705     using allocator_type = AllocatorType<basic_json>;
17706 
17707     /// the type of an element pointer
17708     using pointer = typename std::allocator_traits<allocator_type>::pointer;
17709     /// the type of an element const pointer
17710     using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
17711 
17712     /// an iterator for a basic_json container
17713     using iterator = iter_impl<basic_json>;
17714     /// a const iterator for a basic_json container
17715     using const_iterator = iter_impl<const basic_json>;
17716     /// a reverse iterator for a basic_json container
17717     using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
17718     /// a const reverse iterator for a basic_json container
17719     using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
17720 
17721     /// @}
17722 
17723 
17724     /*!
17725     @brief returns the allocator associated with the container
17726     */
get_allocator()17727     static allocator_type get_allocator()
17728     {
17729         return allocator_type();
17730     }
17731 
17732     /*!
17733     @brief returns version information on the library
17734 
17735     This function returns a JSON object with information about the library,
17736     including the version number and information on the platform and compiler.
17737 
17738     @return JSON object holding version information
17739     key         | description
17740     ----------- | ---------------
17741     `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).
17742     `copyright` | The copyright line for the library as string.
17743     `name`      | The name of the library as string.
17744     `platform`  | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
17745     `url`       | The URL of the project as string.
17746     `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).
17747 
17748     @liveexample{The following code shows an example output of the `meta()`
17749     function.,meta}
17750 
17751     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17752     changes to any JSON value.
17753 
17754     @complexity Constant.
17755 
17756     @since 2.1.0
17757     */
17758     JSON_HEDLEY_WARN_UNUSED_RESULT
meta()17759     static basic_json meta()
17760     {
17761         basic_json result;
17762 
17763         result["copyright"] = "(C) 2013-2021 Niels Lohmann";
17764         result["name"] = "JSON for Modern C++";
17765         result["url"] = "https://github.com/nlohmann/json";
17766         result["version"]["string"] =
17767             std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
17768             std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
17769             std::to_string(NLOHMANN_JSON_VERSION_PATCH);
17770         result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
17771         result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
17772         result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
17773 
17774 #ifdef _WIN32
17775         result["platform"] = "win32";
17776 #elif defined __linux__
17777         result["platform"] = "linux";
17778 #elif defined __APPLE__
17779         result["platform"] = "apple";
17780 #elif defined __unix__
17781         result["platform"] = "unix";
17782 #else
17783         result["platform"] = "unknown";
17784 #endif
17785 
17786 #if defined(__ICC) || defined(__INTEL_COMPILER)
17787         result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
17788 #elif defined(__clang__)
17789         result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
17790 #elif defined(__GNUC__) || defined(__GNUG__)
17791         result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
17792 #elif defined(__HP_cc) || defined(__HP_aCC)
17793         result["compiler"] = "hp"
17794 #elif defined(__IBMCPP__)
17795         result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
17796 #elif defined(_MSC_VER)
17797         result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
17798 #elif defined(__PGI)
17799         result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
17800 #elif defined(__SUNPRO_CC)
17801         result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
17802 #else
17803         result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
17804 #endif
17805 
17806 #ifdef __cplusplus
17807         result["compiler"]["c++"] = std::to_string(__cplusplus);
17808 #else
17809         result["compiler"]["c++"] = "unknown";
17810 #endif
17811         return result;
17812     }
17813 
17814 
17815     ///////////////////////////
17816     // JSON value data types //
17817     ///////////////////////////
17818 
17819     /// @name JSON value data types
17820     /// The data types to store a JSON value. These types are derived from
17821     /// the template arguments passed to class @ref basic_json.
17822     /// @{
17823 
17824 #if defined(JSON_HAS_CPP_14)
17825     // Use transparent comparator if possible, combined with perfect forwarding
17826     // on find() and count() calls prevents unnecessary string construction.
17827     using object_comparator_t = std::less<>;
17828 #else
17829     using object_comparator_t = std::less<StringType>;
17830 #endif
17831 
17832     /*!
17833     @brief a type for an object
17834 
17835     [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows:
17836     > An object is an unordered collection of zero or more name/value pairs,
17837     > where a name is a string and a value is a string, number, boolean, null,
17838     > object, or array.
17839 
17840     To store objects in C++, a type is defined by the template parameters
17841     described below.
17842 
17843     @tparam ObjectType  the container to store objects (e.g., `std::map` or
17844     `std::unordered_map`)
17845     @tparam StringType the type of the keys or names (e.g., `std::string`).
17846     The comparison function `std::less<StringType>` is used to order elements
17847     inside the container.
17848     @tparam AllocatorType the allocator to use for objects (e.g.,
17849     `std::allocator`)
17850 
17851     #### Default type
17852 
17853     With the default values for @a ObjectType (`std::map`), @a StringType
17854     (`std::string`), and @a AllocatorType (`std::allocator`), the default
17855     value for @a object_t is:
17856 
17857     @code {.cpp}
17858     std::map<
17859       std::string, // key_type
17860       basic_json, // value_type
17861       std::less<std::string>, // key_compare
17862       std::allocator<std::pair<const std::string, basic_json>> // allocator_type
17863     >
17864     @endcode
17865 
17866     #### Behavior
17867 
17868     The choice of @a object_t influences the behavior of the JSON class. With
17869     the default type, objects have the following behavior:
17870 
17871     - When all names are unique, objects will be interoperable in the sense
17872       that all software implementations receiving that object will agree on
17873       the name-value mappings.
17874     - When the names within an object are not unique, it is unspecified which
17875       one of the values for a given key will be chosen. For instance,
17876       `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
17877       `{"key": 2}`.
17878     - Internally, name/value pairs are stored in lexicographical order of the
17879       names. Objects will also be serialized (see @ref dump) in this order.
17880       For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
17881       and serialized as `{"a": 2, "b": 1}`.
17882     - When comparing objects, the order of the name/value pairs is irrelevant.
17883       This makes objects interoperable in the sense that they will not be
17884       affected by these differences. For instance, `{"b": 1, "a": 2}` and
17885       `{"a": 2, "b": 1}` will be treated as equal.
17886 
17887     #### Limits
17888 
17889     [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
17890     > An implementation may set limits on the maximum depth of nesting.
17891 
17892     In this class, the object's limit of nesting is not explicitly constrained.
17893     However, a maximum depth of nesting may be introduced by the compiler or
17894     runtime environment. A theoretical limit can be queried by calling the
17895     @ref max_size function of a JSON object.
17896 
17897     #### Storage
17898 
17899     Objects are stored as pointers in a @ref basic_json type. That is, for any
17900     access to object values, a pointer of type `object_t*` must be
17901     dereferenced.
17902 
17903     @sa see @ref array_t -- type for an array value
17904 
17905     @since version 1.0.0
17906 
17907     @note The order name/value pairs are added to the object is *not*
17908     preserved by the library. Therefore, iterating an object may return
17909     name/value pairs in a different order than they were originally stored. In
17910     fact, keys will be traversed in alphabetical order as `std::map` with
17911     `std::less` is used by default. Please note this behavior conforms to [RFC
17912     8259](https://tools.ietf.org/html/rfc8259), because any order implements the
17913     specified "unordered" nature of JSON objects.
17914     */
17915     using object_t = ObjectType<StringType,
17916           basic_json,
17917           object_comparator_t,
17918           AllocatorType<std::pair<const StringType,
17919           basic_json>>>;
17920 
17921     /*!
17922     @brief a type for an array
17923 
17924     [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows:
17925     > An array is an ordered sequence of zero or more values.
17926 
17927     To store objects in C++, a type is defined by the template parameters
17928     explained below.
17929 
17930     @tparam ArrayType  container type to store arrays (e.g., `std::vector` or
17931     `std::list`)
17932     @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
17933 
17934     #### Default type
17935 
17936     With the default values for @a ArrayType (`std::vector`) and @a
17937     AllocatorType (`std::allocator`), the default value for @a array_t is:
17938 
17939     @code {.cpp}
17940     std::vector<
17941       basic_json, // value_type
17942       std::allocator<basic_json> // allocator_type
17943     >
17944     @endcode
17945 
17946     #### Limits
17947 
17948     [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
17949     > An implementation may set limits on the maximum depth of nesting.
17950 
17951     In this class, the array's limit of nesting is not explicitly constrained.
17952     However, a maximum depth of nesting may be introduced by the compiler or
17953     runtime environment. A theoretical limit can be queried by calling the
17954     @ref max_size function of a JSON array.
17955 
17956     #### Storage
17957 
17958     Arrays are stored as pointers in a @ref basic_json type. That is, for any
17959     access to array values, a pointer of type `array_t*` must be dereferenced.
17960 
17961     @sa see @ref object_t -- type for an object value
17962 
17963     @since version 1.0.0
17964     */
17965     using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17966 
17967     /*!
17968     @brief a type for a string
17969 
17970     [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows:
17971     > A string is a sequence of zero or more Unicode characters.
17972 
17973     To store objects in C++, a type is defined by the template parameter
17974     described below. Unicode values are split by the JSON class into
17975     byte-sized characters during deserialization.
17976 
17977     @tparam StringType  the container to store strings (e.g., `std::string`).
17978     Note this container is used for keys/names in objects, see @ref object_t.
17979 
17980     #### Default type
17981 
17982     With the default values for @a StringType (`std::string`), the default
17983     value for @a string_t is:
17984 
17985     @code {.cpp}
17986     std::string
17987     @endcode
17988 
17989     #### Encoding
17990 
17991     Strings are stored in UTF-8 encoding. Therefore, functions like
17992     `std::string::size()` or `std::string::length()` return the number of
17993     bytes in the string rather than the number of characters or glyphs.
17994 
17995     #### String comparison
17996 
17997     [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
17998     > Software implementations are typically required to test names of object
17999     > members for equality. Implementations that transform the textual
18000     > representation into sequences of Unicode code units and then perform the
18001     > comparison numerically, code unit by code unit, are interoperable in the
18002     > sense that implementations will agree in all cases on equality or
18003     > inequality of two strings. For example, implementations that compare
18004     > strings with escaped characters unconverted may incorrectly find that
18005     > `"a\\b"` and `"a\u005Cb"` are not equal.
18006 
18007     This implementation is interoperable as it does compare strings code unit
18008     by code unit.
18009 
18010     #### Storage
18011 
18012     String values are stored as pointers in a @ref basic_json type. That is,
18013     for any access to string values, a pointer of type `string_t*` must be
18014     dereferenced.
18015 
18016     @since version 1.0.0
18017     */
18018     using string_t = StringType;
18019 
18020     /*!
18021     @brief a type for a boolean
18022 
18023     [RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a
18024     type which differentiates the two literals `true` and `false`.
18025 
18026     To store objects in C++, a type is defined by the template parameter @a
18027     BooleanType which chooses the type to use.
18028 
18029     #### Default type
18030 
18031     With the default values for @a BooleanType (`bool`), the default value for
18032     @a boolean_t is:
18033 
18034     @code {.cpp}
18035     bool
18036     @endcode
18037 
18038     #### Storage
18039 
18040     Boolean values are stored directly inside a @ref basic_json type.
18041 
18042     @since version 1.0.0
18043     */
18044     using boolean_t = BooleanType;
18045 
18046     /*!
18047     @brief a type for a number (integer)
18048 
18049     [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18050     > The representation of numbers is similar to that used in most
18051     > programming languages. A number is represented in base 10 using decimal
18052     > digits. It contains an integer component that may be prefixed with an
18053     > optional minus sign, which may be followed by a fraction part and/or an
18054     > exponent part. Leading zeros are not allowed. (...) Numeric values that
18055     > cannot be represented in the grammar below (such as Infinity and NaN)
18056     > are not permitted.
18057 
18058     This description includes both integer and floating-point numbers.
18059     However, C++ allows more precise storage if it is known whether the number
18060     is a signed integer, an unsigned integer or a floating-point number.
18061     Therefore, three different types, @ref number_integer_t, @ref
18062     number_unsigned_t and @ref number_float_t are used.
18063 
18064     To store integer numbers in C++, a type is defined by the template
18065     parameter @a NumberIntegerType which chooses the type to use.
18066 
18067     #### Default type
18068 
18069     With the default values for @a NumberIntegerType (`int64_t`), the default
18070     value for @a number_integer_t is:
18071 
18072     @code {.cpp}
18073     int64_t
18074     @endcode
18075 
18076     #### Default behavior
18077 
18078     - The restrictions about leading zeros is not enforced in C++. Instead,
18079       leading zeros in integer literals lead to an interpretation as octal
18080       number. Internally, the value will be stored as decimal number. For
18081       instance, the C++ integer literal `010` will be serialized to `8`.
18082       During deserialization, leading zeros yield an error.
18083     - Not-a-number (NaN) values will be serialized to `null`.
18084 
18085     #### Limits
18086 
18087     [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
18088     > An implementation may set limits on the range and precision of numbers.
18089 
18090     When the default type is used, the maximal integer number that can be
18091     stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
18092     that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
18093     that are out of range will yield over/underflow when used in a
18094     constructor. During deserialization, too large or small integer numbers
18095     will be automatically be stored as @ref number_unsigned_t or @ref
18096     number_float_t.
18097 
18098     [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
18099     > Note that when such software is used, numbers that are integers and are
18100     > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
18101     > that implementations will agree exactly on their numeric values.
18102 
18103     As this range is a subrange of the exactly supported range [INT64_MIN,
18104     INT64_MAX], this class's integer type is interoperable.
18105 
18106     #### Storage
18107 
18108     Integer number values are stored directly inside a @ref basic_json type.
18109 
18110     @sa see @ref number_float_t -- type for number values (floating-point)
18111 
18112     @sa see @ref number_unsigned_t -- type for number values (unsigned integer)
18113 
18114     @since version 1.0.0
18115     */
18116     using number_integer_t = NumberIntegerType;
18117 
18118     /*!
18119     @brief a type for a number (unsigned)
18120 
18121     [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18122     > The representation of numbers is similar to that used in most
18123     > programming languages. A number is represented in base 10 using decimal
18124     > digits. It contains an integer component that may be prefixed with an
18125     > optional minus sign, which may be followed by a fraction part and/or an
18126     > exponent part. Leading zeros are not allowed. (...) Numeric values that
18127     > cannot be represented in the grammar below (such as Infinity and NaN)
18128     > are not permitted.
18129 
18130     This description includes both integer and floating-point numbers.
18131     However, C++ allows more precise storage if it is known whether the number
18132     is a signed integer, an unsigned integer or a floating-point number.
18133     Therefore, three different types, @ref number_integer_t, @ref
18134     number_unsigned_t and @ref number_float_t are used.
18135 
18136     To store unsigned integer numbers in C++, a type is defined by the
18137     template parameter @a NumberUnsignedType which chooses the type to use.
18138 
18139     #### Default type
18140 
18141     With the default values for @a NumberUnsignedType (`uint64_t`), the
18142     default value for @a number_unsigned_t is:
18143 
18144     @code {.cpp}
18145     uint64_t
18146     @endcode
18147 
18148     #### Default behavior
18149 
18150     - The restrictions about leading zeros is not enforced in C++. Instead,
18151       leading zeros in integer literals lead to an interpretation as octal
18152       number. Internally, the value will be stored as decimal number. For
18153       instance, the C++ integer literal `010` will be serialized to `8`.
18154       During deserialization, leading zeros yield an error.
18155     - Not-a-number (NaN) values will be serialized to `null`.
18156 
18157     #### Limits
18158 
18159     [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
18160     > An implementation may set limits on the range and precision of numbers.
18161 
18162     When the default type is used, the maximal integer number that can be
18163     stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
18164     number that can be stored is `0`. Integer numbers that are out of range
18165     will yield over/underflow when used in a constructor. During
18166     deserialization, too large or small integer numbers will be automatically
18167     be stored as @ref number_integer_t or @ref number_float_t.
18168 
18169     [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
18170     > Note that when such software is used, numbers that are integers and are
18171     > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
18172     > that implementations will agree exactly on their numeric values.
18173 
18174     As this range is a subrange (when considered in conjunction with the
18175     number_integer_t type) of the exactly supported range [0, UINT64_MAX],
18176     this class's integer type is interoperable.
18177 
18178     #### Storage
18179 
18180     Integer number values are stored directly inside a @ref basic_json type.
18181 
18182     @sa see @ref number_float_t -- type for number values (floating-point)
18183     @sa see @ref number_integer_t -- type for number values (integer)
18184 
18185     @since version 2.0.0
18186     */
18187     using number_unsigned_t = NumberUnsignedType;
18188 
18189     /*!
18190     @brief a type for a number (floating-point)
18191 
18192     [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18193     > The representation of numbers is similar to that used in most
18194     > programming languages. A number is represented in base 10 using decimal
18195     > digits. It contains an integer component that may be prefixed with an
18196     > optional minus sign, which may be followed by a fraction part and/or an
18197     > exponent part. Leading zeros are not allowed. (...) Numeric values that
18198     > cannot be represented in the grammar below (such as Infinity and NaN)
18199     > are not permitted.
18200 
18201     This description includes both integer and floating-point numbers.
18202     However, C++ allows more precise storage if it is known whether the number
18203     is a signed integer, an unsigned integer or a floating-point number.
18204     Therefore, three different types, @ref number_integer_t, @ref
18205     number_unsigned_t and @ref number_float_t are used.
18206 
18207     To store floating-point numbers in C++, a type is defined by the template
18208     parameter @a NumberFloatType which chooses the type to use.
18209 
18210     #### Default type
18211 
18212     With the default values for @a NumberFloatType (`double`), the default
18213     value for @a number_float_t is:
18214 
18215     @code {.cpp}
18216     double
18217     @endcode
18218 
18219     #### Default behavior
18220 
18221     - The restrictions about leading zeros is not enforced in C++. Instead,
18222       leading zeros in floating-point literals will be ignored. Internally,
18223       the value will be stored as decimal number. For instance, the C++
18224       floating-point literal `01.2` will be serialized to `1.2`. During
18225       deserialization, leading zeros yield an error.
18226     - Not-a-number (NaN) values will be serialized to `null`.
18227 
18228     #### Limits
18229 
18230     [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
18231     > This specification allows implementations to set limits on the range and
18232     > precision of numbers accepted. Since software that implements IEEE
18233     > 754-2008 binary64 (double precision) numbers is generally available and
18234     > widely used, good interoperability can be achieved by implementations
18235     > that expect no more precision or range than these provide, in the sense
18236     > that implementations will approximate JSON numbers within the expected
18237     > precision.
18238 
18239     This implementation does exactly follow this approach, as it uses double
18240     precision floating-point numbers. Note values smaller than
18241     `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
18242     will be stored as NaN internally and be serialized to `null`.
18243 
18244     #### Storage
18245 
18246     Floating-point number values are stored directly inside a @ref basic_json
18247     type.
18248 
18249     @sa see @ref number_integer_t -- type for number values (integer)
18250 
18251     @sa see @ref number_unsigned_t -- type for number values (unsigned integer)
18252 
18253     @since version 1.0.0
18254     */
18255     using number_float_t = NumberFloatType;
18256 
18257     /*!
18258     @brief a type for a packed binary type
18259 
18260     This type is a type designed to carry binary data that appears in various
18261     serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
18262     BSON's generic binary subtype. This type is NOT a part of standard JSON and
18263     exists solely for compatibility with these binary types. As such, it is
18264     simply defined as an ordered sequence of zero or more byte values.
18265 
18266     Additionally, as an implementation detail, the subtype of the binary data is
18267     carried around as a `std::uint8_t`, which is compatible with both of the
18268     binary data formats that use binary subtyping, (though the specific
18269     numbering is incompatible with each other, and it is up to the user to
18270     translate between them).
18271 
18272     [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
18273     as:
18274     > Major type 2: a byte string. The string's length in bytes is represented
18275     > following the rules for positive integers (major type 0).
18276 
18277     [MessagePack's documentation on the bin type
18278     family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
18279     describes this type as:
18280     > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes
18281     > in addition to the size of the byte array.
18282 
18283     [BSON's specifications](http://bsonspec.org/spec.html) describe several
18284     binary types; however, this type is intended to represent the generic binary
18285     type which has the description:
18286     > Generic binary subtype - This is the most commonly used binary subtype and
18287     > should be the 'default' for drivers and tools.
18288 
18289     None of these impose any limitations on the internal representation other
18290     than the basic unit of storage be some type of array whose parts are
18291     decomposable into bytes.
18292 
18293     The default representation of this binary format is a
18294     `std::vector<std::uint8_t>`, which is a very common way to represent a byte
18295     array in modern C++.
18296 
18297     #### Default type
18298 
18299     The default values for @a BinaryType is `std::vector<std::uint8_t>`
18300 
18301     #### Storage
18302 
18303     Binary Arrays are stored as pointers in a @ref basic_json type. That is,
18304     for any access to array values, a pointer of the type `binary_t*` must be
18305     dereferenced.
18306 
18307     #### Notes on subtypes
18308 
18309     - CBOR
18310        - Binary values are represented as byte strings. Subtypes are serialized
18311          as tagged values.
18312     - MessagePack
18313        - If a subtype is given and the binary array contains exactly 1, 2, 4, 8,
18314          or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8)
18315          is used. For other sizes, the ext family (ext8, ext16, ext32) is used.
18316          The subtype is then added as singed 8-bit integer.
18317        - If no subtype is given, the bin family (bin8, bin16, bin32) is used.
18318     - BSON
18319        - If a subtype is given, it is used and added as unsigned 8-bit integer.
18320        - If no subtype is given, the generic binary subtype 0x00 is used.
18321 
18322     @sa see @ref binary -- create a binary array
18323 
18324     @since version 3.8.0
18325     */
18326     using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
18327     /// @}
18328 
18329   private:
18330 
18331     /// helper for exception-safe object creation
18332     template<typename T, typename... Args>
18333     JSON_HEDLEY_RETURNS_NON_NULL
create(Args &&...args)18334     static T* create(Args&& ... args)
18335     {
18336         AllocatorType<T> alloc;
18337         using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18338 
18339         auto deleter = [&](T * obj)
18340         {
18341             AllocatorTraits::deallocate(alloc, obj, 1);
18342         };
18343         std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18344         AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18345         JSON_ASSERT(obj != nullptr);
18346         return obj.release();
18347     }
18348 
18349     ////////////////////////
18350     // JSON value storage //
18351     ////////////////////////
18352 
18353   JSON_PRIVATE_UNLESS_TESTED:
18354     /*!
18355     @brief a JSON value
18356 
18357     The actual storage for a JSON value of the @ref basic_json class. This
18358     union combines the different storage types for the JSON value types
18359     defined in @ref value_t.
18360 
18361     JSON type | value_t type    | used type
18362     --------- | --------------- | ------------------------
18363     object    | object          | pointer to @ref object_t
18364     array     | array           | pointer to @ref array_t
18365     string    | string          | pointer to @ref string_t
18366     boolean   | boolean         | @ref boolean_t
18367     number    | number_integer  | @ref number_integer_t
18368     number    | number_unsigned | @ref number_unsigned_t
18369     number    | number_float    | @ref number_float_t
18370     binary    | binary          | pointer to @ref binary_t
18371     null      | null            | *no value is stored*
18372 
18373     @note Variable-length types (objects, arrays, and strings) are stored as
18374     pointers. The size of the union should not exceed 64 bits if the default
18375     value types are used.
18376 
18377     @since version 1.0.0
18378     */
18379     union json_value
18380     {
18381         /// object (stored with pointer to save storage)
18382         object_t* object;
18383         /// array (stored with pointer to save storage)
18384         array_t* array;
18385         /// string (stored with pointer to save storage)
18386         string_t* string;
18387         /// binary (stored with pointer to save storage)
18388         binary_t* binary;
18389         /// boolean
18390         boolean_t boolean;
18391         /// number (integer)
18392         number_integer_t number_integer;
18393         /// number (unsigned integer)
18394         number_unsigned_t number_unsigned;
18395         /// number (floating-point)
18396         number_float_t number_float;
18397 
18398         /// default constructor (for null values)
18399         json_value() = default;
18400         /// constructor for booleans
json_value(boolean_t v)18401         json_value(boolean_t v) noexcept : boolean(v) {}
18402         /// constructor for numbers (integer)
json_value(number_integer_t v)18403         json_value(number_integer_t v) noexcept : number_integer(v) {}
18404         /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)18405         json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
18406         /// constructor for numbers (floating-point)
json_value(number_float_t v)18407         json_value(number_float_t v) noexcept : number_float(v) {}
18408         /// constructor for empty values of a given type
json_value(value_t t)18409         json_value(value_t t)
18410         {
18411             switch (t)
18412             {
18413                 case value_t::object:
18414                 {
18415                     object = create<object_t>();
18416                     break;
18417                 }
18418 
18419                 case value_t::array:
18420                 {
18421                     array = create<array_t>();
18422                     break;
18423                 }
18424 
18425                 case value_t::string:
18426                 {
18427                     string = create<string_t>("");
18428                     break;
18429                 }
18430 
18431                 case value_t::binary:
18432                 {
18433                     binary = create<binary_t>();
18434                     break;
18435                 }
18436 
18437                 case value_t::boolean:
18438                 {
18439                     boolean = boolean_t(false);
18440                     break;
18441                 }
18442 
18443                 case value_t::number_integer:
18444                 {
18445                     number_integer = number_integer_t(0);
18446                     break;
18447                 }
18448 
18449                 case value_t::number_unsigned:
18450                 {
18451                     number_unsigned = number_unsigned_t(0);
18452                     break;
18453                 }
18454 
18455                 case value_t::number_float:
18456                 {
18457                     number_float = number_float_t(0.0);
18458                     break;
18459                 }
18460 
18461                 case value_t::null:
18462                 {
18463                     object = nullptr;  // silence warning, see #821
18464                     break;
18465                 }
18466 
18467                 case value_t::discarded:
18468                 default:
18469                 {
18470                     object = nullptr;  // silence warning, see #821
18471                     if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
18472                     {
18473                         JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.2", basic_json())); // LCOV_EXCL_LINE
18474                     }
18475                     break;
18476                 }
18477             }
18478         }
18479 
18480         /// constructor for strings
json_value(const string_t & value)18481         json_value(const string_t& value)
18482         {
18483             string = create<string_t>(value);
18484         }
18485 
18486         /// constructor for rvalue strings
json_value(string_t && value)18487         json_value(string_t&& value)
18488         {
18489             string = create<string_t>(std::move(value));
18490         }
18491 
18492         /// constructor for objects
json_value(const object_t & value)18493         json_value(const object_t& value)
18494         {
18495             object = create<object_t>(value);
18496         }
18497 
18498         /// constructor for rvalue objects
json_value(object_t && value)18499         json_value(object_t&& value)
18500         {
18501             object = create<object_t>(std::move(value));
18502         }
18503 
18504         /// constructor for arrays
json_value(const array_t & value)18505         json_value(const array_t& value)
18506         {
18507             array = create<array_t>(value);
18508         }
18509 
18510         /// constructor for rvalue arrays
json_value(array_t && value)18511         json_value(array_t&& value)
18512         {
18513             array = create<array_t>(std::move(value));
18514         }
18515 
18516         /// constructor for binary arrays
json_value(const typename binary_t::container_type & value)18517         json_value(const typename binary_t::container_type& value)
18518         {
18519             binary = create<binary_t>(value);
18520         }
18521 
18522         /// constructor for rvalue binary arrays
json_value(typename binary_t::container_type && value)18523         json_value(typename binary_t::container_type&& value)
18524         {
18525             binary = create<binary_t>(std::move(value));
18526         }
18527 
18528         /// constructor for binary arrays (internal type)
json_value(const binary_t & value)18529         json_value(const binary_t& value)
18530         {
18531             binary = create<binary_t>(value);
18532         }
18533 
18534         /// constructor for rvalue binary arrays (internal type)
json_value(binary_t && value)18535         json_value(binary_t&& value)
18536         {
18537             binary = create<binary_t>(std::move(value));
18538         }
18539 
destroy(value_t t)18540         void destroy(value_t t)
18541         {
18542             if (t == value_t::array || t == value_t::object)
18543             {
18544                 // flatten the current json_value to a heap-allocated stack
18545                 std::vector<basic_json> stack;
18546 
18547                 // move the top-level items to stack
18548                 if (t == value_t::array)
18549                 {
18550                     stack.reserve(array->size());
18551                     std::move(array->begin(), array->end(), std::back_inserter(stack));
18552                 }
18553                 else
18554                 {
18555                     stack.reserve(object->size());
18556                     for (auto&& it : *object)
18557                     {
18558                         stack.push_back(std::move(it.second));
18559                     }
18560                 }
18561 
18562                 while (!stack.empty())
18563                 {
18564                     // move the last item to local variable to be processed
18565                     basic_json current_item(std::move(stack.back()));
18566                     stack.pop_back();
18567 
18568                     // if current_item is array/object, move
18569                     // its children to the stack to be processed later
18570                     if (current_item.is_array())
18571                     {
18572                         std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
18573 
18574                         current_item.m_value.array->clear();
18575                     }
18576                     else if (current_item.is_object())
18577                     {
18578                         for (auto&& it : *current_item.m_value.object)
18579                         {
18580                             stack.push_back(std::move(it.second));
18581                         }
18582 
18583                         current_item.m_value.object->clear();
18584                     }
18585 
18586                     // it's now safe that current_item get destructed
18587                     // since it doesn't have any children
18588                 }
18589             }
18590 
18591             switch (t)
18592             {
18593                 case value_t::object:
18594                 {
18595                     AllocatorType<object_t> alloc;
18596                     std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18597                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18598                     break;
18599                 }
18600 
18601                 case value_t::array:
18602                 {
18603                     AllocatorType<array_t> alloc;
18604                     std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18605                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18606                     break;
18607                 }
18608 
18609                 case value_t::string:
18610                 {
18611                     AllocatorType<string_t> alloc;
18612                     std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18613                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18614                     break;
18615                 }
18616 
18617                 case value_t::binary:
18618                 {
18619                     AllocatorType<binary_t> alloc;
18620                     std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18621                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18622                     break;
18623                 }
18624 
18625                 case value_t::null:
18626                 case value_t::boolean:
18627                 case value_t::number_integer:
18628                 case value_t::number_unsigned:
18629                 case value_t::number_float:
18630                 case value_t::discarded:
18631                 default:
18632                 {
18633                     break;
18634                 }
18635             }
18636         }
18637     };
18638 
18639   private:
18640     /*!
18641     @brief checks the class invariants
18642 
18643     This function asserts the class invariants. It needs to be called at the
18644     end of every constructor to make sure that created objects respect the
18645     invariant. Furthermore, it has to be called each time the type of a JSON
18646     value is changed, because the invariant expresses a relationship between
18647     @a m_type and @a m_value.
18648 
18649     Furthermore, the parent relation is checked for arrays and objects: If
18650     @a check_parents true and the value is an array or object, then the
18651     container's elements must have the current value as parent.
18652 
18653     @param[in] check_parents  whether the parent relation should be checked.
18654                The value is true by default and should only be set to false
18655                during destruction of objects when the invariant does not
18656                need to hold.
18657     */
assert_invariant(bool check_parents=true) const18658     void assert_invariant(bool check_parents = true) const noexcept
18659     {
18660         JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18661         JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18662         JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18663         JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18664 
18665 #if JSON_DIAGNOSTICS
18666         JSON_TRY
18667         {
18668             // cppcheck-suppress assertWithSideEffect
18669             JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
18670             {
18671                 return j.m_parent == this;
18672             }));
18673         }
18674         JSON_CATCH(...) {} // LCOV_EXCL_LINE
18675 #endif
18676         static_cast<void>(check_parents);
18677     }
18678 
set_parents()18679     void set_parents()
18680     {
18681 #if JSON_DIAGNOSTICS
18682         switch (m_type)
18683         {
18684             case value_t::array:
18685             {
18686                 for (auto& element : *m_value.array)
18687                 {
18688                     element.m_parent = this;
18689                 }
18690                 break;
18691             }
18692 
18693             case value_t::object:
18694             {
18695                 for (auto& element : *m_value.object)
18696                 {
18697                     element.second.m_parent = this;
18698                 }
18699                 break;
18700             }
18701 
18702             case value_t::null:
18703             case value_t::string:
18704             case value_t::boolean:
18705             case value_t::number_integer:
18706             case value_t::number_unsigned:
18707             case value_t::number_float:
18708             case value_t::binary:
18709             case value_t::discarded:
18710             default:
18711                 break;
18712         }
18713 #endif
18714     }
18715 
set_parents(iterator it,typename iterator::difference_type count)18716     iterator set_parents(iterator it, typename iterator::difference_type count)
18717     {
18718 #if JSON_DIAGNOSTICS
18719         for (typename iterator::difference_type i = 0; i < count; ++i)
18720         {
18721             (it + i)->m_parent = this;
18722         }
18723 #else
18724         static_cast<void>(count);
18725 #endif
18726         return it;
18727     }
18728 
set_parent(reference j,std::size_t old_capacity=std::size_t (-1))18729     reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1))
18730     {
18731 #if JSON_DIAGNOSTICS
18732         if (old_capacity != std::size_t(-1))
18733         {
18734             // see https://github.com/nlohmann/json/issues/2838
18735             JSON_ASSERT(type() == value_t::array);
18736             if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
18737             {
18738                 // capacity has changed: update all parents
18739                 set_parents();
18740                 return j;
18741             }
18742         }
18743 
18744         // ordered_json uses a vector internally, so pointers could have
18745         // been invalidated; see https://github.com/nlohmann/json/issues/2962
18746 #ifdef JSON_HEDLEY_MSVC_VERSION
18747 #pragma warning(push )
18748 #pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
18749 #endif
18750         if (detail::is_ordered_map<object_t>::value)
18751         {
18752             set_parents();
18753             return j;
18754         }
18755 #ifdef JSON_HEDLEY_MSVC_VERSION
18756 #pragma warning( pop )
18757 #endif
18758 
18759         j.m_parent = this;
18760 #else
18761         static_cast<void>(j);
18762         static_cast<void>(old_capacity);
18763 #endif
18764         return j;
18765     }
18766 
18767   public:
18768     //////////////////////////
18769     // JSON parser callback //
18770     //////////////////////////
18771 
18772     /*!
18773     @brief parser event types
18774 
18775     The parser callback distinguishes the following events:
18776     - `object_start`: the parser read `{` and started to process a JSON object
18777     - `key`: the parser read a key of a value in an object
18778     - `object_end`: the parser read `}` and finished processing a JSON object
18779     - `array_start`: the parser read `[` and started to process a JSON array
18780     - `array_end`: the parser read `]` and finished processing a JSON array
18781     - `value`: the parser finished reading a JSON value
18782 
18783     @image html callback_events.png "Example when certain parse events are triggered"
18784 
18785     @sa see @ref parser_callback_t for more information and examples
18786     */
18787     using parse_event_t = detail::parse_event_t;
18788 
18789     /*!
18790     @brief per-element parser callback type
18791 
18792     With a parser callback function, the result of parsing a JSON text can be
18793     influenced. When passed to @ref parse, it is called on certain events
18794     (passed as @ref parse_event_t via parameter @a event) with a set recursion
18795     depth @a depth and context JSON value @a parsed. The return value of the
18796     callback function is a boolean indicating whether the element that emitted
18797     the callback shall be kept or not.
18798 
18799     We distinguish six scenarios (determined by the event type) in which the
18800     callback function can be called. The following table describes the values
18801     of the parameters @a depth, @a event, and @a parsed.
18802 
18803     parameter @a event | description | parameter @a depth | parameter @a parsed
18804     ------------------ | ----------- | ------------------ | -------------------
18805     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
18806     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
18807     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
18808     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
18809     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
18810     parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
18811 
18812     @image html callback_events.png "Example when certain parse events are triggered"
18813 
18814     Discarding a value (i.e., returning `false`) has different effects
18815     depending on the context in which function was called:
18816 
18817     - Discarded values in structured types are skipped. That is, the parser
18818       will behave as if the discarded value was never read.
18819     - In case a value outside a structured type is skipped, it is replaced
18820       with `null`. This case happens if the top-level element is skipped.
18821 
18822     @param[in] depth  the depth of the recursion during parsing
18823 
18824     @param[in] event  an event of type parse_event_t indicating the context in
18825     the callback function has been called
18826 
18827     @param[in,out] parsed  the current intermediate parse result; note that
18828     writing to this value has no effect for parse_event_t::key events
18829 
18830     @return Whether the JSON value which called the function during parsing
18831     should be kept (`true`) or not (`false`). In the latter case, it is either
18832     skipped completely or replaced by an empty discarded object.
18833 
18834     @sa see @ref parse for examples
18835 
18836     @since version 1.0.0
18837     */
18838     using parser_callback_t = detail::parser_callback_t<basic_json>;
18839 
18840     //////////////////
18841     // constructors //
18842     //////////////////
18843 
18844     /// @name constructors and destructors
18845     /// Constructors of class @ref basic_json, copy/move constructor, copy
18846     /// assignment, static functions creating objects, and the destructor.
18847     /// @{
18848 
18849     /*!
18850     @brief create an empty value with a given type
18851 
18852     Create an empty JSON value with a given type. The value will be default
18853     initialized with an empty value which depends on the type:
18854 
18855     Value type  | initial value
18856     ----------- | -------------
18857     null        | `null`
18858     boolean     | `false`
18859     string      | `""`
18860     number      | `0`
18861     object      | `{}`
18862     array       | `[]`
18863     binary      | empty array
18864 
18865     @param[in] v  the type of the value to create
18866 
18867     @complexity Constant.
18868 
18869     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18870     changes to any JSON value.
18871 
18872     @liveexample{The following code shows the constructor for different @ref
18873     value_t values,basic_json__value_t}
18874 
18875     @sa see @ref clear() -- restores the postcondition of this constructor
18876 
18877     @since version 1.0.0
18878     */
basic_json(const value_t v)18879     basic_json(const value_t v)
18880         : m_type(v), m_value(v)
18881     {
18882         assert_invariant();
18883     }
18884 
18885     /*!
18886     @brief create a null object
18887 
18888     Create a `null` JSON value. It either takes a null pointer as parameter
18889     (explicitly creating `null`) or no parameter (implicitly creating `null`).
18890     The passed null pointer itself is not read -- it is only used to choose
18891     the right constructor.
18892 
18893     @complexity Constant.
18894 
18895     @exceptionsafety No-throw guarantee: this constructor never throws
18896     exceptions.
18897 
18898     @liveexample{The following code shows the constructor with and without a
18899     null pointer parameter.,basic_json__nullptr_t}
18900 
18901     @since version 1.0.0
18902     */
basic_json(std::nullptr_t=nullptr)18903     basic_json(std::nullptr_t = nullptr) noexcept
18904         : basic_json(value_t::null)
18905     {
18906         assert_invariant();
18907     }
18908 
18909     /*!
18910     @brief create a JSON value
18911 
18912     This is a "catch all" constructor for all compatible JSON types; that is,
18913     types for which a `to_json()` method exists. The constructor forwards the
18914     parameter @a val to that method (to `json_serializer<U>::to_json` method
18915     with `U = uncvref_t<CompatibleType>`, to be exact).
18916 
18917     Template type @a CompatibleType includes, but is not limited to, the
18918     following types:
18919     - **arrays**: @ref array_t and all kinds of compatible containers such as
18920       `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
18921       `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
18922       `std::multiset`, and `std::unordered_multiset` with a `value_type` from
18923       which a @ref basic_json value can be constructed.
18924     - **objects**: @ref object_t and all kinds of compatible associative
18925       containers such as `std::map`, `std::unordered_map`, `std::multimap`,
18926       and `std::unordered_multimap` with a `key_type` compatible to
18927       @ref string_t and a `value_type` from which a @ref basic_json value can
18928       be constructed.
18929     - **strings**: @ref string_t, string literals, and all compatible string
18930       containers can be used.
18931     - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
18932       @ref number_float_t, and all convertible number types such as `int`,
18933       `size_t`, `int64_t`, `float` or `double` can be used.
18934     - **boolean**: @ref boolean_t / `bool` can be used.
18935     - **binary**: @ref binary_t / `std::vector<std::uint8_t>` may be used,
18936       unfortunately because string literals cannot be distinguished from binary
18937       character arrays by the C++ type system, all types compatible with `const
18938       char*` will be directed to the string constructor instead.  This is both
18939       for backwards compatibility, and due to the fact that a binary type is not
18940       a standard JSON type.
18941 
18942     See the examples below.
18943 
18944     @tparam CompatibleType a type such that:
18945     - @a CompatibleType is not derived from `std::istream`,
18946     - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
18947          constructors),
18948     - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
18949     - @a CompatibleType is not a @ref basic_json nested type (e.g.,
18950          @ref json_pointer, @ref iterator, etc ...)
18951     - `json_serializer<U>` has a `to_json(basic_json_t&, CompatibleType&&)` method
18952 
18953     @tparam U = `uncvref_t<CompatibleType>`
18954 
18955     @param[in] val the value to be forwarded to the respective constructor
18956 
18957     @complexity Usually linear in the size of the passed @a val, also
18958                 depending on the implementation of the called `to_json()`
18959                 method.
18960 
18961     @exceptionsafety Depends on the called constructor. For types directly
18962     supported by the library (i.e., all types for which no `to_json()` function
18963     was provided), strong guarantee holds: if an exception is thrown, there are
18964     no changes to any JSON value.
18965 
18966     @liveexample{The following code shows the constructor with several
18967     compatible types.,basic_json__CompatibleType}
18968 
18969     @since version 2.1.0
18970     */
18971     template < typename CompatibleType,
18972                typename U = detail::uncvref_t<CompatibleType>,
18973                detail::enable_if_t <
18974                    !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
basic_json(CompatibleType && val)18975     basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
18976                 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
18977                                            std::forward<CompatibleType>(val))))
18978     {
18979         JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
18980         set_parents();
18981         assert_invariant();
18982     }
18983 
18984     /*!
18985     @brief create a JSON value from an existing one
18986 
18987     This is a constructor for existing @ref basic_json types.
18988     It does not hijack copy/move constructors, since the parameter has different
18989     template arguments than the current ones.
18990 
18991     The constructor tries to convert the internal @ref m_value of the parameter.
18992 
18993     @tparam BasicJsonType a type such that:
18994     - @a BasicJsonType is a @ref basic_json type.
18995     - @a BasicJsonType has different template arguments than @ref basic_json_t.
18996 
18997     @param[in] val the @ref basic_json value to be converted.
18998 
18999     @complexity Usually linear in the size of the passed @a val, also
19000                 depending on the implementation of the called `to_json()`
19001                 method.
19002 
19003     @exceptionsafety Depends on the called constructor. For types directly
19004     supported by the library (i.e., all types for which no `to_json()` function
19005     was provided), strong guarantee holds: if an exception is thrown, there are
19006     no changes to any JSON value.
19007 
19008     @since version 3.2.0
19009     */
19010     template < typename BasicJsonType,
19011                detail::enable_if_t <
19012                    detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
basic_json(const BasicJsonType & val)19013     basic_json(const BasicJsonType& val)
19014     {
19015         using other_boolean_t = typename BasicJsonType::boolean_t;
19016         using other_number_float_t = typename BasicJsonType::number_float_t;
19017         using other_number_integer_t = typename BasicJsonType::number_integer_t;
19018         using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
19019         using other_string_t = typename BasicJsonType::string_t;
19020         using other_object_t = typename BasicJsonType::object_t;
19021         using other_array_t = typename BasicJsonType::array_t;
19022         using other_binary_t = typename BasicJsonType::binary_t;
19023 
19024         switch (val.type())
19025         {
19026             case value_t::boolean:
19027                 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
19028                 break;
19029             case value_t::number_float:
19030                 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
19031                 break;
19032             case value_t::number_integer:
19033                 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
19034                 break;
19035             case value_t::number_unsigned:
19036                 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
19037                 break;
19038             case value_t::string:
19039                 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
19040                 break;
19041             case value_t::object:
19042                 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
19043                 break;
19044             case value_t::array:
19045                 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
19046                 break;
19047             case value_t::binary:
19048                 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
19049                 break;
19050             case value_t::null:
19051                 *this = nullptr;
19052                 break;
19053             case value_t::discarded:
19054                 m_type = value_t::discarded;
19055                 break;
19056             default:            // LCOV_EXCL_LINE
19057                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19058         }
19059         set_parents();
19060         assert_invariant();
19061     }
19062 
19063     /*!
19064     @brief create a container (array or object) from an initializer list
19065 
19066     Creates a JSON value of type array or object from the passed initializer
19067     list @a init. In case @a type_deduction is `true` (default), the type of
19068     the JSON value to be created is deducted from the initializer list @a init
19069     according to the following rules:
19070 
19071     1. If the list is empty, an empty JSON object value `{}` is created.
19072     2. If the list consists of pairs whose first element is a string, a JSON
19073        object value is created where the first elements of the pairs are
19074        treated as keys and the second elements are as values.
19075     3. In all other cases, an array is created.
19076 
19077     The rules aim to create the best fit between a C++ initializer list and
19078     JSON values. The rationale is as follows:
19079 
19080     1. The empty initializer list is written as `{}` which is exactly an empty
19081        JSON object.
19082     2. C++ has no way of describing mapped types other than to list a list of
19083        pairs. As JSON requires that keys must be of type string, rule 2 is the
19084        weakest constraint one can pose on initializer lists to interpret them
19085        as an object.
19086     3. In all other cases, the initializer list could not be interpreted as
19087        JSON object type, so interpreting it as JSON array type is safe.
19088 
19089     With the rules described above, the following JSON values cannot be
19090     expressed by an initializer list:
19091 
19092     - the empty array (`[]`): use @ref array(initializer_list_t)
19093       with an empty initializer list in this case
19094     - arrays whose elements satisfy rule 2: use @ref
19095       array(initializer_list_t) with the same initializer list
19096       in this case
19097 
19098     @note When used without parentheses around an empty initializer list, @ref
19099     basic_json() is called instead of this function, yielding the JSON null
19100     value.
19101 
19102     @param[in] init  initializer list with JSON values
19103 
19104     @param[in] type_deduction internal parameter; when set to `true`, the type
19105     of the JSON value is deducted from the initializer list @a init; when set
19106     to `false`, the type provided via @a manual_type is forced. This mode is
19107     used by the functions @ref array(initializer_list_t) and
19108     @ref object(initializer_list_t).
19109 
19110     @param[in] manual_type internal parameter; when @a type_deduction is set
19111     to `false`, the created JSON value will use the provided type (only @ref
19112     value_t::array and @ref value_t::object are valid); when @a type_deduction
19113     is set to `true`, this parameter has no effect
19114 
19115     @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
19116     `value_t::object`, but @a init contains an element which is not a pair
19117     whose first element is a string. In this case, the constructor could not
19118     create an object. If @a type_deduction would have be `true`, an array
19119     would have been created. See @ref object(initializer_list_t)
19120     for an example.
19121 
19122     @complexity Linear in the size of the initializer list @a init.
19123 
19124     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19125     changes to any JSON value.
19126 
19127     @liveexample{The example below shows how JSON values are created from
19128     initializer lists.,basic_json__list_init_t}
19129 
19130     @sa see @ref array(initializer_list_t) -- create a JSON array
19131     value from an initializer list
19132     @sa see @ref object(initializer_list_t) -- create a JSON object
19133     value from an initializer list
19134 
19135     @since version 1.0.0
19136     */
basic_json(initializer_list_t init,bool type_deduction=true,value_t manual_type=value_t::array)19137     basic_json(initializer_list_t init,
19138                bool type_deduction = true,
19139                value_t manual_type = value_t::array)
19140     {
19141         // check if each element is an array with two elements whose first
19142         // element is a string
19143         bool is_an_object = std::all_of(init.begin(), init.end(),
19144                                         [](const detail::json_ref<basic_json>& element_ref)
19145         {
19146             return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19147         });
19148 
19149         // adjust type if type deduction is not wanted
19150         if (!type_deduction)
19151         {
19152             // if array is wanted, do not create an object though possible
19153             if (manual_type == value_t::array)
19154             {
19155                 is_an_object = false;
19156             }
19157 
19158             // if object is wanted but impossible, throw an exception
19159             if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19160             {
19161                 JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
19162             }
19163         }
19164 
19165         if (is_an_object)
19166         {
19167             // the initializer list is a list of pairs -> create object
19168             m_type = value_t::object;
19169             m_value = value_t::object;
19170 
19171             for (auto& element_ref : init)
19172             {
19173                 auto element = element_ref.moved_or_copied();
19174                 m_value.object->emplace(
19175                     std::move(*((*element.m_value.array)[0].m_value.string)),
19176                     std::move((*element.m_value.array)[1]));
19177             }
19178         }
19179         else
19180         {
19181             // the initializer list describes an array -> create array
19182             m_type = value_t::array;
19183             m_value.array = create<array_t>(init.begin(), init.end());
19184         }
19185 
19186         set_parents();
19187         assert_invariant();
19188     }
19189 
19190     /*!
19191     @brief explicitly create a binary array (without subtype)
19192 
19193     Creates a JSON binary array value from a given binary container. Binary
19194     values are part of various binary formats, such as CBOR, MessagePack, and
19195     BSON. This constructor is used to create a value for serialization to those
19196     formats.
19197 
19198     @note Note, this function exists because of the difficulty in correctly
19199     specifying the correct template overload in the standard value ctor, as both
19200     JSON arrays and JSON binary arrays are backed with some form of a
19201     `std::vector`. Because JSON binary arrays are a non-standard extension it
19202     was decided that it would be best to prevent automatic initialization of a
19203     binary array type, for backwards compatibility and so it does not happen on
19204     accident.
19205 
19206     @param[in] init container containing bytes to use as binary type
19207 
19208     @return JSON binary array value
19209 
19210     @complexity Linear in the size of @a init.
19211 
19212     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19213     changes to any JSON value.
19214 
19215     @since version 3.8.0
19216     */
19217     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(const typename binary_t::container_type & init)19218     static basic_json binary(const typename binary_t::container_type& init)
19219     {
19220         auto res = basic_json();
19221         res.m_type = value_t::binary;
19222         res.m_value = init;
19223         return res;
19224     }
19225 
19226     /*!
19227     @brief explicitly create a binary array (with subtype)
19228 
19229     Creates a JSON binary array value from a given binary container. Binary
19230     values are part of various binary formats, such as CBOR, MessagePack, and
19231     BSON. This constructor is used to create a value for serialization to those
19232     formats.
19233 
19234     @note Note, this function exists because of the difficulty in correctly
19235     specifying the correct template overload in the standard value ctor, as both
19236     JSON arrays and JSON binary arrays are backed with some form of a
19237     `std::vector`. Because JSON binary arrays are a non-standard extension it
19238     was decided that it would be best to prevent automatic initialization of a
19239     binary array type, for backwards compatibility and so it does not happen on
19240     accident.
19241 
19242     @param[in] init container containing bytes to use as binary type
19243     @param[in] subtype subtype to use in MessagePack and BSON
19244 
19245     @return JSON binary array value
19246 
19247     @complexity Linear in the size of @a init.
19248 
19249     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19250     changes to any JSON value.
19251 
19252     @since version 3.8.0
19253     */
19254     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(const typename binary_t::container_type & init,typename binary_t::subtype_type subtype)19255     static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
19256     {
19257         auto res = basic_json();
19258         res.m_type = value_t::binary;
19259         res.m_value = binary_t(init, subtype);
19260         return res;
19261     }
19262 
19263     /// @copydoc binary(const typename binary_t::container_type&)
19264     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(typename binary_t::container_type && init)19265     static basic_json binary(typename binary_t::container_type&& init)
19266     {
19267         auto res = basic_json();
19268         res.m_type = value_t::binary;
19269         res.m_value = std::move(init);
19270         return res;
19271     }
19272 
19273     /// @copydoc binary(const typename binary_t::container_type&, typename binary_t::subtype_type)
19274     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(typename binary_t::container_type && init,typename binary_t::subtype_type subtype)19275     static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
19276     {
19277         auto res = basic_json();
19278         res.m_type = value_t::binary;
19279         res.m_value = binary_t(std::move(init), subtype);
19280         return res;
19281     }
19282 
19283     /*!
19284     @brief explicitly create an array from an initializer list
19285 
19286     Creates a JSON array value from a given initializer list. That is, given a
19287     list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
19288     initializer list is empty, the empty array `[]` is created.
19289 
19290     @note This function is only needed to express two edge cases that cannot
19291     be realized with the initializer list constructor (@ref
19292     basic_json(initializer_list_t, bool, value_t)). These cases
19293     are:
19294     1. creating an array whose elements are all pairs whose first element is a
19295     string -- in this case, the initializer list constructor would create an
19296     object, taking the first elements as keys
19297     2. creating an empty array -- passing the empty initializer list to the
19298     initializer list constructor yields an empty object
19299 
19300     @param[in] init  initializer list with JSON values to create an array from
19301     (optional)
19302 
19303     @return JSON array value
19304 
19305     @complexity Linear in the size of @a init.
19306 
19307     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19308     changes to any JSON value.
19309 
19310     @liveexample{The following code shows an example for the `array`
19311     function.,array}
19312 
19313     @sa see @ref basic_json(initializer_list_t, bool, value_t) --
19314     create a JSON value from an initializer list
19315     @sa see @ref object(initializer_list_t) -- create a JSON object
19316     value from an initializer list
19317 
19318     @since version 1.0.0
19319     */
19320     JSON_HEDLEY_WARN_UNUSED_RESULT
array(initializer_list_t init={})19321     static basic_json array(initializer_list_t init = {})
19322     {
19323         return basic_json(init, false, value_t::array);
19324     }
19325 
19326     /*!
19327     @brief explicitly create an object from an initializer list
19328 
19329     Creates a JSON object value from a given initializer list. The initializer
19330     lists elements must be pairs, and their first elements must be strings. If
19331     the initializer list is empty, the empty object `{}` is created.
19332 
19333     @note This function is only added for symmetry reasons. In contrast to the
19334     related function @ref array(initializer_list_t), there are
19335     no cases which can only be expressed by this function. That is, any
19336     initializer list @a init can also be passed to the initializer list
19337     constructor @ref basic_json(initializer_list_t, bool, value_t).
19338 
19339     @param[in] init  initializer list to create an object from (optional)
19340 
19341     @return JSON object value
19342 
19343     @throw type_error.301 if @a init is not a list of pairs whose first
19344     elements are strings. In this case, no object can be created. When such a
19345     value is passed to @ref basic_json(initializer_list_t, bool, value_t),
19346     an array would have been created from the passed initializer list @a init.
19347     See example below.
19348 
19349     @complexity Linear in the size of @a init.
19350 
19351     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19352     changes to any JSON value.
19353 
19354     @liveexample{The following code shows an example for the `object`
19355     function.,object}
19356 
19357     @sa see @ref basic_json(initializer_list_t, bool, value_t) --
19358     create a JSON value from an initializer list
19359     @sa see @ref array(initializer_list_t) -- create a JSON array
19360     value from an initializer list
19361 
19362     @since version 1.0.0
19363     */
19364     JSON_HEDLEY_WARN_UNUSED_RESULT
object(initializer_list_t init={})19365     static basic_json object(initializer_list_t init = {})
19366     {
19367         return basic_json(init, false, value_t::object);
19368     }
19369 
19370     /*!
19371     @brief construct an array with count copies of given value
19372 
19373     Constructs a JSON array value by creating @a cnt copies of a passed value.
19374     In case @a cnt is `0`, an empty array is created.
19375 
19376     @param[in] cnt  the number of JSON copies of @a val to create
19377     @param[in] val  the JSON value to copy
19378 
19379     @post `std::distance(begin(),end()) == cnt` holds.
19380 
19381     @complexity Linear in @a cnt.
19382 
19383     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19384     changes to any JSON value.
19385 
19386     @liveexample{The following code shows examples for the @ref
19387     basic_json(size_type\, const basic_json&)
19388     constructor.,basic_json__size_type_basic_json}
19389 
19390     @since version 1.0.0
19391     */
basic_json(size_type cnt,const basic_json & val)19392     basic_json(size_type cnt, const basic_json& val)
19393         : m_type(value_t::array)
19394     {
19395         m_value.array = create<array_t>(cnt, val);
19396         set_parents();
19397         assert_invariant();
19398     }
19399 
19400     /*!
19401     @brief construct a JSON container given an iterator range
19402 
19403     Constructs the JSON value with the contents of the range `[first, last)`.
19404     The semantics depends on the different types a JSON value can have:
19405     - In case of a null type, invalid_iterator.206 is thrown.
19406     - In case of other primitive types (number, boolean, or string), @a first
19407       must be `begin()` and @a last must be `end()`. In this case, the value is
19408       copied. Otherwise, invalid_iterator.204 is thrown.
19409     - In case of structured types (array, object), the constructor behaves as
19410       similar versions for `std::vector` or `std::map`; that is, a JSON array
19411       or object is constructed from the values in the range.
19412 
19413     @tparam InputIT an input iterator type (@ref iterator or @ref
19414     const_iterator)
19415 
19416     @param[in] first begin of the range to copy from (included)
19417     @param[in] last end of the range to copy from (excluded)
19418 
19419     @pre Iterators @a first and @a last must be initialized. **This
19420          precondition is enforced with an assertion (see warning).** If
19421          assertions are switched off, a violation of this precondition yields
19422          undefined behavior.
19423 
19424     @pre Range `[first, last)` is valid. Usually, this precondition cannot be
19425          checked efficiently. Only certain edge cases are detected; see the
19426          description of the exceptions below. A violation of this precondition
19427          yields undefined behavior.
19428 
19429     @warning A precondition is enforced with a runtime assertion that will
19430              result in calling `std::abort` if this precondition is not met.
19431              Assertions can be disabled by defining `NDEBUG` at compile time.
19432              See https://en.cppreference.com/w/cpp/error/assert for more
19433              information.
19434 
19435     @throw invalid_iterator.201 if iterators @a first and @a last are not
19436     compatible (i.e., do not belong to the same JSON value). In this case,
19437     the range `[first, last)` is undefined.
19438     @throw invalid_iterator.204 if iterators @a first and @a last belong to a
19439     primitive type (number, boolean, or string), but @a first does not point
19440     to the first element any more. In this case, the range `[first, last)` is
19441     undefined. See example code below.
19442     @throw invalid_iterator.206 if iterators @a first and @a last belong to a
19443     null value. In this case, the range `[first, last)` is undefined.
19444 
19445     @complexity Linear in distance between @a first and @a last.
19446 
19447     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19448     changes to any JSON value.
19449 
19450     @liveexample{The example below shows several ways to create JSON values by
19451     specifying a subrange with iterators.,basic_json__InputIt_InputIt}
19452 
19453     @since version 1.0.0
19454     */
19455     template < class InputIT, typename std::enable_if <
19456                    std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19457                    std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
basic_json(InputIT first,InputIT last)19458     basic_json(InputIT first, InputIT last)
19459     {
19460         JSON_ASSERT(first.m_object != nullptr);
19461         JSON_ASSERT(last.m_object != nullptr);
19462 
19463         // make sure iterator fits the current value
19464         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19465         {
19466             JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
19467         }
19468 
19469         // copy type from first iterator
19470         m_type = first.m_object->m_type;
19471 
19472         // check if iterator range is complete for primitive values
19473         switch (m_type)
19474         {
19475             case value_t::boolean:
19476             case value_t::number_float:
19477             case value_t::number_integer:
19478             case value_t::number_unsigned:
19479             case value_t::string:
19480             {
19481                 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19482                                          || !last.m_it.primitive_iterator.is_end()))
19483                 {
19484                     JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
19485                 }
19486                 break;
19487             }
19488 
19489             case value_t::null:
19490             case value_t::object:
19491             case value_t::array:
19492             case value_t::binary:
19493             case value_t::discarded:
19494             default:
19495                 break;
19496         }
19497 
19498         switch (m_type)
19499         {
19500             case value_t::number_integer:
19501             {
19502                 m_value.number_integer = first.m_object->m_value.number_integer;
19503                 break;
19504             }
19505 
19506             case value_t::number_unsigned:
19507             {
19508                 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19509                 break;
19510             }
19511 
19512             case value_t::number_float:
19513             {
19514                 m_value.number_float = first.m_object->m_value.number_float;
19515                 break;
19516             }
19517 
19518             case value_t::boolean:
19519             {
19520                 m_value.boolean = first.m_object->m_value.boolean;
19521                 break;
19522             }
19523 
19524             case value_t::string:
19525             {
19526                 m_value = *first.m_object->m_value.string;
19527                 break;
19528             }
19529 
19530             case value_t::object:
19531             {
19532                 m_value.object = create<object_t>(first.m_it.object_iterator,
19533                                                   last.m_it.object_iterator);
19534                 break;
19535             }
19536 
19537             case value_t::array:
19538             {
19539                 m_value.array = create<array_t>(first.m_it.array_iterator,
19540                                                 last.m_it.array_iterator);
19541                 break;
19542             }
19543 
19544             case value_t::binary:
19545             {
19546                 m_value = *first.m_object->m_value.binary;
19547                 break;
19548             }
19549 
19550             case value_t::null:
19551             case value_t::discarded:
19552             default:
19553                 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
19554         }
19555 
19556         set_parents();
19557         assert_invariant();
19558     }
19559 
19560 
19561     ///////////////////////////////////////
19562     // other constructors and destructor //
19563     ///////////////////////////////////////
19564 
19565     template<typename JsonRef,
19566              detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
19567                                  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
basic_json(const JsonRef & ref)19568     basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19569 
19570     /*!
19571     @brief copy constructor
19572 
19573     Creates a copy of a given JSON value.
19574 
19575     @param[in] other  the JSON value to copy
19576 
19577     @post `*this == other`
19578 
19579     @complexity Linear in the size of @a other.
19580 
19581     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19582     changes to any JSON value.
19583 
19584     @requirement This function helps `basic_json` satisfying the
19585     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19586     requirements:
19587     - The complexity is linear.
19588     - As postcondition, it holds: `other == basic_json(other)`.
19589 
19590     @liveexample{The following code shows an example for the copy
19591     constructor.,basic_json__basic_json}
19592 
19593     @since version 1.0.0
19594     */
basic_json(const basic_json & other)19595     basic_json(const basic_json& other)
19596         : m_type(other.m_type)
19597     {
19598         // check of passed value is valid
19599         other.assert_invariant();
19600 
19601         switch (m_type)
19602         {
19603             case value_t::object:
19604             {
19605                 m_value = *other.m_value.object;
19606                 break;
19607             }
19608 
19609             case value_t::array:
19610             {
19611                 m_value = *other.m_value.array;
19612                 break;
19613             }
19614 
19615             case value_t::string:
19616             {
19617                 m_value = *other.m_value.string;
19618                 break;
19619             }
19620 
19621             case value_t::boolean:
19622             {
19623                 m_value = other.m_value.boolean;
19624                 break;
19625             }
19626 
19627             case value_t::number_integer:
19628             {
19629                 m_value = other.m_value.number_integer;
19630                 break;
19631             }
19632 
19633             case value_t::number_unsigned:
19634             {
19635                 m_value = other.m_value.number_unsigned;
19636                 break;
19637             }
19638 
19639             case value_t::number_float:
19640             {
19641                 m_value = other.m_value.number_float;
19642                 break;
19643             }
19644 
19645             case value_t::binary:
19646             {
19647                 m_value = *other.m_value.binary;
19648                 break;
19649             }
19650 
19651             case value_t::null:
19652             case value_t::discarded:
19653             default:
19654                 break;
19655         }
19656 
19657         set_parents();
19658         assert_invariant();
19659     }
19660 
19661     /*!
19662     @brief move constructor
19663 
19664     Move constructor. Constructs a JSON value with the contents of the given
19665     value @a other using move semantics. It "steals" the resources from @a
19666     other and leaves it as JSON null value.
19667 
19668     @param[in,out] other  value to move to this object
19669 
19670     @post `*this` has the same value as @a other before the call.
19671     @post @a other is a JSON null value.
19672 
19673     @complexity Constant.
19674 
19675     @exceptionsafety No-throw guarantee: this constructor never throws
19676     exceptions.
19677 
19678     @requirement This function helps `basic_json` satisfying the
19679     [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
19680     requirements.
19681 
19682     @liveexample{The code below shows the move constructor explicitly called
19683     via std::move.,basic_json__moveconstructor}
19684 
19685     @since version 1.0.0
19686     */
basic_json(basic_json && other)19687     basic_json(basic_json&& other) noexcept
19688         : m_type(std::move(other.m_type)),
19689           m_value(std::move(other.m_value))
19690     {
19691         // check that passed value is valid
19692         other.assert_invariant(false);
19693 
19694         // invalidate payload
19695         other.m_type = value_t::null;
19696         other.m_value = {};
19697 
19698         set_parents();
19699         assert_invariant();
19700     }
19701 
19702     /*!
19703     @brief copy assignment
19704 
19705     Copy assignment operator. Copies a JSON value via the "copy and swap"
19706     strategy: It is expressed in terms of the copy constructor, destructor,
19707     and the `swap()` member function.
19708 
19709     @param[in] other  value to copy from
19710 
19711     @complexity Linear.
19712 
19713     @requirement This function helps `basic_json` satisfying the
19714     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19715     requirements:
19716     - The complexity is linear.
19717 
19718     @liveexample{The code below shows and example for the copy assignment. It
19719     creates a copy of value `a` which is then swapped with `b`. Finally\, the
19720     copy of `a` (which is the null value after the swap) is
19721     destroyed.,basic_json__copyassignment}
19722 
19723     @since version 1.0.0
19724     */
operator =(basic_json other)19725     basic_json& operator=(basic_json other) noexcept (
19726         std::is_nothrow_move_constructible<value_t>::value&&
19727         std::is_nothrow_move_assignable<value_t>::value&&
19728         std::is_nothrow_move_constructible<json_value>::value&&
19729         std::is_nothrow_move_assignable<json_value>::value
19730     )
19731     {
19732         // check that passed value is valid
19733         other.assert_invariant();
19734 
19735         using std::swap;
19736         swap(m_type, other.m_type);
19737         swap(m_value, other.m_value);
19738 
19739         set_parents();
19740         assert_invariant();
19741         return *this;
19742     }
19743 
19744     /*!
19745     @brief destructor
19746 
19747     Destroys the JSON value and frees all allocated memory.
19748 
19749     @complexity Linear.
19750 
19751     @requirement This function helps `basic_json` satisfying the
19752     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19753     requirements:
19754     - The complexity is linear.
19755     - All stored elements are destroyed and all memory is freed.
19756 
19757     @since version 1.0.0
19758     */
~basic_json()19759     ~basic_json() noexcept
19760     {
19761         assert_invariant(false);
19762         m_value.destroy(m_type);
19763     }
19764 
19765     /// @}
19766 
19767   public:
19768     ///////////////////////
19769     // object inspection //
19770     ///////////////////////
19771 
19772     /// @name object inspection
19773     /// Functions to inspect the type of a JSON value.
19774     /// @{
19775 
19776     /*!
19777     @brief serialization
19778 
19779     Serialization function for JSON values. The function tries to mimic
19780     Python's `json.dumps()` function, and currently supports its @a indent
19781     and @a ensure_ascii parameters.
19782 
19783     @param[in] indent If indent is nonnegative, then array elements and object
19784     members will be pretty-printed with that indent level. An indent level of
19785     `0` will only insert newlines. `-1` (the default) selects the most compact
19786     representation.
19787     @param[in] indent_char The character to use for indentation if @a indent is
19788     greater than `0`. The default is ` ` (space).
19789     @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
19790     in the output are escaped with `\uXXXX` sequences, and the result consists
19791     of ASCII characters only.
19792     @param[in] error_handler  how to react on decoding errors; there are three
19793     possible values: `strict` (throws and exception in case a decoding error
19794     occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
19795     and `ignore` (ignore invalid UTF-8 sequences during serialization; all
19796     bytes are copied to the output unchanged).
19797 
19798     @return string containing the serialization of the JSON value
19799 
19800     @throw type_error.316 if a string stored inside the JSON value is not
19801                           UTF-8 encoded and @a error_handler is set to strict
19802 
19803     @note Binary values are serialized as object containing two keys:
19804       - "bytes": an array of bytes as integers
19805       - "subtype": the subtype as integer or "null" if the binary has no subtype
19806 
19807     @complexity Linear.
19808 
19809     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19810     changes in the JSON value.
19811 
19812     @liveexample{The following example shows the effect of different @a indent\,
19813     @a indent_char\, and @a ensure_ascii parameters to the result of the
19814     serialization.,dump}
19815 
19816     @see https://docs.python.org/2/library/json.html#json.dump
19817 
19818     @since version 1.0.0; indentation character @a indent_char, option
19819            @a ensure_ascii and exceptions added in version 3.0.0; error
19820            handlers added in version 3.4.0; serialization of binary values added
19821            in version 3.8.0.
19822     */
dump(const int indent=-1,const char indent_char=' ',const bool ensure_ascii=false,const error_handler_t error_handler=error_handler_t::strict) const19823     string_t dump(const int indent = -1,
19824                   const char indent_char = ' ',
19825                   const bool ensure_ascii = false,
19826                   const error_handler_t error_handler = error_handler_t::strict) const
19827     {
19828         string_t result;
19829         serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19830 
19831         if (indent >= 0)
19832         {
19833             s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19834         }
19835         else
19836         {
19837             s.dump(*this, false, ensure_ascii, 0);
19838         }
19839 
19840         return result;
19841     }
19842 
19843     /*!
19844     @brief return the type of the JSON value (explicit)
19845 
19846     Return the type of the JSON value as a value from the @ref value_t
19847     enumeration.
19848 
19849     @return the type of the JSON value
19850             Value type                | return value
19851             ------------------------- | -------------------------
19852             null                      | value_t::null
19853             boolean                   | value_t::boolean
19854             string                    | value_t::string
19855             number (integer)          | value_t::number_integer
19856             number (unsigned integer) | value_t::number_unsigned
19857             number (floating-point)   | value_t::number_float
19858             object                    | value_t::object
19859             array                     | value_t::array
19860             binary                    | value_t::binary
19861             discarded                 | value_t::discarded
19862 
19863     @complexity Constant.
19864 
19865     @exceptionsafety No-throw guarantee: this member function never throws
19866     exceptions.
19867 
19868     @liveexample{The following code exemplifies `type()` for all JSON
19869     types.,type}
19870 
19871     @sa see @ref operator value_t() -- return the type of the JSON value (implicit)
19872     @sa see @ref type_name() -- return the type as string
19873 
19874     @since version 1.0.0
19875     */
type() const19876     constexpr value_t type() const noexcept
19877     {
19878         return m_type;
19879     }
19880 
19881     /*!
19882     @brief return whether type is primitive
19883 
19884     This function returns true if and only if the JSON type is primitive
19885     (string, number, boolean, or null).
19886 
19887     @return `true` if type is primitive (string, number, boolean, or null),
19888     `false` otherwise.
19889 
19890     @complexity Constant.
19891 
19892     @exceptionsafety No-throw guarantee: this member function never throws
19893     exceptions.
19894 
19895     @liveexample{The following code exemplifies `is_primitive()` for all JSON
19896     types.,is_primitive}
19897 
19898     @sa see @ref is_structured() -- returns whether JSON value is structured
19899     @sa see @ref is_null() -- returns whether JSON value is `null`
19900     @sa see @ref is_string() -- returns whether JSON value is a string
19901     @sa see @ref is_boolean() -- returns whether JSON value is a boolean
19902     @sa see @ref is_number() -- returns whether JSON value is a number
19903     @sa see @ref is_binary() -- returns whether JSON value is a binary array
19904 
19905     @since version 1.0.0
19906     */
is_primitive() const19907     constexpr bool is_primitive() const noexcept
19908     {
19909         return is_null() || is_string() || is_boolean() || is_number() || is_binary();
19910     }
19911 
19912     /*!
19913     @brief return whether type is structured
19914 
19915     This function returns true if and only if the JSON type is structured
19916     (array or object).
19917 
19918     @return `true` if type is structured (array or object), `false` otherwise.
19919 
19920     @complexity Constant.
19921 
19922     @exceptionsafety No-throw guarantee: this member function never throws
19923     exceptions.
19924 
19925     @liveexample{The following code exemplifies `is_structured()` for all JSON
19926     types.,is_structured}
19927 
19928     @sa see @ref is_primitive() -- returns whether value is primitive
19929     @sa see @ref is_array() -- returns whether value is an array
19930     @sa see @ref is_object() -- returns whether value is an object
19931 
19932     @since version 1.0.0
19933     */
is_structured() const19934     constexpr bool is_structured() const noexcept
19935     {
19936         return is_array() || is_object();
19937     }
19938 
19939     /*!
19940     @brief return whether value is null
19941 
19942     This function returns true if and only if the JSON value is null.
19943 
19944     @return `true` if type is null, `false` otherwise.
19945 
19946     @complexity Constant.
19947 
19948     @exceptionsafety No-throw guarantee: this member function never throws
19949     exceptions.
19950 
19951     @liveexample{The following code exemplifies `is_null()` for all JSON
19952     types.,is_null}
19953 
19954     @since version 1.0.0
19955     */
is_null() const19956     constexpr bool is_null() const noexcept
19957     {
19958         return m_type == value_t::null;
19959     }
19960 
19961     /*!
19962     @brief return whether value is a boolean
19963 
19964     This function returns true if and only if the JSON value is a boolean.
19965 
19966     @return `true` if type is boolean, `false` otherwise.
19967 
19968     @complexity Constant.
19969 
19970     @exceptionsafety No-throw guarantee: this member function never throws
19971     exceptions.
19972 
19973     @liveexample{The following code exemplifies `is_boolean()` for all JSON
19974     types.,is_boolean}
19975 
19976     @since version 1.0.0
19977     */
is_boolean() const19978     constexpr bool is_boolean() const noexcept
19979     {
19980         return m_type == value_t::boolean;
19981     }
19982 
19983     /*!
19984     @brief return whether value is a number
19985 
19986     This function returns true if and only if the JSON value is a number. This
19987     includes both integer (signed and unsigned) and floating-point values.
19988 
19989     @return `true` if type is number (regardless whether integer, unsigned
19990     integer or floating-type), `false` otherwise.
19991 
19992     @complexity Constant.
19993 
19994     @exceptionsafety No-throw guarantee: this member function never throws
19995     exceptions.
19996 
19997     @liveexample{The following code exemplifies `is_number()` for all JSON
19998     types.,is_number}
19999 
20000     @sa see @ref is_number_integer() -- check if value is an integer or unsigned
20001     integer number
20002     @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20003     number
20004     @sa see @ref is_number_float() -- check if value is a floating-point number
20005 
20006     @since version 1.0.0
20007     */
is_number() const20008     constexpr bool is_number() const noexcept
20009     {
20010         return is_number_integer() || is_number_float();
20011     }
20012 
20013     /*!
20014     @brief return whether value is an integer number
20015 
20016     This function returns true if and only if the JSON value is a signed or
20017     unsigned integer number. This excludes floating-point values.
20018 
20019     @return `true` if type is an integer or unsigned integer number, `false`
20020     otherwise.
20021 
20022     @complexity Constant.
20023 
20024     @exceptionsafety No-throw guarantee: this member function never throws
20025     exceptions.
20026 
20027     @liveexample{The following code exemplifies `is_number_integer()` for all
20028     JSON types.,is_number_integer}
20029 
20030     @sa see @ref is_number() -- check if value is a number
20031     @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20032     number
20033     @sa see @ref is_number_float() -- check if value is a floating-point number
20034 
20035     @since version 1.0.0
20036     */
is_number_integer() const20037     constexpr bool is_number_integer() const noexcept
20038     {
20039         return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
20040     }
20041 
20042     /*!
20043     @brief return whether value is an unsigned integer number
20044 
20045     This function returns true if and only if the JSON value is an unsigned
20046     integer number. This excludes floating-point and signed integer values.
20047 
20048     @return `true` if type is an unsigned integer number, `false` otherwise.
20049 
20050     @complexity Constant.
20051 
20052     @exceptionsafety No-throw guarantee: this member function never throws
20053     exceptions.
20054 
20055     @liveexample{The following code exemplifies `is_number_unsigned()` for all
20056     JSON types.,is_number_unsigned}
20057 
20058     @sa see @ref is_number() -- check if value is a number
20059     @sa see @ref is_number_integer() -- check if value is an integer or unsigned
20060     integer number
20061     @sa see @ref is_number_float() -- check if value is a floating-point number
20062 
20063     @since version 2.0.0
20064     */
is_number_unsigned() const20065     constexpr bool is_number_unsigned() const noexcept
20066     {
20067         return m_type == value_t::number_unsigned;
20068     }
20069 
20070     /*!
20071     @brief return whether value is a floating-point number
20072 
20073     This function returns true if and only if the JSON value is a
20074     floating-point number. This excludes signed and unsigned integer values.
20075 
20076     @return `true` if type is a floating-point number, `false` otherwise.
20077 
20078     @complexity Constant.
20079 
20080     @exceptionsafety No-throw guarantee: this member function never throws
20081     exceptions.
20082 
20083     @liveexample{The following code exemplifies `is_number_float()` for all
20084     JSON types.,is_number_float}
20085 
20086     @sa see @ref is_number() -- check if value is number
20087     @sa see @ref is_number_integer() -- check if value is an integer number
20088     @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20089     number
20090 
20091     @since version 1.0.0
20092     */
is_number_float() const20093     constexpr bool is_number_float() const noexcept
20094     {
20095         return m_type == value_t::number_float;
20096     }
20097 
20098     /*!
20099     @brief return whether value is an object
20100 
20101     This function returns true if and only if the JSON value is an object.
20102 
20103     @return `true` if type is object, `false` otherwise.
20104 
20105     @complexity Constant.
20106 
20107     @exceptionsafety No-throw guarantee: this member function never throws
20108     exceptions.
20109 
20110     @liveexample{The following code exemplifies `is_object()` for all JSON
20111     types.,is_object}
20112 
20113     @since version 1.0.0
20114     */
is_object() const20115     constexpr bool is_object() const noexcept
20116     {
20117         return m_type == value_t::object;
20118     }
20119 
20120     /*!
20121     @brief return whether value is an array
20122 
20123     This function returns true if and only if the JSON value is an array.
20124 
20125     @return `true` if type is array, `false` otherwise.
20126 
20127     @complexity Constant.
20128 
20129     @exceptionsafety No-throw guarantee: this member function never throws
20130     exceptions.
20131 
20132     @liveexample{The following code exemplifies `is_array()` for all JSON
20133     types.,is_array}
20134 
20135     @since version 1.0.0
20136     */
is_array() const20137     constexpr bool is_array() const noexcept
20138     {
20139         return m_type == value_t::array;
20140     }
20141 
20142     /*!
20143     @brief return whether value is a string
20144 
20145     This function returns true if and only if the JSON value is a string.
20146 
20147     @return `true` if type is string, `false` otherwise.
20148 
20149     @complexity Constant.
20150 
20151     @exceptionsafety No-throw guarantee: this member function never throws
20152     exceptions.
20153 
20154     @liveexample{The following code exemplifies `is_string()` for all JSON
20155     types.,is_string}
20156 
20157     @since version 1.0.0
20158     */
is_string() const20159     constexpr bool is_string() const noexcept
20160     {
20161         return m_type == value_t::string;
20162     }
20163 
20164     /*!
20165     @brief return whether value is a binary array
20166 
20167     This function returns true if and only if the JSON value is a binary array.
20168 
20169     @return `true` if type is binary array, `false` otherwise.
20170 
20171     @complexity Constant.
20172 
20173     @exceptionsafety No-throw guarantee: this member function never throws
20174     exceptions.
20175 
20176     @liveexample{The following code exemplifies `is_binary()` for all JSON
20177     types.,is_binary}
20178 
20179     @since version 3.8.0
20180     */
is_binary() const20181     constexpr bool is_binary() const noexcept
20182     {
20183         return m_type == value_t::binary;
20184     }
20185 
20186     /*!
20187     @brief return whether value is discarded
20188 
20189     This function returns true if and only if the JSON value was discarded
20190     during parsing with a callback function (see @ref parser_callback_t).
20191 
20192     @note This function will always be `false` for JSON values after parsing.
20193     That is, discarded values can only occur during parsing, but will be
20194     removed when inside a structured value or replaced by null in other cases.
20195 
20196     @return `true` if type is discarded, `false` otherwise.
20197 
20198     @complexity Constant.
20199 
20200     @exceptionsafety No-throw guarantee: this member function never throws
20201     exceptions.
20202 
20203     @liveexample{The following code exemplifies `is_discarded()` for all JSON
20204     types.,is_discarded}
20205 
20206     @since version 1.0.0
20207     */
is_discarded() const20208     constexpr bool is_discarded() const noexcept
20209     {
20210         return m_type == value_t::discarded;
20211     }
20212 
20213     /*!
20214     @brief return the type of the JSON value (implicit)
20215 
20216     Implicitly return the type of the JSON value as a value from the @ref
20217     value_t enumeration.
20218 
20219     @return the type of the JSON value
20220 
20221     @complexity Constant.
20222 
20223     @exceptionsafety No-throw guarantee: this member function never throws
20224     exceptions.
20225 
20226     @liveexample{The following code exemplifies the @ref value_t operator for
20227     all JSON types.,operator__value_t}
20228 
20229     @sa see @ref type() -- return the type of the JSON value (explicit)
20230     @sa see @ref type_name() -- return the type as string
20231 
20232     @since version 1.0.0
20233     */
operator value_t() const20234     constexpr operator value_t() const noexcept
20235     {
20236         return m_type;
20237     }
20238 
20239     /// @}
20240 
20241   private:
20242     //////////////////
20243     // value access //
20244     //////////////////
20245 
20246     /// get a boolean (explicit)
get_impl(boolean_t *) const20247     boolean_t get_impl(boolean_t* /*unused*/) const
20248     {
20249         if (JSON_HEDLEY_LIKELY(is_boolean()))
20250         {
20251             return m_value.boolean;
20252         }
20253 
20254         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
20255     }
20256 
20257     /// get a pointer to the value (object)
get_impl_ptr(object_t *)20258     object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20259     {
20260         return is_object() ? m_value.object : nullptr;
20261     }
20262 
20263     /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const20264     constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20265     {
20266         return is_object() ? m_value.object : nullptr;
20267     }
20268 
20269     /// get a pointer to the value (array)
get_impl_ptr(array_t *)20270     array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20271     {
20272         return is_array() ? m_value.array : nullptr;
20273     }
20274 
20275     /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const20276     constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20277     {
20278         return is_array() ? m_value.array : nullptr;
20279     }
20280 
20281     /// get a pointer to the value (string)
get_impl_ptr(string_t *)20282     string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20283     {
20284         return is_string() ? m_value.string : nullptr;
20285     }
20286 
20287     /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const20288     constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20289     {
20290         return is_string() ? m_value.string : nullptr;
20291     }
20292 
20293     /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)20294     boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20295     {
20296         return is_boolean() ? &m_value.boolean : nullptr;
20297     }
20298 
20299     /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const20300     constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20301     {
20302         return is_boolean() ? &m_value.boolean : nullptr;
20303     }
20304 
20305     /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)20306     number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
20307     {
20308         return is_number_integer() ? &m_value.number_integer : nullptr;
20309     }
20310 
20311     /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const20312     constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20313     {
20314         return is_number_integer() ? &m_value.number_integer : nullptr;
20315     }
20316 
20317     /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)20318     number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
20319     {
20320         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20321     }
20322 
20323     /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const20324     constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20325     {
20326         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20327     }
20328 
20329     /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)20330     number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
20331     {
20332         return is_number_float() ? &m_value.number_float : nullptr;
20333     }
20334 
20335     /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const20336     constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20337     {
20338         return is_number_float() ? &m_value.number_float : nullptr;
20339     }
20340 
20341     /// get a pointer to the value (binary)
get_impl_ptr(binary_t *)20342     binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20343     {
20344         return is_binary() ? m_value.binary : nullptr;
20345     }
20346 
20347     /// get a pointer to the value (binary)
get_impl_ptr(const binary_t *) const20348     constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20349     {
20350         return is_binary() ? m_value.binary : nullptr;
20351     }
20352 
20353     /*!
20354     @brief helper function to implement get_ref()
20355 
20356     This function helps to implement get_ref() without code duplication for
20357     const and non-const overloads
20358 
20359     @tparam ThisType will be deduced as `basic_json` or `const basic_json`
20360 
20361     @throw type_error.303 if ReferenceType does not match underlying value
20362     type of the current JSON
20363     */
20364     template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)20365     static ReferenceType get_ref_impl(ThisType& obj)
20366     {
20367         // delegate the call to get_ptr<>()
20368         auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20369 
20370         if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20371         {
20372             return *ptr;
20373         }
20374 
20375         JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
20376     }
20377 
20378   public:
20379     /// @name value access
20380     /// Direct access to the stored value of a JSON value.
20381     /// @{
20382 
20383     /*!
20384     @brief get a pointer value (implicit)
20385 
20386     Implicit pointer access to the internally stored JSON value. No copies are
20387     made.
20388 
20389     @warning Writing data to the pointee of the result yields an undefined
20390     state.
20391 
20392     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
20393     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
20394     @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
20395     assertion.
20396 
20397     @return pointer to the internally stored JSON value if the requested
20398     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
20399 
20400     @complexity Constant.
20401 
20402     @liveexample{The example below shows how pointers to internal values of a
20403     JSON value can be requested. Note that no type conversions are made and a
20404     `nullptr` is returned if the value and the requested pointer type does not
20405     match.,get_ptr}
20406 
20407     @since version 1.0.0
20408     */
20409     template<typename PointerType, typename std::enable_if<
20410                  std::is_pointer<PointerType>::value, int>::type = 0>
get_ptr()20411     auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20412     {
20413         // delegate the call to get_impl_ptr<>()
20414         return get_impl_ptr(static_cast<PointerType>(nullptr));
20415     }
20416 
20417     /*!
20418     @brief get a pointer value (implicit)
20419     @copydoc get_ptr()
20420     */
20421     template < typename PointerType, typename std::enable_if <
20422                    std::is_pointer<PointerType>::value&&
20423                    std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
get_ptr() const20424     constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20425     {
20426         // delegate the call to get_impl_ptr<>() const
20427         return get_impl_ptr(static_cast<PointerType>(nullptr));
20428     }
20429 
20430   private:
20431     /*!
20432     @brief get a value (explicit)
20433 
20434     Explicit type conversion between the JSON value and a compatible value
20435     which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
20436     and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
20437     The value is converted by calling the @ref json_serializer<ValueType>
20438     `from_json()` method.
20439 
20440     The function is equivalent to executing
20441     @code {.cpp}
20442     ValueType ret;
20443     JSONSerializer<ValueType>::from_json(*this, ret);
20444     return ret;
20445     @endcode
20446 
20447     This overloads is chosen if:
20448     - @a ValueType is not @ref basic_json,
20449     - @ref json_serializer<ValueType> has a `from_json()` method of the form
20450       `void from_json(const basic_json&, ValueType&)`, and
20451     - @ref json_serializer<ValueType> does not have a `from_json()` method of
20452       the form `ValueType from_json(const basic_json&)`
20453 
20454     @tparam ValueType the returned value type
20455 
20456     @return copy of the JSON value, converted to @a ValueType
20457 
20458     @throw what @ref json_serializer<ValueType> `from_json()` method throws
20459 
20460     @liveexample{The example below shows several conversions from JSON values
20461     to other types. There a few things to note: (1) Floating-point numbers can
20462     be converted to integers\, (2) A JSON array can be converted to a standard
20463     `std::vector<short>`\, (3) A JSON object can be converted to C++
20464     associative containers such as `std::unordered_map<std::string\,
20465     json>`.,get__ValueType_const}
20466 
20467     @since version 2.1.0
20468     */
20469     template < typename ValueType,
20470                detail::enable_if_t <
20471                    detail::is_default_constructible<ValueType>::value&&
20472                    detail::has_from_json<basic_json_t, ValueType>::value,
20473                    int > = 0 >
20474     ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20475                 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20476     {
20477         ValueType ret{};
20478         JSONSerializer<ValueType>::from_json(*this, ret);
20479         return ret;
20480     }
20481 
20482     /*!
20483     @brief get a value (explicit); special case
20484 
20485     Explicit type conversion between the JSON value and a compatible value
20486     which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
20487     and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
20488     The value is converted by calling the @ref json_serializer<ValueType>
20489     `from_json()` method.
20490 
20491     The function is equivalent to executing
20492     @code {.cpp}
20493     return JSONSerializer<ValueType>::from_json(*this);
20494     @endcode
20495 
20496     This overloads is chosen if:
20497     - @a ValueType is not @ref basic_json and
20498     - @ref json_serializer<ValueType> has a `from_json()` method of the form
20499       `ValueType from_json(const basic_json&)`
20500 
20501     @note If @ref json_serializer<ValueType> has both overloads of
20502     `from_json()`, this one is chosen.
20503 
20504     @tparam ValueType the returned value type
20505 
20506     @return copy of the JSON value, converted to @a ValueType
20507 
20508     @throw what @ref json_serializer<ValueType> `from_json()` method throws
20509 
20510     @since version 2.1.0
20511     */
20512     template < typename ValueType,
20513                detail::enable_if_t <
20514                    detail::has_non_default_from_json<basic_json_t, ValueType>::value,
20515                    int > = 0 >
20516     ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20517                 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20518     {
20519         return JSONSerializer<ValueType>::from_json(*this);
20520     }
20521 
20522     /*!
20523     @brief get special-case overload
20524 
20525     This overloads converts the current @ref basic_json in a different
20526     @ref basic_json type
20527 
20528     @tparam BasicJsonType == @ref basic_json
20529 
20530     @return a copy of *this, converted into @a BasicJsonType
20531 
20532     @complexity Depending on the implementation of the called `from_json()`
20533                 method.
20534 
20535     @since version 3.2.0
20536     */
20537     template < typename BasicJsonType,
20538                detail::enable_if_t <
20539                    detail::is_basic_json<BasicJsonType>::value,
20540                    int > = 0 >
20541     BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20542     {
20543         return *this;
20544     }
20545 
20546     /*!
20547     @brief get special-case overload
20548 
20549     This overloads avoids a lot of template boilerplate, it can be seen as the
20550     identity method
20551 
20552     @tparam BasicJsonType == @ref basic_json
20553 
20554     @return a copy of *this
20555 
20556     @complexity Constant.
20557 
20558     @since version 2.1.0
20559     */
20560     template<typename BasicJsonType,
20561              detail::enable_if_t<
20562                  std::is_same<BasicJsonType, basic_json_t>::value,
20563                  int> = 0>
get_impl(detail::priority_tag<3>) const20564     basic_json get_impl(detail::priority_tag<3> /*unused*/) const
20565     {
20566         return *this;
20567     }
20568 
20569     /*!
20570     @brief get a pointer value (explicit)
20571     @copydoc get()
20572     */
20573     template<typename PointerType,
20574              detail::enable_if_t<
20575                  std::is_pointer<PointerType>::value,
20576                  int> = 0>
get_impl(detail::priority_tag<4>) const20577     constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20578     -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20579     {
20580         // delegate the call to get_ptr
20581         return get_ptr<PointerType>();
20582     }
20583 
20584   public:
20585     /*!
20586     @brief get a (pointer) value (explicit)
20587 
20588     Performs explicit type conversion between the JSON value and a compatible value if required.
20589 
20590     - If the requested type is a pointer to the internally stored JSON value that pointer is returned.
20591     No copies are made.
20592 
20593     - If the requested type is the current @ref basic_json, or a different @ref basic_json convertible
20594     from the current @ref basic_json.
20595 
20596     - Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`
20597     method.
20598 
20599     @tparam ValueTypeCV the provided value type
20600     @tparam ValueType the returned value type
20601 
20602     @return copy of the JSON value, converted to @tparam ValueType if necessary
20603 
20604     @throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
20605 
20606     @since version 2.1.0
20607     */
20608     template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20609 #if defined(JSON_HAS_CPP_14)
20610     constexpr
20611 #endif
get() const20612     auto get() const noexcept(
20613     noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20614     -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20615     {
20616         // we cannot static_assert on ValueTypeCV being non-const, because
20617         // there is support for get<const basic_json_t>(), which is why we
20618         // still need the uncvref
20619         static_assert(!std::is_reference<ValueTypeCV>::value,
20620                       "get() cannot be used with reference types, you might want to use get_ref()");
20621         return get_impl<ValueType>(detail::priority_tag<4> {});
20622     }
20623 
20624     /*!
20625     @brief get a pointer value (explicit)
20626 
20627     Explicit pointer access to the internally stored JSON value. No copies are
20628     made.
20629 
20630     @warning The pointer becomes invalid if the underlying JSON object
20631     changes.
20632 
20633     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
20634     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
20635     @ref number_unsigned_t, or @ref number_float_t.
20636 
20637     @return pointer to the internally stored JSON value if the requested
20638     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
20639 
20640     @complexity Constant.
20641 
20642     @liveexample{The example below shows how pointers to internal values of a
20643     JSON value can be requested. Note that no type conversions are made and a
20644     `nullptr` is returned if the value and the requested pointer type does not
20645     match.,get__PointerType}
20646 
20647     @sa see @ref get_ptr() for explicit pointer-member access
20648 
20649     @since version 1.0.0
20650     */
20651     template<typename PointerType, typename std::enable_if<
20652                  std::is_pointer<PointerType>::value, int>::type = 0>
get()20653     auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20654     {
20655         // delegate the call to get_ptr
20656         return get_ptr<PointerType>();
20657     }
20658 
20659     /*!
20660     @brief get a value (explicit)
20661 
20662     Explicit type conversion between the JSON value and a compatible value.
20663     The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
20664     `from_json()` method.
20665 
20666     The function is equivalent to executing
20667     @code {.cpp}
20668     ValueType v;
20669     JSONSerializer<ValueType>::from_json(*this, v);
20670     @endcode
20671 
20672     This overloads is chosen if:
20673     - @a ValueType is not @ref basic_json,
20674     - @ref json_serializer<ValueType> has a `from_json()` method of the form
20675       `void from_json(const basic_json&, ValueType&)`, and
20676 
20677     @tparam ValueType the input parameter type.
20678 
20679     @return the input parameter, allowing chaining calls.
20680 
20681     @throw what @ref json_serializer<ValueType> `from_json()` method throws
20682 
20683     @liveexample{The example below shows several conversions from JSON values
20684     to other types. There a few things to note: (1) Floating-point numbers can
20685     be converted to integers\, (2) A JSON array can be converted to a standard
20686     `std::vector<short>`\, (3) A JSON object can be converted to C++
20687     associative containers such as `std::unordered_map<std::string\,
20688     json>`.,get_to}
20689 
20690     @since version 3.3.0
20691     */
20692     template < typename ValueType,
20693                detail::enable_if_t <
20694                    !detail::is_basic_json<ValueType>::value&&
20695                    detail::has_from_json<basic_json_t, ValueType>::value,
20696                    int > = 0 >
20697     ValueType & get_to(ValueType& v) const noexcept(noexcept(
20698                 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20699     {
20700         JSONSerializer<ValueType>::from_json(*this, v);
20701         return v;
20702     }
20703 
20704     // specialization to allow to call get_to with a basic_json value
20705     // see https://github.com/nlohmann/json/issues/2175
20706     template<typename ValueType,
20707              detail::enable_if_t <
20708                  detail::is_basic_json<ValueType>::value,
20709                  int> = 0>
20710     ValueType & get_to(ValueType& v) const
20711     {
20712         v = *this;
20713         return v;
20714     }
20715 
20716     template <
20717         typename T, std::size_t N,
20718         typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20719         detail::enable_if_t <
20720             detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
20721     Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20722     noexcept(noexcept(JSONSerializer<Array>::from_json(
20723                           std::declval<const basic_json_t&>(), v)))
20724     {
20725         JSONSerializer<Array>::from_json(*this, v);
20726         return v;
20727     }
20728 
20729     /*!
20730     @brief get a reference value (implicit)
20731 
20732     Implicit reference access to the internally stored JSON value. No copies
20733     are made.
20734 
20735     @warning Writing data to the referee of the result yields an undefined
20736     state.
20737 
20738     @tparam ReferenceType reference type; must be a reference to @ref array_t,
20739     @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
20740     @ref number_float_t. Enforced by static assertion.
20741 
20742     @return reference to the internally stored JSON value if the requested
20743     reference type @a ReferenceType fits to the JSON value; throws
20744     type_error.303 otherwise
20745 
20746     @throw type_error.303 in case passed type @a ReferenceType is incompatible
20747     with the stored JSON value; see example below
20748 
20749     @complexity Constant.
20750 
20751     @liveexample{The example shows several calls to `get_ref()`.,get_ref}
20752 
20753     @since version 1.1.0
20754     */
20755     template<typename ReferenceType, typename std::enable_if<
20756                  std::is_reference<ReferenceType>::value, int>::type = 0>
20757     ReferenceType get_ref()
20758     {
20759         // delegate call to get_ref_impl
20760         return get_ref_impl<ReferenceType>(*this);
20761     }
20762 
20763     /*!
20764     @brief get a reference value (implicit)
20765     @copydoc get_ref()
20766     */
20767     template < typename ReferenceType, typename std::enable_if <
20768                    std::is_reference<ReferenceType>::value&&
20769                    std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
20770     ReferenceType get_ref() const
20771     {
20772         // delegate call to get_ref_impl
20773         return get_ref_impl<ReferenceType>(*this);
20774     }
20775 
20776     /*!
20777     @brief get a value (implicit)
20778 
20779     Implicit type conversion between the JSON value and a compatible value.
20780     The call is realized by calling @ref get() const.
20781 
20782     @tparam ValueType non-pointer type compatible to the JSON value, for
20783     instance `int` for JSON integer numbers, `bool` for JSON booleans, or
20784     `std::vector` types for JSON arrays. The character type of @ref string_t
20785     as well as an initializer list of this type is excluded to avoid
20786     ambiguities as these types implicitly convert to `std::string`.
20787 
20788     @return copy of the JSON value, converted to type @a ValueType
20789 
20790     @throw type_error.302 in case passed type @a ValueType is incompatible
20791     to the JSON value type (e.g., the JSON value is of type boolean, but a
20792     string is requested); see example below
20793 
20794     @complexity Linear in the size of the JSON value.
20795 
20796     @liveexample{The example below shows several conversions from JSON values
20797     to other types. There a few things to note: (1) Floating-point numbers can
20798     be converted to integers\, (2) A JSON array can be converted to a standard
20799     `std::vector<short>`\, (3) A JSON object can be converted to C++
20800     associative containers such as `std::unordered_map<std::string\,
20801     json>`.,operator__ValueType}
20802 
20803     @since version 1.0.0
20804     */
20805     template < typename ValueType, typename std::enable_if <
20806                    detail::conjunction <
20807                        detail::negation<std::is_pointer<ValueType>>,
20808                        detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
20809                                         detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
20810                                         detail::negation<detail::is_basic_json<ValueType>>,
20811                                         detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,
20812 
20813 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20814                                                 detail::negation<std::is_same<ValueType, std::string_view>>,
20815 #endif
20816                                                 detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>
20817                                                 >::value, int >::type = 0 >
operator ValueType() const20818                                         JSON_EXPLICIT operator ValueType() const
20819     {
20820         // delegate the call to get<>() const
20821         return get<ValueType>();
20822     }
20823 
20824     /*!
20825     @return reference to the binary value
20826 
20827     @throw type_error.302 if the value is not binary
20828 
20829     @sa see @ref is_binary() to check if the value is binary
20830 
20831     @since version 3.8.0
20832     */
get_binary()20833     binary_t& get_binary()
20834     {
20835         if (!is_binary())
20836         {
20837             JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20838         }
20839 
20840         return *get_ptr<binary_t*>();
20841     }
20842 
20843     /// @copydoc get_binary()
get_binary() const20844     const binary_t& get_binary() const
20845     {
20846         if (!is_binary())
20847         {
20848             JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20849         }
20850 
20851         return *get_ptr<const binary_t*>();
20852     }
20853 
20854     /// @}
20855 
20856 
20857     ////////////////////
20858     // element access //
20859     ////////////////////
20860 
20861     /// @name element access
20862     /// Access to the JSON value.
20863     /// @{
20864 
20865     /*!
20866     @brief access specified array element with bounds checking
20867 
20868     Returns a reference to the element at specified location @a idx, with
20869     bounds checking.
20870 
20871     @param[in] idx  index of the element to access
20872 
20873     @return reference to the element at index @a idx
20874 
20875     @throw type_error.304 if the JSON value is not an array; in this case,
20876     calling `at` with an index makes no sense. See example below.
20877     @throw out_of_range.401 if the index @a idx is out of range of the array;
20878     that is, `idx >= size()`. See example below.
20879 
20880     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20881     changes in the JSON value.
20882 
20883     @complexity Constant.
20884 
20885     @since version 1.0.0
20886 
20887     @liveexample{The example below shows how array elements can be read and
20888     written using `at()`. It also demonstrates the different exceptions that
20889     can be thrown.,at__size_type}
20890     */
at(size_type idx)20891     reference at(size_type idx)
20892     {
20893         // at only works for arrays
20894         if (JSON_HEDLEY_LIKELY(is_array()))
20895         {
20896             JSON_TRY
20897             {
20898                 return set_parent(m_value.array->at(idx));
20899             }
20900             JSON_CATCH (std::out_of_range&)
20901             {
20902                 // create better exception explanation
20903                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20904             }
20905         }
20906         else
20907         {
20908             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20909         }
20910     }
20911 
20912     /*!
20913     @brief access specified array element with bounds checking
20914 
20915     Returns a const reference to the element at specified location @a idx,
20916     with bounds checking.
20917 
20918     @param[in] idx  index of the element to access
20919 
20920     @return const reference to the element at index @a idx
20921 
20922     @throw type_error.304 if the JSON value is not an array; in this case,
20923     calling `at` with an index makes no sense. See example below.
20924     @throw out_of_range.401 if the index @a idx is out of range of the array;
20925     that is, `idx >= size()`. See example below.
20926 
20927     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20928     changes in the JSON value.
20929 
20930     @complexity Constant.
20931 
20932     @since version 1.0.0
20933 
20934     @liveexample{The example below shows how array elements can be read using
20935     `at()`. It also demonstrates the different exceptions that can be thrown.,
20936     at__size_type_const}
20937     */
at(size_type idx) const20938     const_reference at(size_type idx) const
20939     {
20940         // at only works for arrays
20941         if (JSON_HEDLEY_LIKELY(is_array()))
20942         {
20943             JSON_TRY
20944             {
20945                 return m_value.array->at(idx);
20946             }
20947             JSON_CATCH (std::out_of_range&)
20948             {
20949                 // create better exception explanation
20950                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20951             }
20952         }
20953         else
20954         {
20955             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20956         }
20957     }
20958 
20959     /*!
20960     @brief access specified object element with bounds checking
20961 
20962     Returns a reference to the element at with specified key @a key, with
20963     bounds checking.
20964 
20965     @param[in] key  key of the element to access
20966 
20967     @return reference to the element at key @a key
20968 
20969     @throw type_error.304 if the JSON value is not an object; in this case,
20970     calling `at` with a key makes no sense. See example below.
20971     @throw out_of_range.403 if the key @a key is is not stored in the object;
20972     that is, `find(key) == end()`. See example below.
20973 
20974     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20975     changes in the JSON value.
20976 
20977     @complexity Logarithmic in the size of the container.
20978 
20979     @sa see @ref operator[](const typename object_t::key_type&) for unchecked
20980     access by reference
20981     @sa see @ref value() for access by value with a default value
20982 
20983     @since version 1.0.0
20984 
20985     @liveexample{The example below shows how object elements can be read and
20986     written using `at()`. It also demonstrates the different exceptions that
20987     can be thrown.,at__object_t_key_type}
20988     */
at(const typename object_t::key_type & key)20989     reference at(const typename object_t::key_type& key)
20990     {
20991         // at only works for objects
20992         if (JSON_HEDLEY_LIKELY(is_object()))
20993         {
20994             JSON_TRY
20995             {
20996                 return set_parent(m_value.object->at(key));
20997             }
20998             JSON_CATCH (std::out_of_range&)
20999             {
21000                 // create better exception explanation
21001                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21002             }
21003         }
21004         else
21005         {
21006             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21007         }
21008     }
21009 
21010     /*!
21011     @brief access specified object element with bounds checking
21012 
21013     Returns a const reference to the element at with specified key @a key,
21014     with bounds checking.
21015 
21016     @param[in] key  key of the element to access
21017 
21018     @return const reference to the element at key @a key
21019 
21020     @throw type_error.304 if the JSON value is not an object; in this case,
21021     calling `at` with a key makes no sense. See example below.
21022     @throw out_of_range.403 if the key @a key is is not stored in the object;
21023     that is, `find(key) == end()`. See example below.
21024 
21025     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21026     changes in the JSON value.
21027 
21028     @complexity Logarithmic in the size of the container.
21029 
21030     @sa see @ref operator[](const typename object_t::key_type&) for unchecked
21031     access by reference
21032     @sa see @ref value() for access by value with a default value
21033 
21034     @since version 1.0.0
21035 
21036     @liveexample{The example below shows how object elements can be read using
21037     `at()`. It also demonstrates the different exceptions that can be thrown.,
21038     at__object_t_key_type_const}
21039     */
at(const typename object_t::key_type & key) const21040     const_reference at(const typename object_t::key_type& key) const
21041     {
21042         // at only works for objects
21043         if (JSON_HEDLEY_LIKELY(is_object()))
21044         {
21045             JSON_TRY
21046             {
21047                 return m_value.object->at(key);
21048             }
21049             JSON_CATCH (std::out_of_range&)
21050             {
21051                 // create better exception explanation
21052                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21053             }
21054         }
21055         else
21056         {
21057             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21058         }
21059     }
21060 
21061     /*!
21062     @brief access specified array element
21063 
21064     Returns a reference to the element at specified location @a idx.
21065 
21066     @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
21067     then the array is silently filled up with `null` values to make `idx` a
21068     valid reference to the last stored element.
21069 
21070     @param[in] idx  index of the element to access
21071 
21072     @return reference to the element at index @a idx
21073 
21074     @throw type_error.305 if the JSON value is not an array or null; in that
21075     cases, using the [] operator with an index makes no sense.
21076 
21077     @complexity Constant if @a idx is in the range of the array. Otherwise
21078     linear in `idx - size()`.
21079 
21080     @liveexample{The example below shows how array elements can be read and
21081     written using `[]` operator. Note the addition of `null`
21082     values.,operatorarray__size_type}
21083 
21084     @since version 1.0.0
21085     */
operator [](size_type idx)21086     reference operator[](size_type idx)
21087     {
21088         // implicitly convert null value to an empty array
21089         if (is_null())
21090         {
21091             m_type = value_t::array;
21092             m_value.array = create<array_t>();
21093             assert_invariant();
21094         }
21095 
21096         // operator[] only works for arrays
21097         if (JSON_HEDLEY_LIKELY(is_array()))
21098         {
21099             // fill up array with null values if given idx is outside range
21100             if (idx >= m_value.array->size())
21101             {
21102 #if JSON_DIAGNOSTICS
21103                 // remember array size before resizing
21104                 const auto previous_size = m_value.array->size();
21105 #endif
21106                 m_value.array->resize(idx + 1);
21107 
21108 #if JSON_DIAGNOSTICS
21109                 // set parent for values added above
21110                 set_parents(begin() + static_cast<typename iterator::difference_type>(previous_size), static_cast<typename iterator::difference_type>(idx + 1 - previous_size));
21111 #endif
21112             }
21113 
21114             return m_value.array->operator[](idx);
21115         }
21116 
21117         JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21118     }
21119 
21120     /*!
21121     @brief access specified array element
21122 
21123     Returns a const reference to the element at specified location @a idx.
21124 
21125     @param[in] idx  index of the element to access
21126 
21127     @return const reference to the element at index @a idx
21128 
21129     @throw type_error.305 if the JSON value is not an array; in that case,
21130     using the [] operator with an index makes no sense.
21131 
21132     @complexity Constant.
21133 
21134     @liveexample{The example below shows how array elements can be read using
21135     the `[]` operator.,operatorarray__size_type_const}
21136 
21137     @since version 1.0.0
21138     */
operator [](size_type idx) const21139     const_reference operator[](size_type idx) const
21140     {
21141         // const operator[] only works for arrays
21142         if (JSON_HEDLEY_LIKELY(is_array()))
21143         {
21144             return m_value.array->operator[](idx);
21145         }
21146 
21147         JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21148     }
21149 
21150     /*!
21151     @brief access specified object element
21152 
21153     Returns a reference to the element at with specified key @a key.
21154 
21155     @note If @a key is not found in the object, then it is silently added to
21156     the object and filled with a `null` value to make `key` a valid reference.
21157     In case the value was `null` before, it is converted to an object.
21158 
21159     @param[in] key  key of the element to access
21160 
21161     @return reference to the element at key @a key
21162 
21163     @throw type_error.305 if the JSON value is not an object or null; in that
21164     cases, using the [] operator with a key makes no sense.
21165 
21166     @complexity Logarithmic in the size of the container.
21167 
21168     @liveexample{The example below shows how object elements can be read and
21169     written using the `[]` operator.,operatorarray__key_type}
21170 
21171     @sa see @ref at(const typename object_t::key_type&) for access by reference
21172     with range checking
21173     @sa see @ref value() for access by value with a default value
21174 
21175     @since version 1.0.0
21176     */
operator [](const typename object_t::key_type & key)21177     reference operator[](const typename object_t::key_type& key)
21178     {
21179         // implicitly convert null value to an empty object
21180         if (is_null())
21181         {
21182             m_type = value_t::object;
21183             m_value.object = create<object_t>();
21184             assert_invariant();
21185         }
21186 
21187         // operator[] only works for objects
21188         if (JSON_HEDLEY_LIKELY(is_object()))
21189         {
21190             return set_parent(m_value.object->operator[](key));
21191         }
21192 
21193         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21194     }
21195 
21196     /*!
21197     @brief read-only access specified object element
21198 
21199     Returns a const reference to the element at with specified key @a key. No
21200     bounds checking is performed.
21201 
21202     @warning If the element with key @a key does not exist, the behavior is
21203     undefined.
21204 
21205     @param[in] key  key of the element to access
21206 
21207     @return const reference to the element at key @a key
21208 
21209     @pre The element with key @a key must exist. **This precondition is
21210          enforced with an assertion.**
21211 
21212     @throw type_error.305 if the JSON value is not an object; in that case,
21213     using the [] operator with a key makes no sense.
21214 
21215     @complexity Logarithmic in the size of the container.
21216 
21217     @liveexample{The example below shows how object elements can be read using
21218     the `[]` operator.,operatorarray__key_type_const}
21219 
21220     @sa see @ref at(const typename object_t::key_type&) for access by reference
21221     with range checking
21222     @sa see @ref value() for access by value with a default value
21223 
21224     @since version 1.0.0
21225     */
operator [](const typename object_t::key_type & key) const21226     const_reference operator[](const typename object_t::key_type& key) const
21227     {
21228         // const operator[] only works for objects
21229         if (JSON_HEDLEY_LIKELY(is_object()))
21230         {
21231             JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21232             return m_value.object->find(key)->second;
21233         }
21234 
21235         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21236     }
21237 
21238     /*!
21239     @brief access specified object element
21240 
21241     Returns a reference to the element at with specified key @a key.
21242 
21243     @note If @a key is not found in the object, then it is silently added to
21244     the object and filled with a `null` value to make `key` a valid reference.
21245     In case the value was `null` before, it is converted to an object.
21246 
21247     @param[in] key  key of the element to access
21248 
21249     @return reference to the element at key @a key
21250 
21251     @throw type_error.305 if the JSON value is not an object or null; in that
21252     cases, using the [] operator with a key makes no sense.
21253 
21254     @complexity Logarithmic in the size of the container.
21255 
21256     @liveexample{The example below shows how object elements can be read and
21257     written using the `[]` operator.,operatorarray__key_type}
21258 
21259     @sa see @ref at(const typename object_t::key_type&) for access by reference
21260     with range checking
21261     @sa see @ref value() for access by value with a default value
21262 
21263     @since version 1.1.0
21264     */
21265     template<typename T>
21266     JSON_HEDLEY_NON_NULL(2)
operator [](T * key)21267     reference operator[](T* key)
21268     {
21269         // implicitly convert null to object
21270         if (is_null())
21271         {
21272             m_type = value_t::object;
21273             m_value = value_t::object;
21274             assert_invariant();
21275         }
21276 
21277         // at only works for objects
21278         if (JSON_HEDLEY_LIKELY(is_object()))
21279         {
21280             return set_parent(m_value.object->operator[](key));
21281         }
21282 
21283         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21284     }
21285 
21286     /*!
21287     @brief read-only access specified object element
21288 
21289     Returns a const reference to the element at with specified key @a key. No
21290     bounds checking is performed.
21291 
21292     @warning If the element with key @a key does not exist, the behavior is
21293     undefined.
21294 
21295     @param[in] key  key of the element to access
21296 
21297     @return const reference to the element at key @a key
21298 
21299     @pre The element with key @a key must exist. **This precondition is
21300          enforced with an assertion.**
21301 
21302     @throw type_error.305 if the JSON value is not an object; in that case,
21303     using the [] operator with a key makes no sense.
21304 
21305     @complexity Logarithmic in the size of the container.
21306 
21307     @liveexample{The example below shows how object elements can be read using
21308     the `[]` operator.,operatorarray__key_type_const}
21309 
21310     @sa see @ref at(const typename object_t::key_type&) for access by reference
21311     with range checking
21312     @sa see @ref value() for access by value with a default value
21313 
21314     @since version 1.1.0
21315     */
21316     template<typename T>
21317     JSON_HEDLEY_NON_NULL(2)
operator [](T * key) const21318     const_reference operator[](T* key) const
21319     {
21320         // at only works for objects
21321         if (JSON_HEDLEY_LIKELY(is_object()))
21322         {
21323             JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21324             return m_value.object->find(key)->second;
21325         }
21326 
21327         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21328     }
21329 
21330     /*!
21331     @brief access specified object element with default value
21332 
21333     Returns either a copy of an object's element at the specified key @a key
21334     or a given default value if no element with key @a key exists.
21335 
21336     The function is basically equivalent to executing
21337     @code {.cpp}
21338     try {
21339         return at(key);
21340     } catch(out_of_range) {
21341         return default_value;
21342     }
21343     @endcode
21344 
21345     @note Unlike @ref at(const typename object_t::key_type&), this function
21346     does not throw if the given key @a key was not found.
21347 
21348     @note Unlike @ref operator[](const typename object_t::key_type& key), this
21349     function does not implicitly add an element to the position defined by @a
21350     key. This function is furthermore also applicable to const objects.
21351 
21352     @param[in] key  key of the element to access
21353     @param[in] default_value  the value to return if @a key is not found
21354 
21355     @tparam ValueType type compatible to JSON values, for instance `int` for
21356     JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
21357     JSON arrays. Note the type of the expected value at @a key and the default
21358     value @a default_value must be compatible.
21359 
21360     @return copy of the element at key @a key or @a default_value if @a key
21361     is not found
21362 
21363     @throw type_error.302 if @a default_value does not match the type of the
21364     value at @a key
21365     @throw type_error.306 if the JSON value is not an object; in that case,
21366     using `value()` with a key makes no sense.
21367 
21368     @complexity Logarithmic in the size of the container.
21369 
21370     @liveexample{The example below shows how object elements can be queried
21371     with a default value.,basic_json__value}
21372 
21373     @sa see @ref at(const typename object_t::key_type&) for access by reference
21374     with range checking
21375     @sa see @ref operator[](const typename object_t::key_type&) for unchecked
21376     access by reference
21377 
21378     @since version 1.0.0
21379     */
21380     // using std::is_convertible in a std::enable_if will fail when using explicit conversions
21381     template < class ValueType, typename std::enable_if <
21382                    detail::is_getable<basic_json_t, ValueType>::value
21383                    && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
21384     ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21385     {
21386         // at only works for objects
21387         if (JSON_HEDLEY_LIKELY(is_object()))
21388         {
21389             // if key is found, return value and given default value otherwise
21390             const auto it = find(key);
21391             if (it != end())
21392             {
21393                 return it->template get<ValueType>();
21394             }
21395 
21396             return default_value;
21397         }
21398 
21399         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21400     }
21401 
21402     /*!
21403     @brief overload for a default value of type const char*
21404     @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
21405     */
value(const typename object_t::key_type & key,const char * default_value) const21406     string_t value(const typename object_t::key_type& key, const char* default_value) const
21407     {
21408         return value(key, string_t(default_value));
21409     }
21410 
21411     /*!
21412     @brief access specified object element via JSON Pointer with default value
21413 
21414     Returns either a copy of an object's element at the specified key @a key
21415     or a given default value if no element with key @a key exists.
21416 
21417     The function is basically equivalent to executing
21418     @code {.cpp}
21419     try {
21420         return at(ptr);
21421     } catch(out_of_range) {
21422         return default_value;
21423     }
21424     @endcode
21425 
21426     @note Unlike @ref at(const json_pointer&), this function does not throw
21427     if the given key @a key was not found.
21428 
21429     @param[in] ptr  a JSON pointer to the element to access
21430     @param[in] default_value  the value to return if @a ptr found no value
21431 
21432     @tparam ValueType type compatible to JSON values, for instance `int` for
21433     JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
21434     JSON arrays. Note the type of the expected value at @a key and the default
21435     value @a default_value must be compatible.
21436 
21437     @return copy of the element at key @a key or @a default_value if @a key
21438     is not found
21439 
21440     @throw type_error.302 if @a default_value does not match the type of the
21441     value at @a ptr
21442     @throw type_error.306 if the JSON value is not an object; in that case,
21443     using `value()` with a key makes no sense.
21444 
21445     @complexity Logarithmic in the size of the container.
21446 
21447     @liveexample{The example below shows how object elements can be queried
21448     with a default value.,basic_json__value_ptr}
21449 
21450     @sa see @ref operator[](const json_pointer&) for unchecked access by reference
21451 
21452     @since version 2.0.2
21453     */
21454     template<class ValueType, typename std::enable_if<
21455                  detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
21456     ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21457     {
21458         // at only works for objects
21459         if (JSON_HEDLEY_LIKELY(is_object()))
21460         {
21461             // if pointer resolves a value, return it or use default value
21462             JSON_TRY
21463             {
21464                 return ptr.get_checked(this).template get<ValueType>();
21465             }
21466             JSON_INTERNAL_CATCH (out_of_range&)
21467             {
21468                 return default_value;
21469             }
21470         }
21471 
21472         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21473     }
21474 
21475     /*!
21476     @brief overload for a default value of type const char*
21477     @copydoc basic_json::value(const json_pointer&, ValueType) const
21478     */
21479     JSON_HEDLEY_NON_NULL(3)
value(const json_pointer & ptr,const char * default_value) const21480     string_t value(const json_pointer& ptr, const char* default_value) const
21481     {
21482         return value(ptr, string_t(default_value));
21483     }
21484 
21485     /*!
21486     @brief access the first element
21487 
21488     Returns a reference to the first element in the container. For a JSON
21489     container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
21490 
21491     @return In case of a structured type (array or object), a reference to the
21492     first element is returned. In case of number, string, boolean, or binary
21493     values, a reference to the value is returned.
21494 
21495     @complexity Constant.
21496 
21497     @pre The JSON value must not be `null` (would throw `std::out_of_range`)
21498     or an empty array or object (undefined behavior, **guarded by
21499     assertions**).
21500     @post The JSON value remains unchanged.
21501 
21502     @throw invalid_iterator.214 when called on `null` value
21503 
21504     @liveexample{The following code shows an example for `front()`.,front}
21505 
21506     @sa see @ref back() -- access the last element
21507 
21508     @since version 1.0.0
21509     */
front()21510     reference front()
21511     {
21512         return *begin();
21513     }
21514 
21515     /*!
21516     @copydoc basic_json::front()
21517     */
front() const21518     const_reference front() const
21519     {
21520         return *cbegin();
21521     }
21522 
21523     /*!
21524     @brief access the last element
21525 
21526     Returns a reference to the last element in the container. For a JSON
21527     container `c`, the expression `c.back()` is equivalent to
21528     @code {.cpp}
21529     auto tmp = c.end();
21530     --tmp;
21531     return *tmp;
21532     @endcode
21533 
21534     @return In case of a structured type (array or object), a reference to the
21535     last element is returned. In case of number, string, boolean, or binary
21536     values, a reference to the value is returned.
21537 
21538     @complexity Constant.
21539 
21540     @pre The JSON value must not be `null` (would throw `std::out_of_range`)
21541     or an empty array or object (undefined behavior, **guarded by
21542     assertions**).
21543     @post The JSON value remains unchanged.
21544 
21545     @throw invalid_iterator.214 when called on a `null` value. See example
21546     below.
21547 
21548     @liveexample{The following code shows an example for `back()`.,back}
21549 
21550     @sa see @ref front() -- access the first element
21551 
21552     @since version 1.0.0
21553     */
back()21554     reference back()
21555     {
21556         auto tmp = end();
21557         --tmp;
21558         return *tmp;
21559     }
21560 
21561     /*!
21562     @copydoc basic_json::back()
21563     */
back() const21564     const_reference back() const
21565     {
21566         auto tmp = cend();
21567         --tmp;
21568         return *tmp;
21569     }
21570 
21571     /*!
21572     @brief remove element given an iterator
21573 
21574     Removes the element specified by iterator @a pos. The iterator @a pos must
21575     be valid and dereferenceable. Thus the `end()` iterator (which is valid,
21576     but is not dereferenceable) cannot be used as a value for @a pos.
21577 
21578     If called on a primitive type other than `null`, the resulting JSON value
21579     will be `null`.
21580 
21581     @param[in] pos iterator to the element to remove
21582     @return Iterator following the last removed element. If the iterator @a
21583     pos refers to the last element, the `end()` iterator is returned.
21584 
21585     @tparam IteratorType an @ref iterator or @ref const_iterator
21586 
21587     @post Invalidates iterators and references at or after the point of the
21588     erase, including the `end()` iterator.
21589 
21590     @throw type_error.307 if called on a `null` value; example: `"cannot use
21591     erase() with null"`
21592     @throw invalid_iterator.202 if called on an iterator which does not belong
21593     to the current JSON value; example: `"iterator does not fit current
21594     value"`
21595     @throw invalid_iterator.205 if called on a primitive type with invalid
21596     iterator (i.e., any iterator which is not `begin()`); example: `"iterator
21597     out of range"`
21598 
21599     @complexity The complexity depends on the type:
21600     - objects: amortized constant
21601     - arrays: linear in distance between @a pos and the end of the container
21602     - strings and binary: linear in the length of the member
21603     - other types: constant
21604 
21605     @liveexample{The example shows the result of `erase()` for different JSON
21606     types.,erase__IteratorType}
21607 
21608     @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21609     the given range
21610     @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21611     from an object at the given key
21612     @sa see @ref erase(const size_type) -- removes the element from an array at
21613     the given index
21614 
21615     @since version 1.0.0
21616     */
21617     template < class IteratorType, typename std::enable_if <
21618                    std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21619                    std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21620                = 0 >
21621     IteratorType erase(IteratorType pos)
21622     {
21623         // make sure iterator fits the current value
21624         if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21625         {
21626             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
21627         }
21628 
21629         IteratorType result = end();
21630 
21631         switch (m_type)
21632         {
21633             case value_t::boolean:
21634             case value_t::number_float:
21635             case value_t::number_integer:
21636             case value_t::number_unsigned:
21637             case value_t::string:
21638             case value_t::binary:
21639             {
21640                 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21641                 {
21642                     JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
21643                 }
21644 
21645                 if (is_string())
21646                 {
21647                     AllocatorType<string_t> alloc;
21648                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21649                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21650                     m_value.string = nullptr;
21651                 }
21652                 else if (is_binary())
21653                 {
21654                     AllocatorType<binary_t> alloc;
21655                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21656                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21657                     m_value.binary = nullptr;
21658                 }
21659 
21660                 m_type = value_t::null;
21661                 assert_invariant();
21662                 break;
21663             }
21664 
21665             case value_t::object:
21666             {
21667                 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21668                 break;
21669             }
21670 
21671             case value_t::array:
21672             {
21673                 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21674                 break;
21675             }
21676 
21677             case value_t::null:
21678             case value_t::discarded:
21679             default:
21680                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21681         }
21682 
21683         return result;
21684     }
21685 
21686     /*!
21687     @brief remove elements given an iterator range
21688 
21689     Removes the element specified by the range `[first; last)`. The iterator
21690     @a first does not need to be dereferenceable if `first == last`: erasing
21691     an empty range is a no-op.
21692 
21693     If called on a primitive type other than `null`, the resulting JSON value
21694     will be `null`.
21695 
21696     @param[in] first iterator to the beginning of the range to remove
21697     @param[in] last iterator past the end of the range to remove
21698     @return Iterator following the last removed element. If the iterator @a
21699     second refers to the last element, the `end()` iterator is returned.
21700 
21701     @tparam IteratorType an @ref iterator or @ref const_iterator
21702 
21703     @post Invalidates iterators and references at or after the point of the
21704     erase, including the `end()` iterator.
21705 
21706     @throw type_error.307 if called on a `null` value; example: `"cannot use
21707     erase() with null"`
21708     @throw invalid_iterator.203 if called on iterators which does not belong
21709     to the current JSON value; example: `"iterators do not fit current value"`
21710     @throw invalid_iterator.204 if called on a primitive type with invalid
21711     iterators (i.e., if `first != begin()` and `last != end()`); example:
21712     `"iterators out of range"`
21713 
21714     @complexity The complexity depends on the type:
21715     - objects: `log(size()) + std::distance(first, last)`
21716     - arrays: linear in the distance between @a first and @a last, plus linear
21717       in the distance between @a last and end of the container
21718     - strings and binary: linear in the length of the member
21719     - other types: constant
21720 
21721     @liveexample{The example shows the result of `erase()` for different JSON
21722     types.,erase__IteratorType_IteratorType}
21723 
21724     @sa see @ref erase(IteratorType) -- removes the element at a given position
21725     @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21726     from an object at the given key
21727     @sa see @ref erase(const size_type) -- removes the element from an array at
21728     the given index
21729 
21730     @since version 1.0.0
21731     */
21732     template < class IteratorType, typename std::enable_if <
21733                    std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21734                    std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21735                = 0 >
21736     IteratorType erase(IteratorType first, IteratorType last)
21737     {
21738         // make sure iterator fits the current value
21739         if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21740         {
21741             JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
21742         }
21743 
21744         IteratorType result = end();
21745 
21746         switch (m_type)
21747         {
21748             case value_t::boolean:
21749             case value_t::number_float:
21750             case value_t::number_integer:
21751             case value_t::number_unsigned:
21752             case value_t::string:
21753             case value_t::binary:
21754             {
21755                 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21756                                        || !last.m_it.primitive_iterator.is_end()))
21757                 {
21758                     JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
21759                 }
21760 
21761                 if (is_string())
21762                 {
21763                     AllocatorType<string_t> alloc;
21764                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21765                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21766                     m_value.string = nullptr;
21767                 }
21768                 else if (is_binary())
21769                 {
21770                     AllocatorType<binary_t> alloc;
21771                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21772                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21773                     m_value.binary = nullptr;
21774                 }
21775 
21776                 m_type = value_t::null;
21777                 assert_invariant();
21778                 break;
21779             }
21780 
21781             case value_t::object:
21782             {
21783                 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21784                                               last.m_it.object_iterator);
21785                 break;
21786             }
21787 
21788             case value_t::array:
21789             {
21790                 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21791                                              last.m_it.array_iterator);
21792                 break;
21793             }
21794 
21795             case value_t::null:
21796             case value_t::discarded:
21797             default:
21798                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21799         }
21800 
21801         return result;
21802     }
21803 
21804     /*!
21805     @brief remove element from a JSON object given a key
21806 
21807     Removes elements from a JSON object with the key value @a key.
21808 
21809     @param[in] key value of the elements to remove
21810 
21811     @return Number of elements removed. If @a ObjectType is the default
21812     `std::map` type, the return value will always be `0` (@a key was not
21813     found) or `1` (@a key was found).
21814 
21815     @post References and iterators to the erased elements are invalidated.
21816     Other references and iterators are not affected.
21817 
21818     @throw type_error.307 when called on a type other than JSON object;
21819     example: `"cannot use erase() with null"`
21820 
21821     @complexity `log(size()) + count(key)`
21822 
21823     @liveexample{The example shows the effect of `erase()`.,erase__key_type}
21824 
21825     @sa see @ref erase(IteratorType) -- removes the element at a given position
21826     @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21827     the given range
21828     @sa see @ref erase(const size_type) -- removes the element from an array at
21829     the given index
21830 
21831     @since version 1.0.0
21832     */
erase(const typename object_t::key_type & key)21833     size_type erase(const typename object_t::key_type& key)
21834     {
21835         // this erase only works for objects
21836         if (JSON_HEDLEY_LIKELY(is_object()))
21837         {
21838             return m_value.object->erase(key);
21839         }
21840 
21841         JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21842     }
21843 
21844     /*!
21845     @brief remove element from a JSON array given an index
21846 
21847     Removes element from a JSON array at the index @a idx.
21848 
21849     @param[in] idx index of the element to remove
21850 
21851     @throw type_error.307 when called on a type other than JSON object;
21852     example: `"cannot use erase() with null"`
21853     @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
21854     is out of range"`
21855 
21856     @complexity Linear in distance between @a idx and the end of the container.
21857 
21858     @liveexample{The example shows the effect of `erase()`.,erase__size_type}
21859 
21860     @sa see @ref erase(IteratorType) -- removes the element at a given position
21861     @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21862     the given range
21863     @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21864     from an object at the given key
21865 
21866     @since version 1.0.0
21867     */
erase(const size_type idx)21868     void erase(const size_type idx)
21869     {
21870         // this erase only works for arrays
21871         if (JSON_HEDLEY_LIKELY(is_array()))
21872         {
21873             if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21874             {
21875                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21876             }
21877 
21878             m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21879         }
21880         else
21881         {
21882             JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21883         }
21884     }
21885 
21886     /// @}
21887 
21888 
21889     ////////////
21890     // lookup //
21891     ////////////
21892 
21893     /// @name lookup
21894     /// @{
21895 
21896     /*!
21897     @brief find an element in a JSON object
21898 
21899     Finds an element in a JSON object with key equivalent to @a key. If the
21900     element is not found or the JSON value is not an object, end() is
21901     returned.
21902 
21903     @note This method always returns @ref end() when executed on a JSON type
21904           that is not an object.
21905 
21906     @param[in] key key value of the element to search for.
21907 
21908     @return Iterator to an element with key equivalent to @a key. If no such
21909     element is found or the JSON value is not an object, past-the-end (see
21910     @ref end()) iterator is returned.
21911 
21912     @complexity Logarithmic in the size of the JSON object.
21913 
21914     @liveexample{The example shows how `find()` is used.,find__key_type}
21915 
21916     @sa see @ref contains(KeyT&&) const -- checks whether a key exists
21917 
21918     @since version 1.0.0
21919     */
21920     template<typename KeyT>
find(KeyT && key)21921     iterator find(KeyT&& key)
21922     {
21923         auto result = end();
21924 
21925         if (is_object())
21926         {
21927             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
21928         }
21929 
21930         return result;
21931     }
21932 
21933     /*!
21934     @brief find an element in a JSON object
21935     @copydoc find(KeyT&&)
21936     */
21937     template<typename KeyT>
find(KeyT && key) const21938     const_iterator find(KeyT&& key) const
21939     {
21940         auto result = cend();
21941 
21942         if (is_object())
21943         {
21944             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
21945         }
21946 
21947         return result;
21948     }
21949 
21950     /*!
21951     @brief returns the number of occurrences of a key in a JSON object
21952 
21953     Returns the number of elements with key @a key. If ObjectType is the
21954     default `std::map` type, the return value will always be `0` (@a key was
21955     not found) or `1` (@a key was found).
21956 
21957     @note This method always returns `0` when executed on a JSON type that is
21958           not an object.
21959 
21960     @param[in] key key value of the element to count
21961 
21962     @return Number of elements with key @a key. If the JSON value is not an
21963     object, the return value will be `0`.
21964 
21965     @complexity Logarithmic in the size of the JSON object.
21966 
21967     @liveexample{The example shows how `count()` is used.,count}
21968 
21969     @since version 1.0.0
21970     */
21971     template<typename KeyT>
count(KeyT && key) const21972     size_type count(KeyT&& key) const
21973     {
21974         // return 0 for all nonobject types
21975         return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
21976     }
21977 
21978     /*!
21979     @brief check the existence of an element in a JSON object
21980 
21981     Check whether an element exists in a JSON object with key equivalent to
21982     @a key. If the element is not found or the JSON value is not an object,
21983     false is returned.
21984 
21985     @note This method always returns false when executed on a JSON type
21986           that is not an object.
21987 
21988     @param[in] key key value to check its existence.
21989 
21990     @return true if an element with specified @a key exists. If no such
21991     element with such key is found or the JSON value is not an object,
21992     false is returned.
21993 
21994     @complexity Logarithmic in the size of the JSON object.
21995 
21996     @liveexample{The following code shows an example for `contains()`.,contains}
21997 
21998     @sa see @ref find(KeyT&&) -- returns an iterator to an object element
21999     @sa see @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
22000 
22001     @since version 3.6.0
22002     */
22003     template < typename KeyT, typename std::enable_if <
22004                    !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
contains(KeyT && key) const22005     bool contains(KeyT && key) const
22006     {
22007         return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
22008     }
22009 
22010     /*!
22011     @brief check the existence of an element in a JSON object given a JSON pointer
22012 
22013     Check whether the given JSON pointer @a ptr can be resolved in the current
22014     JSON value.
22015 
22016     @note This method can be executed on any JSON value type.
22017 
22018     @param[in] ptr JSON pointer to check its existence.
22019 
22020     @return true if the JSON pointer can be resolved to a stored value, false
22021     otherwise.
22022 
22023     @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
22024 
22025     @throw parse_error.106   if an array index begins with '0'
22026     @throw parse_error.109   if an array index was not a number
22027 
22028     @complexity Logarithmic in the size of the JSON object.
22029 
22030     @liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
22031 
22032     @sa see @ref contains(KeyT &&) const -- checks the existence of a key
22033 
22034     @since version 3.7.0
22035     */
contains(const json_pointer & ptr) const22036     bool contains(const json_pointer& ptr) const
22037     {
22038         return ptr.contains(this);
22039     }
22040 
22041     /// @}
22042 
22043 
22044     ///////////////
22045     // iterators //
22046     ///////////////
22047 
22048     /// @name iterators
22049     /// @{
22050 
22051     /*!
22052     @brief returns an iterator to the first element
22053 
22054     Returns an iterator to the first element.
22055 
22056     @image html range-begin-end.svg "Illustration from cppreference.com"
22057 
22058     @return iterator to the first element
22059 
22060     @complexity Constant.
22061 
22062     @requirement This function helps `basic_json` satisfying the
22063     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22064     requirements:
22065     - The complexity is constant.
22066 
22067     @liveexample{The following code shows an example for `begin()`.,begin}
22068 
22069     @sa see @ref cbegin() -- returns a const iterator to the beginning
22070     @sa see @ref end() -- returns an iterator to the end
22071     @sa see @ref cend() -- returns a const iterator to the end
22072 
22073     @since version 1.0.0
22074     */
begin()22075     iterator begin() noexcept
22076     {
22077         iterator result(this);
22078         result.set_begin();
22079         return result;
22080     }
22081 
22082     /*!
22083     @copydoc basic_json::cbegin()
22084     */
begin() const22085     const_iterator begin() const noexcept
22086     {
22087         return cbegin();
22088     }
22089 
22090     /*!
22091     @brief returns a const iterator to the first element
22092 
22093     Returns a const iterator to the first element.
22094 
22095     @image html range-begin-end.svg "Illustration from cppreference.com"
22096 
22097     @return const iterator to the first element
22098 
22099     @complexity Constant.
22100 
22101     @requirement This function helps `basic_json` satisfying the
22102     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22103     requirements:
22104     - The complexity is constant.
22105     - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
22106 
22107     @liveexample{The following code shows an example for `cbegin()`.,cbegin}
22108 
22109     @sa see @ref begin() -- returns an iterator to the beginning
22110     @sa see @ref end() -- returns an iterator to the end
22111     @sa see @ref cend() -- returns a const iterator to the end
22112 
22113     @since version 1.0.0
22114     */
cbegin() const22115     const_iterator cbegin() const noexcept
22116     {
22117         const_iterator result(this);
22118         result.set_begin();
22119         return result;
22120     }
22121 
22122     /*!
22123     @brief returns an iterator to one past the last element
22124 
22125     Returns an iterator to one past the last element.
22126 
22127     @image html range-begin-end.svg "Illustration from cppreference.com"
22128 
22129     @return iterator one past the last element
22130 
22131     @complexity Constant.
22132 
22133     @requirement This function helps `basic_json` satisfying the
22134     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22135     requirements:
22136     - The complexity is constant.
22137 
22138     @liveexample{The following code shows an example for `end()`.,end}
22139 
22140     @sa see @ref cend() -- returns a const iterator to the end
22141     @sa see @ref begin() -- returns an iterator to the beginning
22142     @sa see @ref cbegin() -- returns a const iterator to the beginning
22143 
22144     @since version 1.0.0
22145     */
end()22146     iterator end() noexcept
22147     {
22148         iterator result(this);
22149         result.set_end();
22150         return result;
22151     }
22152 
22153     /*!
22154     @copydoc basic_json::cend()
22155     */
end() const22156     const_iterator end() const noexcept
22157     {
22158         return cend();
22159     }
22160 
22161     /*!
22162     @brief returns a const iterator to one past the last element
22163 
22164     Returns a const iterator to one past the last element.
22165 
22166     @image html range-begin-end.svg "Illustration from cppreference.com"
22167 
22168     @return const iterator one past the last element
22169 
22170     @complexity Constant.
22171 
22172     @requirement This function helps `basic_json` satisfying the
22173     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22174     requirements:
22175     - The complexity is constant.
22176     - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
22177 
22178     @liveexample{The following code shows an example for `cend()`.,cend}
22179 
22180     @sa see @ref end() -- returns an iterator to the end
22181     @sa see @ref begin() -- returns an iterator to the beginning
22182     @sa see @ref cbegin() -- returns a const iterator to the beginning
22183 
22184     @since version 1.0.0
22185     */
cend() const22186     const_iterator cend() const noexcept
22187     {
22188         const_iterator result(this);
22189         result.set_end();
22190         return result;
22191     }
22192 
22193     /*!
22194     @brief returns an iterator to the reverse-beginning
22195 
22196     Returns an iterator to the reverse-beginning; that is, the last element.
22197 
22198     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22199 
22200     @complexity Constant.
22201 
22202     @requirement This function helps `basic_json` satisfying the
22203     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22204     requirements:
22205     - The complexity is constant.
22206     - Has the semantics of `reverse_iterator(end())`.
22207 
22208     @liveexample{The following code shows an example for `rbegin()`.,rbegin}
22209 
22210     @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22211     @sa see @ref rend() -- returns a reverse iterator to the end
22212     @sa see @ref crend() -- returns a const reverse iterator to the end
22213 
22214     @since version 1.0.0
22215     */
rbegin()22216     reverse_iterator rbegin() noexcept
22217     {
22218         return reverse_iterator(end());
22219     }
22220 
22221     /*!
22222     @copydoc basic_json::crbegin()
22223     */
rbegin() const22224     const_reverse_iterator rbegin() const noexcept
22225     {
22226         return crbegin();
22227     }
22228 
22229     /*!
22230     @brief returns an iterator to the reverse-end
22231 
22232     Returns an iterator to the reverse-end; that is, one before the first
22233     element.
22234 
22235     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22236 
22237     @complexity Constant.
22238 
22239     @requirement This function helps `basic_json` satisfying the
22240     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22241     requirements:
22242     - The complexity is constant.
22243     - Has the semantics of `reverse_iterator(begin())`.
22244 
22245     @liveexample{The following code shows an example for `rend()`.,rend}
22246 
22247     @sa see @ref crend() -- returns a const reverse iterator to the end
22248     @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22249     @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22250 
22251     @since version 1.0.0
22252     */
rend()22253     reverse_iterator rend() noexcept
22254     {
22255         return reverse_iterator(begin());
22256     }
22257 
22258     /*!
22259     @copydoc basic_json::crend()
22260     */
rend() const22261     const_reverse_iterator rend() const noexcept
22262     {
22263         return crend();
22264     }
22265 
22266     /*!
22267     @brief returns a const reverse iterator to the last element
22268 
22269     Returns a const iterator to the reverse-beginning; that is, the last
22270     element.
22271 
22272     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22273 
22274     @complexity Constant.
22275 
22276     @requirement This function helps `basic_json` satisfying the
22277     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22278     requirements:
22279     - The complexity is constant.
22280     - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
22281 
22282     @liveexample{The following code shows an example for `crbegin()`.,crbegin}
22283 
22284     @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22285     @sa see @ref rend() -- returns a reverse iterator to the end
22286     @sa see @ref crend() -- returns a const reverse iterator to the end
22287 
22288     @since version 1.0.0
22289     */
crbegin() const22290     const_reverse_iterator crbegin() const noexcept
22291     {
22292         return const_reverse_iterator(cend());
22293     }
22294 
22295     /*!
22296     @brief returns a const reverse iterator to one before the first
22297 
22298     Returns a const reverse iterator to the reverse-end; that is, one before
22299     the first element.
22300 
22301     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22302 
22303     @complexity Constant.
22304 
22305     @requirement This function helps `basic_json` satisfying the
22306     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22307     requirements:
22308     - The complexity is constant.
22309     - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
22310 
22311     @liveexample{The following code shows an example for `crend()`.,crend}
22312 
22313     @sa see @ref rend() -- returns a reverse iterator to the end
22314     @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22315     @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22316 
22317     @since version 1.0.0
22318     */
crend() const22319     const_reverse_iterator crend() const noexcept
22320     {
22321         return const_reverse_iterator(cbegin());
22322     }
22323 
22324   public:
22325     /*!
22326     @brief wrapper to access iterator member functions in range-based for
22327 
22328     This function allows to access @ref iterator::key() and @ref
22329     iterator::value() during range-based for loops. In these loops, a
22330     reference to the JSON values is returned, so there is no access to the
22331     underlying iterator.
22332 
22333     For loop without iterator_wrapper:
22334 
22335     @code{cpp}
22336     for (auto it = j_object.begin(); it != j_object.end(); ++it)
22337     {
22338         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22339     }
22340     @endcode
22341 
22342     Range-based for loop without iterator proxy:
22343 
22344     @code{cpp}
22345     for (auto it : j_object)
22346     {
22347         // "it" is of type json::reference and has no key() member
22348         std::cout << "value: " << it << '\n';
22349     }
22350     @endcode
22351 
22352     Range-based for loop with iterator proxy:
22353 
22354     @code{cpp}
22355     for (auto it : json::iterator_wrapper(j_object))
22356     {
22357         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22358     }
22359     @endcode
22360 
22361     @note When iterating over an array, `key()` will return the index of the
22362           element as string (see example).
22363 
22364     @param[in] ref  reference to a JSON value
22365     @return iteration proxy object wrapping @a ref with an interface to use in
22366             range-based for loops
22367 
22368     @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
22369 
22370     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
22371     changes in the JSON value.
22372 
22373     @complexity Constant.
22374 
22375     @note The name of this function is not yet final and may change in the
22376     future.
22377 
22378     @deprecated This stream operator is deprecated and will be removed in
22379                 future 4.0.0 of the library. Please use @ref items() instead;
22380                 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
22381     */
items()22382     JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22383     static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22384     {
22385         return ref.items();
22386     }
22387 
22388     /*!
22389     @copydoc iterator_wrapper(reference)
22390     */
items()22391     JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22392     static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22393     {
22394         return ref.items();
22395     }
22396 
22397     /*!
22398     @brief helper to access iterator member functions in range-based for
22399 
22400     This function allows to access @ref iterator::key() and @ref
22401     iterator::value() during range-based for loops. In these loops, a
22402     reference to the JSON values is returned, so there is no access to the
22403     underlying iterator.
22404 
22405     For loop without `items()` function:
22406 
22407     @code{cpp}
22408     for (auto it = j_object.begin(); it != j_object.end(); ++it)
22409     {
22410         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22411     }
22412     @endcode
22413 
22414     Range-based for loop without `items()` function:
22415 
22416     @code{cpp}
22417     for (auto it : j_object)
22418     {
22419         // "it" is of type json::reference and has no key() member
22420         std::cout << "value: " << it << '\n';
22421     }
22422     @endcode
22423 
22424     Range-based for loop with `items()` function:
22425 
22426     @code{cpp}
22427     for (auto& el : j_object.items())
22428     {
22429         std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
22430     }
22431     @endcode
22432 
22433     The `items()` function also allows to use
22434     [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
22435     (C++17):
22436 
22437     @code{cpp}
22438     for (auto& [key, val] : j_object.items())
22439     {
22440         std::cout << "key: " << key << ", value:" << val << '\n';
22441     }
22442     @endcode
22443 
22444     @note When iterating over an array, `key()` will return the index of the
22445           element as string (see example). For primitive types (e.g., numbers),
22446           `key()` returns an empty string.
22447 
22448     @warning Using `items()` on temporary objects is dangerous. Make sure the
22449              object's lifetime exeeds the iteration. See
22450              <https://github.com/nlohmann/json/issues/2040> for more
22451              information.
22452 
22453     @return iteration proxy object wrapping @a ref with an interface to use in
22454             range-based for loops
22455 
22456     @liveexample{The following code shows how the function is used.,items}
22457 
22458     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
22459     changes in the JSON value.
22460 
22461     @complexity Constant.
22462 
22463     @since version 3.1.0, structured bindings support since 3.5.0.
22464     */
items()22465     iteration_proxy<iterator> items() noexcept
22466     {
22467         return iteration_proxy<iterator>(*this);
22468     }
22469 
22470     /*!
22471     @copydoc items()
22472     */
items() const22473     iteration_proxy<const_iterator> items() const noexcept
22474     {
22475         return iteration_proxy<const_iterator>(*this);
22476     }
22477 
22478     /// @}
22479 
22480 
22481     //////////////
22482     // capacity //
22483     //////////////
22484 
22485     /// @name capacity
22486     /// @{
22487 
22488     /*!
22489     @brief checks whether the container is empty.
22490 
22491     Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
22492 
22493     @return The return value depends on the different types and is
22494             defined as follows:
22495             Value type  | return value
22496             ----------- | -------------
22497             null        | `true`
22498             boolean     | `false`
22499             string      | `false`
22500             number      | `false`
22501             binary      | `false`
22502             object      | result of function `object_t::empty()`
22503             array       | result of function `array_t::empty()`
22504 
22505     @liveexample{The following code uses `empty()` to check if a JSON
22506     object contains any elements.,empty}
22507 
22508     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22509     the Container concept; that is, their `empty()` functions have constant
22510     complexity.
22511 
22512     @iterators No changes.
22513 
22514     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22515 
22516     @note This function does not return whether a string stored as JSON value
22517     is empty - it returns whether the JSON container itself is empty which is
22518     false in the case of a string.
22519 
22520     @requirement This function helps `basic_json` satisfying the
22521     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22522     requirements:
22523     - The complexity is constant.
22524     - Has the semantics of `begin() == end()`.
22525 
22526     @sa see @ref size() -- returns the number of elements
22527 
22528     @since version 1.0.0
22529     */
empty() const22530     bool empty() const noexcept
22531     {
22532         switch (m_type)
22533         {
22534             case value_t::null:
22535             {
22536                 // null values are empty
22537                 return true;
22538             }
22539 
22540             case value_t::array:
22541             {
22542                 // delegate call to array_t::empty()
22543                 return m_value.array->empty();
22544             }
22545 
22546             case value_t::object:
22547             {
22548                 // delegate call to object_t::empty()
22549                 return m_value.object->empty();
22550             }
22551 
22552             case value_t::string:
22553             case value_t::boolean:
22554             case value_t::number_integer:
22555             case value_t::number_unsigned:
22556             case value_t::number_float:
22557             case value_t::binary:
22558             case value_t::discarded:
22559             default:
22560             {
22561                 // all other types are nonempty
22562                 return false;
22563             }
22564         }
22565     }
22566 
22567     /*!
22568     @brief returns the number of elements
22569 
22570     Returns the number of elements in a JSON value.
22571 
22572     @return The return value depends on the different types and is
22573             defined as follows:
22574             Value type  | return value
22575             ----------- | -------------
22576             null        | `0`
22577             boolean     | `1`
22578             string      | `1`
22579             number      | `1`
22580             binary      | `1`
22581             object      | result of function object_t::size()
22582             array       | result of function array_t::size()
22583 
22584     @liveexample{The following code calls `size()` on the different value
22585     types.,size}
22586 
22587     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22588     the Container concept; that is, their size() functions have constant
22589     complexity.
22590 
22591     @iterators No changes.
22592 
22593     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22594 
22595     @note This function does not return the length of a string stored as JSON
22596     value - it returns the number of elements in the JSON value which is 1 in
22597     the case of a string.
22598 
22599     @requirement This function helps `basic_json` satisfying the
22600     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22601     requirements:
22602     - The complexity is constant.
22603     - Has the semantics of `std::distance(begin(), end())`.
22604 
22605     @sa see @ref empty() -- checks whether the container is empty
22606     @sa see @ref max_size() -- returns the maximal number of elements
22607 
22608     @since version 1.0.0
22609     */
size() const22610     size_type size() const noexcept
22611     {
22612         switch (m_type)
22613         {
22614             case value_t::null:
22615             {
22616                 // null values are empty
22617                 return 0;
22618             }
22619 
22620             case value_t::array:
22621             {
22622                 // delegate call to array_t::size()
22623                 return m_value.array->size();
22624             }
22625 
22626             case value_t::object:
22627             {
22628                 // delegate call to object_t::size()
22629                 return m_value.object->size();
22630             }
22631 
22632             case value_t::string:
22633             case value_t::boolean:
22634             case value_t::number_integer:
22635             case value_t::number_unsigned:
22636             case value_t::number_float:
22637             case value_t::binary:
22638             case value_t::discarded:
22639             default:
22640             {
22641                 // all other types have size 1
22642                 return 1;
22643             }
22644         }
22645     }
22646 
22647     /*!
22648     @brief returns the maximum possible number of elements
22649 
22650     Returns the maximum number of elements a JSON value is able to hold due to
22651     system or library implementation limitations, i.e. `std::distance(begin(),
22652     end())` for the JSON value.
22653 
22654     @return The return value depends on the different types and is
22655             defined as follows:
22656             Value type  | return value
22657             ----------- | -------------
22658             null        | `0` (same as `size()`)
22659             boolean     | `1` (same as `size()`)
22660             string      | `1` (same as `size()`)
22661             number      | `1` (same as `size()`)
22662             binary      | `1` (same as `size()`)
22663             object      | result of function `object_t::max_size()`
22664             array       | result of function `array_t::max_size()`
22665 
22666     @liveexample{The following code calls `max_size()` on the different value
22667     types. Note the output is implementation specific.,max_size}
22668 
22669     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22670     the Container concept; that is, their `max_size()` functions have constant
22671     complexity.
22672 
22673     @iterators No changes.
22674 
22675     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22676 
22677     @requirement This function helps `basic_json` satisfying the
22678     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22679     requirements:
22680     - The complexity is constant.
22681     - Has the semantics of returning `b.size()` where `b` is the largest
22682       possible JSON value.
22683 
22684     @sa see @ref size() -- returns the number of elements
22685 
22686     @since version 1.0.0
22687     */
max_size() const22688     size_type max_size() const noexcept
22689     {
22690         switch (m_type)
22691         {
22692             case value_t::array:
22693             {
22694                 // delegate call to array_t::max_size()
22695                 return m_value.array->max_size();
22696             }
22697 
22698             case value_t::object:
22699             {
22700                 // delegate call to object_t::max_size()
22701                 return m_value.object->max_size();
22702             }
22703 
22704             case value_t::null:
22705             case value_t::string:
22706             case value_t::boolean:
22707             case value_t::number_integer:
22708             case value_t::number_unsigned:
22709             case value_t::number_float:
22710             case value_t::binary:
22711             case value_t::discarded:
22712             default:
22713             {
22714                 // all other types have max_size() == size()
22715                 return size();
22716             }
22717         }
22718     }
22719 
22720     /// @}
22721 
22722 
22723     ///////////////
22724     // modifiers //
22725     ///////////////
22726 
22727     /// @name modifiers
22728     /// @{
22729 
22730     /*!
22731     @brief clears the contents
22732 
22733     Clears the content of a JSON value and resets it to the default value as
22734     if @ref basic_json(value_t) would have been called with the current value
22735     type from @ref type():
22736 
22737     Value type  | initial value
22738     ----------- | -------------
22739     null        | `null`
22740     boolean     | `false`
22741     string      | `""`
22742     number      | `0`
22743     binary      | An empty byte vector
22744     object      | `{}`
22745     array       | `[]`
22746 
22747     @post Has the same effect as calling
22748     @code {.cpp}
22749     *this = basic_json(type());
22750     @endcode
22751 
22752     @liveexample{The example below shows the effect of `clear()` to different
22753     JSON types.,clear}
22754 
22755     @complexity Linear in the size of the JSON value.
22756 
22757     @iterators All iterators, pointers and references related to this container
22758                are invalidated.
22759 
22760     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22761 
22762     @sa see @ref basic_json(value_t) -- constructor that creates an object with the
22763         same value than calling `clear()`
22764 
22765     @since version 1.0.0
22766     */
clear()22767     void clear() noexcept
22768     {
22769         switch (m_type)
22770         {
22771             case value_t::number_integer:
22772             {
22773                 m_value.number_integer = 0;
22774                 break;
22775             }
22776 
22777             case value_t::number_unsigned:
22778             {
22779                 m_value.number_unsigned = 0;
22780                 break;
22781             }
22782 
22783             case value_t::number_float:
22784             {
22785                 m_value.number_float = 0.0;
22786                 break;
22787             }
22788 
22789             case value_t::boolean:
22790             {
22791                 m_value.boolean = false;
22792                 break;
22793             }
22794 
22795             case value_t::string:
22796             {
22797                 m_value.string->clear();
22798                 break;
22799             }
22800 
22801             case value_t::binary:
22802             {
22803                 m_value.binary->clear();
22804                 break;
22805             }
22806 
22807             case value_t::array:
22808             {
22809                 m_value.array->clear();
22810                 break;
22811             }
22812 
22813             case value_t::object:
22814             {
22815                 m_value.object->clear();
22816                 break;
22817             }
22818 
22819             case value_t::null:
22820             case value_t::discarded:
22821             default:
22822                 break;
22823         }
22824     }
22825 
22826     /*!
22827     @brief add an object to an array
22828 
22829     Appends the given element @a val to the end of the JSON value. If the
22830     function is called on a JSON null value, an empty array is created before
22831     appending @a val.
22832 
22833     @param[in] val the value to add to the JSON array
22834 
22835     @throw type_error.308 when called on a type other than JSON array or
22836     null; example: `"cannot use push_back() with number"`
22837 
22838     @complexity Amortized constant.
22839 
22840     @liveexample{The example shows how `push_back()` and `+=` can be used to
22841     add elements to a JSON array. Note how the `null` value was silently
22842     converted to a JSON array.,push_back}
22843 
22844     @since version 1.0.0
22845     */
push_back(basic_json && val)22846     void push_back(basic_json&& val)
22847     {
22848         // push_back only works for null objects or arrays
22849         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22850         {
22851             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22852         }
22853 
22854         // transform null object into an array
22855         if (is_null())
22856         {
22857             m_type = value_t::array;
22858             m_value = value_t::array;
22859             assert_invariant();
22860         }
22861 
22862         // add element to array (move semantics)
22863         const auto old_capacity = m_value.array->capacity();
22864         m_value.array->push_back(std::move(val));
22865         set_parent(m_value.array->back(), old_capacity);
22866         // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
22867     }
22868 
22869     /*!
22870     @brief add an object to an array
22871     @copydoc push_back(basic_json&&)
22872     */
operator +=(basic_json && val)22873     reference operator+=(basic_json&& val)
22874     {
22875         push_back(std::move(val));
22876         return *this;
22877     }
22878 
22879     /*!
22880     @brief add an object to an array
22881     @copydoc push_back(basic_json&&)
22882     */
push_back(const basic_json & val)22883     void push_back(const basic_json& val)
22884     {
22885         // push_back only works for null objects or arrays
22886         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22887         {
22888             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22889         }
22890 
22891         // transform null object into an array
22892         if (is_null())
22893         {
22894             m_type = value_t::array;
22895             m_value = value_t::array;
22896             assert_invariant();
22897         }
22898 
22899         // add element to array
22900         const auto old_capacity = m_value.array->capacity();
22901         m_value.array->push_back(val);
22902         set_parent(m_value.array->back(), old_capacity);
22903     }
22904 
22905     /*!
22906     @brief add an object to an array
22907     @copydoc push_back(basic_json&&)
22908     */
operator +=(const basic_json & val)22909     reference operator+=(const basic_json& val)
22910     {
22911         push_back(val);
22912         return *this;
22913     }
22914 
22915     /*!
22916     @brief add an object to an object
22917 
22918     Inserts the given element @a val to the JSON object. If the function is
22919     called on a JSON null value, an empty object is created before inserting
22920     @a val.
22921 
22922     @param[in] val the value to add to the JSON object
22923 
22924     @throw type_error.308 when called on a type other than JSON object or
22925     null; example: `"cannot use push_back() with number"`
22926 
22927     @complexity Logarithmic in the size of the container, O(log(`size()`)).
22928 
22929     @liveexample{The example shows how `push_back()` and `+=` can be used to
22930     add elements to a JSON object. Note how the `null` value was silently
22931     converted to a JSON object.,push_back__object_t__value}
22932 
22933     @since version 1.0.0
22934     */
push_back(const typename object_t::value_type & val)22935     void push_back(const typename object_t::value_type& val)
22936     {
22937         // push_back only works for null objects or objects
22938         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22939         {
22940             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22941         }
22942 
22943         // transform null object into an object
22944         if (is_null())
22945         {
22946             m_type = value_t::object;
22947             m_value = value_t::object;
22948             assert_invariant();
22949         }
22950 
22951         // add element to object
22952         auto res = m_value.object->insert(val);
22953         set_parent(res.first->second);
22954     }
22955 
22956     /*!
22957     @brief add an object to an object
22958     @copydoc push_back(const typename object_t::value_type&)
22959     */
operator +=(const typename object_t::value_type & val)22960     reference operator+=(const typename object_t::value_type& val)
22961     {
22962         push_back(val);
22963         return *this;
22964     }
22965 
22966     /*!
22967     @brief add an object to an object
22968 
22969     This function allows to use `push_back` with an initializer list. In case
22970 
22971     1. the current value is an object,
22972     2. the initializer list @a init contains only two elements, and
22973     3. the first element of @a init is a string,
22974 
22975     @a init is converted into an object element and added using
22976     @ref push_back(const typename object_t::value_type&). Otherwise, @a init
22977     is converted to a JSON value and added using @ref push_back(basic_json&&).
22978 
22979     @param[in] init  an initializer list
22980 
22981     @complexity Linear in the size of the initializer list @a init.
22982 
22983     @note This function is required to resolve an ambiguous overload error,
22984           because pairs like `{"key", "value"}` can be both interpreted as
22985           `object_t::value_type` or `std::initializer_list<basic_json>`, see
22986           https://github.com/nlohmann/json/issues/235 for more information.
22987 
22988     @liveexample{The example shows how initializer lists are treated as
22989     objects when possible.,push_back__initializer_list}
22990     */
push_back(initializer_list_t init)22991     void push_back(initializer_list_t init)
22992     {
22993         if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22994         {
22995             basic_json&& key = init.begin()->moved_or_copied();
22996             push_back(typename object_t::value_type(
22997                           std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22998         }
22999         else
23000         {
23001             push_back(basic_json(init));
23002         }
23003     }
23004 
23005     /*!
23006     @brief add an object to an object
23007     @copydoc push_back(initializer_list_t)
23008     */
operator +=(initializer_list_t init)23009     reference operator+=(initializer_list_t init)
23010     {
23011         push_back(init);
23012         return *this;
23013     }
23014 
23015     /*!
23016     @brief add an object to an array
23017 
23018     Creates a JSON value from the passed parameters @a args to the end of the
23019     JSON value. If the function is called on a JSON null value, an empty array
23020     is created before appending the value created from @a args.
23021 
23022     @param[in] args arguments to forward to a constructor of @ref basic_json
23023     @tparam Args compatible types to create a @ref basic_json object
23024 
23025     @return reference to the inserted element
23026 
23027     @throw type_error.311 when called on a type other than JSON array or
23028     null; example: `"cannot use emplace_back() with number"`
23029 
23030     @complexity Amortized constant.
23031 
23032     @liveexample{The example shows how `push_back()` can be used to add
23033     elements to a JSON array. Note how the `null` value was silently converted
23034     to a JSON array.,emplace_back}
23035 
23036     @since version 2.0.8, returns reference since 3.7.0
23037     */
23038     template<class... Args>
emplace_back(Args &&...args)23039     reference emplace_back(Args&& ... args)
23040     {
23041         // emplace_back only works for null objects or arrays
23042         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23043         {
23044             JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
23045         }
23046 
23047         // transform null object into an array
23048         if (is_null())
23049         {
23050             m_type = value_t::array;
23051             m_value = value_t::array;
23052             assert_invariant();
23053         }
23054 
23055         // add element to array (perfect forwarding)
23056         const auto old_capacity = m_value.array->capacity();
23057         m_value.array->emplace_back(std::forward<Args>(args)...);
23058         return set_parent(m_value.array->back(), old_capacity);
23059     }
23060 
23061     /*!
23062     @brief add an object to an object if key does not exist
23063 
23064     Inserts a new element into a JSON object constructed in-place with the
23065     given @a args if there is no element with the key in the container. If the
23066     function is called on a JSON null value, an empty object is created before
23067     appending the value created from @a args.
23068 
23069     @param[in] args arguments to forward to a constructor of @ref basic_json
23070     @tparam Args compatible types to create a @ref basic_json object
23071 
23072     @return a pair consisting of an iterator to the inserted element, or the
23073             already-existing element if no insertion happened, and a bool
23074             denoting whether the insertion took place.
23075 
23076     @throw type_error.311 when called on a type other than JSON object or
23077     null; example: `"cannot use emplace() with number"`
23078 
23079     @complexity Logarithmic in the size of the container, O(log(`size()`)).
23080 
23081     @liveexample{The example shows how `emplace()` can be used to add elements
23082     to a JSON object. Note how the `null` value was silently converted to a
23083     JSON object. Further note how no value is added if there was already one
23084     value stored with the same key.,emplace}
23085 
23086     @since version 2.0.8
23087     */
23088     template<class... Args>
emplace(Args &&...args)23089     std::pair<iterator, bool> emplace(Args&& ... args)
23090     {
23091         // emplace only works for null objects or arrays
23092         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23093         {
23094             JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
23095         }
23096 
23097         // transform null object into an object
23098         if (is_null())
23099         {
23100             m_type = value_t::object;
23101             m_value = value_t::object;
23102             assert_invariant();
23103         }
23104 
23105         // add element to array (perfect forwarding)
23106         auto res = m_value.object->emplace(std::forward<Args>(args)...);
23107         set_parent(res.first->second);
23108 
23109         // create result iterator and set iterator to the result of emplace
23110         auto it = begin();
23111         it.m_it.object_iterator = res.first;
23112 
23113         // return pair of iterator and boolean
23114         return {it, res.second};
23115     }
23116 
23117     /// Helper for insertion of an iterator
23118     /// @note: This uses std::distance to support GCC 4.8,
23119     ///        see https://github.com/nlohmann/json/pull/1257
23120     template<typename... Args>
insert_iterator(const_iterator pos,Args &&...args)23121     iterator insert_iterator(const_iterator pos, Args&& ... args)
23122     {
23123         iterator result(this);
23124         JSON_ASSERT(m_value.array != nullptr);
23125 
23126         auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
23127         m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
23128         result.m_it.array_iterator = m_value.array->begin() + insert_pos;
23129 
23130         // This could have been written as:
23131         // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
23132         // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
23133 
23134         set_parents();
23135         return result;
23136     }
23137 
23138     /*!
23139     @brief inserts element
23140 
23141     Inserts element @a val before iterator @a pos.
23142 
23143     @param[in] pos iterator before which the content will be inserted; may be
23144     the end() iterator
23145     @param[in] val element to insert
23146     @return iterator pointing to the inserted @a val.
23147 
23148     @throw type_error.309 if called on JSON values other than arrays;
23149     example: `"cannot use insert() with string"`
23150     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23151     example: `"iterator does not fit current value"`
23152 
23153     @complexity Constant plus linear in the distance between @a pos and end of
23154     the container.
23155 
23156     @liveexample{The example shows how `insert()` is used.,insert}
23157 
23158     @since version 1.0.0
23159     */
insert(const_iterator pos,const basic_json & val)23160     iterator insert(const_iterator pos, const basic_json& val)
23161     {
23162         // insert only works for arrays
23163         if (JSON_HEDLEY_LIKELY(is_array()))
23164         {
23165             // check if iterator pos fits to this JSON value
23166             if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23167             {
23168                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23169             }
23170 
23171             // insert to array and return iterator
23172             return insert_iterator(pos, val);
23173         }
23174 
23175         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23176     }
23177 
23178     /*!
23179     @brief inserts element
23180     @copydoc insert(const_iterator, const basic_json&)
23181     */
insert(const_iterator pos,basic_json && val)23182     iterator insert(const_iterator pos, basic_json&& val)
23183     {
23184         return insert(pos, val);
23185     }
23186 
23187     /*!
23188     @brief inserts elements
23189 
23190     Inserts @a cnt copies of @a val before iterator @a pos.
23191 
23192     @param[in] pos iterator before which the content will be inserted; may be
23193     the end() iterator
23194     @param[in] cnt number of copies of @a val to insert
23195     @param[in] val element to insert
23196     @return iterator pointing to the first element inserted, or @a pos if
23197     `cnt==0`
23198 
23199     @throw type_error.309 if called on JSON values other than arrays; example:
23200     `"cannot use insert() with string"`
23201     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23202     example: `"iterator does not fit current value"`
23203 
23204     @complexity Linear in @a cnt plus linear in the distance between @a pos
23205     and end of the container.
23206 
23207     @liveexample{The example shows how `insert()` is used.,insert__count}
23208 
23209     @since version 1.0.0
23210     */
insert(const_iterator pos,size_type cnt,const basic_json & val)23211     iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
23212     {
23213         // insert only works for arrays
23214         if (JSON_HEDLEY_LIKELY(is_array()))
23215         {
23216             // check if iterator pos fits to this JSON value
23217             if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23218             {
23219                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23220             }
23221 
23222             // insert to array and return iterator
23223             return insert_iterator(pos, cnt, val);
23224         }
23225 
23226         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23227     }
23228 
23229     /*!
23230     @brief inserts elements
23231 
23232     Inserts elements from range `[first, last)` before iterator @a pos.
23233 
23234     @param[in] pos iterator before which the content will be inserted; may be
23235     the end() iterator
23236     @param[in] first begin of the range of elements to insert
23237     @param[in] last end of the range of elements to insert
23238 
23239     @throw type_error.309 if called on JSON values other than arrays; example:
23240     `"cannot use insert() with string"`
23241     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23242     example: `"iterator does not fit current value"`
23243     @throw invalid_iterator.210 if @a first and @a last do not belong to the
23244     same JSON value; example: `"iterators do not fit"`
23245     @throw invalid_iterator.211 if @a first or @a last are iterators into
23246     container for which insert is called; example: `"passed iterators may not
23247     belong to container"`
23248 
23249     @return iterator pointing to the first element inserted, or @a pos if
23250     `first==last`
23251 
23252     @complexity Linear in `std::distance(first, last)` plus linear in the
23253     distance between @a pos and end of the container.
23254 
23255     @liveexample{The example shows how `insert()` is used.,insert__range}
23256 
23257     @since version 1.0.0
23258     */
insert(const_iterator pos,const_iterator first,const_iterator last)23259     iterator insert(const_iterator pos, const_iterator first, const_iterator last)
23260     {
23261         // insert only works for arrays
23262         if (JSON_HEDLEY_UNLIKELY(!is_array()))
23263         {
23264             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23265         }
23266 
23267         // check if iterator pos fits to this JSON value
23268         if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23269         {
23270             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23271         }
23272 
23273         // check if range iterators belong to the same JSON object
23274         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23275         {
23276             JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23277         }
23278 
23279         if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
23280         {
23281             JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
23282         }
23283 
23284         // insert to array and return iterator
23285         return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
23286     }
23287 
23288     /*!
23289     @brief inserts elements
23290 
23291     Inserts elements from initializer list @a ilist before iterator @a pos.
23292 
23293     @param[in] pos iterator before which the content will be inserted; may be
23294     the end() iterator
23295     @param[in] ilist initializer list to insert the values from
23296 
23297     @throw type_error.309 if called on JSON values other than arrays; example:
23298     `"cannot use insert() with string"`
23299     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23300     example: `"iterator does not fit current value"`
23301 
23302     @return iterator pointing to the first element inserted, or @a pos if
23303     `ilist` is empty
23304 
23305     @complexity Linear in `ilist.size()` plus linear in the distance between
23306     @a pos and end of the container.
23307 
23308     @liveexample{The example shows how `insert()` is used.,insert__ilist}
23309 
23310     @since version 1.0.0
23311     */
insert(const_iterator pos,initializer_list_t ilist)23312     iterator insert(const_iterator pos, initializer_list_t ilist)
23313     {
23314         // insert only works for arrays
23315         if (JSON_HEDLEY_UNLIKELY(!is_array()))
23316         {
23317             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23318         }
23319 
23320         // check if iterator pos fits to this JSON value
23321         if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23322         {
23323             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23324         }
23325 
23326         // insert to array and return iterator
23327         return insert_iterator(pos, ilist.begin(), ilist.end());
23328     }
23329 
23330     /*!
23331     @brief inserts elements
23332 
23333     Inserts elements from range `[first, last)`.
23334 
23335     @param[in] first begin of the range of elements to insert
23336     @param[in] last end of the range of elements to insert
23337 
23338     @throw type_error.309 if called on JSON values other than objects; example:
23339     `"cannot use insert() with string"`
23340     @throw invalid_iterator.202 if iterator @a first or @a last does does not
23341     point to an object; example: `"iterators first and last must point to
23342     objects"`
23343     @throw invalid_iterator.210 if @a first and @a last do not belong to the
23344     same JSON value; example: `"iterators do not fit"`
23345 
23346     @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
23347     of elements to insert.
23348 
23349     @liveexample{The example shows how `insert()` is used.,insert__range_object}
23350 
23351     @since version 3.0.0
23352     */
insert(const_iterator first,const_iterator last)23353     void insert(const_iterator first, const_iterator last)
23354     {
23355         // insert only works for objects
23356         if (JSON_HEDLEY_UNLIKELY(!is_object()))
23357         {
23358             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23359         }
23360 
23361         // check if range iterators belong to the same JSON object
23362         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23363         {
23364             JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23365         }
23366 
23367         // passed iterators must belong to objects
23368         if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23369         {
23370             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23371         }
23372 
23373         m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
23374     }
23375 
23376     /*!
23377     @brief updates a JSON object from another object, overwriting existing keys
23378 
23379     Inserts all values from JSON object @a j and overwrites existing keys.
23380 
23381     @param[in] j  JSON object to read values from
23382 
23383     @throw type_error.312 if called on JSON values other than objects; example:
23384     `"cannot use update() with string"`
23385 
23386     @complexity O(N*log(size() + N)), where N is the number of elements to
23387                 insert.
23388 
23389     @liveexample{The example shows how `update()` is used.,update}
23390 
23391     @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
23392 
23393     @since version 3.0.0
23394     */
update(const_reference j)23395     void update(const_reference j)
23396     {
23397         // implicitly convert null value to an empty object
23398         if (is_null())
23399         {
23400             m_type = value_t::object;
23401             m_value.object = create<object_t>();
23402             assert_invariant();
23403         }
23404 
23405         if (JSON_HEDLEY_UNLIKELY(!is_object()))
23406         {
23407             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23408         }
23409         if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
23410         {
23411             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
23412         }
23413 
23414         for (auto it = j.cbegin(); it != j.cend(); ++it)
23415         {
23416             m_value.object->operator[](it.key()) = it.value();
23417         }
23418     }
23419 
23420     /*!
23421     @brief updates a JSON object from another object, overwriting existing keys
23422 
23423     Inserts all values from from range `[first, last)` and overwrites existing
23424     keys.
23425 
23426     @param[in] first begin of the range of elements to insert
23427     @param[in] last end of the range of elements to insert
23428 
23429     @throw type_error.312 if called on JSON values other than objects; example:
23430     `"cannot use update() with string"`
23431     @throw invalid_iterator.202 if iterator @a first or @a last does does not
23432     point to an object; example: `"iterators first and last must point to
23433     objects"`
23434     @throw invalid_iterator.210 if @a first and @a last do not belong to the
23435     same JSON value; example: `"iterators do not fit"`
23436 
23437     @complexity O(N*log(size() + N)), where N is the number of elements to
23438                 insert.
23439 
23440     @liveexample{The example shows how `update()` is used__range.,update}
23441 
23442     @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
23443 
23444     @since version 3.0.0
23445     */
update(const_iterator first,const_iterator last)23446     void update(const_iterator first, const_iterator last)
23447     {
23448         // implicitly convert null value to an empty object
23449         if (is_null())
23450         {
23451             m_type = value_t::object;
23452             m_value.object = create<object_t>();
23453             assert_invariant();
23454         }
23455 
23456         if (JSON_HEDLEY_UNLIKELY(!is_object()))
23457         {
23458             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23459         }
23460 
23461         // check if range iterators belong to the same JSON object
23462         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23463         {
23464             JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23465         }
23466 
23467         // passed iterators must belong to objects
23468         if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
23469                                  || !last.m_object->is_object()))
23470         {
23471             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23472         }
23473 
23474         for (auto it = first; it != last; ++it)
23475         {
23476             m_value.object->operator[](it.key()) = it.value();
23477         }
23478     }
23479 
23480     /*!
23481     @brief exchanges the values
23482 
23483     Exchanges the contents of the JSON value with those of @a other. Does not
23484     invoke any move, copy, or swap operations on individual elements. All
23485     iterators and references remain valid. The past-the-end iterator is
23486     invalidated.
23487 
23488     @param[in,out] other JSON value to exchange the contents with
23489 
23490     @complexity Constant.
23491 
23492     @liveexample{The example below shows how JSON values can be swapped with
23493     `swap()`.,swap__reference}
23494 
23495     @since version 1.0.0
23496     */
swap(reference other)23497     void swap(reference other) noexcept (
23498         std::is_nothrow_move_constructible<value_t>::value&&
23499         std::is_nothrow_move_assignable<value_t>::value&&
23500         std::is_nothrow_move_constructible<json_value>::value&&
23501         std::is_nothrow_move_assignable<json_value>::value
23502     )
23503     {
23504         std::swap(m_type, other.m_type);
23505         std::swap(m_value, other.m_value);
23506 
23507         set_parents();
23508         other.set_parents();
23509         assert_invariant();
23510     }
23511 
23512     /*!
23513     @brief exchanges the values
23514 
23515     Exchanges the contents of the JSON value from @a left with those of @a right. Does not
23516     invoke any move, copy, or swap operations on individual elements. All
23517     iterators and references remain valid. The past-the-end iterator is
23518     invalidated. implemented as a friend function callable via ADL.
23519 
23520     @param[in,out] left JSON value to exchange the contents with
23521     @param[in,out] right JSON value to exchange the contents with
23522 
23523     @complexity Constant.
23524 
23525     @liveexample{The example below shows how JSON values can be swapped with
23526     `swap()`.,swap__reference}
23527 
23528     @since version 1.0.0
23529     */
swap(reference left,reference right)23530     friend void swap(reference left, reference right) noexcept (
23531         std::is_nothrow_move_constructible<value_t>::value&&
23532         std::is_nothrow_move_assignable<value_t>::value&&
23533         std::is_nothrow_move_constructible<json_value>::value&&
23534         std::is_nothrow_move_assignable<json_value>::value
23535     )
23536     {
23537         left.swap(right);
23538     }
23539 
23540     /*!
23541     @brief exchanges the values
23542 
23543     Exchanges the contents of a JSON array with those of @a other. Does not
23544     invoke any move, copy, or swap operations on individual elements. All
23545     iterators and references remain valid. The past-the-end iterator is
23546     invalidated.
23547 
23548     @param[in,out] other array to exchange the contents with
23549 
23550     @throw type_error.310 when JSON value is not an array; example: `"cannot
23551     use swap() with string"`
23552 
23553     @complexity Constant.
23554 
23555     @liveexample{The example below shows how arrays can be swapped with
23556     `swap()`.,swap__array_t}
23557 
23558     @since version 1.0.0
23559     */
swap(array_t & other)23560     void swap(array_t& other) // NOLINT(bugprone-exception-escape)
23561     {
23562         // swap only works for arrays
23563         if (JSON_HEDLEY_LIKELY(is_array()))
23564         {
23565             std::swap(*(m_value.array), other);
23566         }
23567         else
23568         {
23569             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23570         }
23571     }
23572 
23573     /*!
23574     @brief exchanges the values
23575 
23576     Exchanges the contents of a JSON object with those of @a other. Does not
23577     invoke any move, copy, or swap operations on individual elements. All
23578     iterators and references remain valid. The past-the-end iterator is
23579     invalidated.
23580 
23581     @param[in,out] other object to exchange the contents with
23582 
23583     @throw type_error.310 when JSON value is not an object; example:
23584     `"cannot use swap() with string"`
23585 
23586     @complexity Constant.
23587 
23588     @liveexample{The example below shows how objects can be swapped with
23589     `swap()`.,swap__object_t}
23590 
23591     @since version 1.0.0
23592     */
swap(object_t & other)23593     void swap(object_t& other) // NOLINT(bugprone-exception-escape)
23594     {
23595         // swap only works for objects
23596         if (JSON_HEDLEY_LIKELY(is_object()))
23597         {
23598             std::swap(*(m_value.object), other);
23599         }
23600         else
23601         {
23602             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23603         }
23604     }
23605 
23606     /*!
23607     @brief exchanges the values
23608 
23609     Exchanges the contents of a JSON string with those of @a other. Does not
23610     invoke any move, copy, or swap operations on individual elements. All
23611     iterators and references remain valid. The past-the-end iterator is
23612     invalidated.
23613 
23614     @param[in,out] other string to exchange the contents with
23615 
23616     @throw type_error.310 when JSON value is not a string; example: `"cannot
23617     use swap() with boolean"`
23618 
23619     @complexity Constant.
23620 
23621     @liveexample{The example below shows how strings can be swapped with
23622     `swap()`.,swap__string_t}
23623 
23624     @since version 1.0.0
23625     */
swap(string_t & other)23626     void swap(string_t& other) // NOLINT(bugprone-exception-escape)
23627     {
23628         // swap only works for strings
23629         if (JSON_HEDLEY_LIKELY(is_string()))
23630         {
23631             std::swap(*(m_value.string), other);
23632         }
23633         else
23634         {
23635             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23636         }
23637     }
23638 
23639     /*!
23640     @brief exchanges the values
23641 
23642     Exchanges the contents of a JSON string with those of @a other. Does not
23643     invoke any move, copy, or swap operations on individual elements. All
23644     iterators and references remain valid. The past-the-end iterator is
23645     invalidated.
23646 
23647     @param[in,out] other binary to exchange the contents with
23648 
23649     @throw type_error.310 when JSON value is not a string; example: `"cannot
23650     use swap() with boolean"`
23651 
23652     @complexity Constant.
23653 
23654     @liveexample{The example below shows how strings can be swapped with
23655     `swap()`.,swap__binary_t}
23656 
23657     @since version 3.8.0
23658     */
swap(binary_t & other)23659     void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
23660     {
23661         // swap only works for strings
23662         if (JSON_HEDLEY_LIKELY(is_binary()))
23663         {
23664             std::swap(*(m_value.binary), other);
23665         }
23666         else
23667         {
23668             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23669         }
23670     }
23671 
23672     /// @copydoc swap(binary_t&)
swap(typename binary_t::container_type & other)23673     void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
23674     {
23675         // swap only works for strings
23676         if (JSON_HEDLEY_LIKELY(is_binary()))
23677         {
23678             std::swap(*(m_value.binary), other);
23679         }
23680         else
23681         {
23682             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23683         }
23684     }
23685 
23686     /// @}
23687 
23688   public:
23689     //////////////////////////////////////////
23690     // lexicographical comparison operators //
23691     //////////////////////////////////////////
23692 
23693     /// @name lexicographical comparison operators
23694     /// @{
23695 
23696     /*!
23697     @brief comparison: equal
23698 
23699     Compares two JSON values for equality according to the following rules:
23700     - Two JSON values are equal if (1) they are from the same type and (2)
23701       their stored values are the same according to their respective
23702       `operator==`.
23703     - Integer and floating-point numbers are automatically converted before
23704       comparison. Note that two NaN values are always treated as unequal.
23705     - Two JSON null values are equal.
23706 
23707     @note Floating-point inside JSON values numbers are compared with
23708     `json::number_float_t::operator==` which is `double::operator==` by
23709     default. To compare floating-point while respecting an epsilon, an alternative
23710     [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39)
23711     could be used, for instance
23712     @code {.cpp}
23713     template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
23714     inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
23715     {
23716         return std::abs(a - b) <= epsilon;
23717     }
23718     @endcode
23719     Or you can self-defined operator equal function like this:
23720     @code {.cpp}
23721     bool my_equal(const_reference lhs, const_reference rhs) {
23722     const auto lhs_type lhs.type();
23723     const auto rhs_type rhs.type();
23724     if (lhs_type == rhs_type) {
23725         switch(lhs_type)
23726             // self_defined case
23727             case value_t::number_float:
23728                 return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();
23729             // other cases remain the same with the original
23730             ...
23731     }
23732     ...
23733     }
23734     @endcode
23735 
23736     @note NaN values never compare equal to themselves or to other NaN values.
23737 
23738     @param[in] lhs  first JSON value to consider
23739     @param[in] rhs  second JSON value to consider
23740     @return whether the values @a lhs and @a rhs are equal
23741 
23742     @exceptionsafety No-throw guarantee: this function never throws exceptions.
23743 
23744     @complexity Linear.
23745 
23746     @liveexample{The example demonstrates comparing several JSON
23747     types.,operator__equal}
23748 
23749     @since version 1.0.0
23750     */
operator ==(const_reference lhs,const_reference rhs)23751     friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23752     {
23753 #ifdef __GNUC__
23754 #pragma GCC diagnostic push
23755 #pragma GCC diagnostic ignored "-Wfloat-equal"
23756 #endif
23757         const auto lhs_type = lhs.type();
23758         const auto rhs_type = rhs.type();
23759 
23760         if (lhs_type == rhs_type)
23761         {
23762             switch (lhs_type)
23763             {
23764                 case value_t::array:
23765                     return *lhs.m_value.array == *rhs.m_value.array;
23766 
23767                 case value_t::object:
23768                     return *lhs.m_value.object == *rhs.m_value.object;
23769 
23770                 case value_t::null:
23771                     return true;
23772 
23773                 case value_t::string:
23774                     return *lhs.m_value.string == *rhs.m_value.string;
23775 
23776                 case value_t::boolean:
23777                     return lhs.m_value.boolean == rhs.m_value.boolean;
23778 
23779                 case value_t::number_integer:
23780                     return lhs.m_value.number_integer == rhs.m_value.number_integer;
23781 
23782                 case value_t::number_unsigned:
23783                     return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
23784 
23785                 case value_t::number_float:
23786                     return lhs.m_value.number_float == rhs.m_value.number_float;
23787 
23788                 case value_t::binary:
23789                     return *lhs.m_value.binary == *rhs.m_value.binary;
23790 
23791                 case value_t::discarded:
23792                 default:
23793                     return false;
23794             }
23795         }
23796         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23797         {
23798             return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
23799         }
23800         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23801         {
23802             return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
23803         }
23804         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23805         {
23806             return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
23807         }
23808         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23809         {
23810             return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
23811         }
23812         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23813         {
23814             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
23815         }
23816         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23817         {
23818             return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23819         }
23820 
23821         return false;
23822 #ifdef __GNUC__
23823 #pragma GCC diagnostic pop
23824 #endif
23825     }
23826 
23827     /*!
23828     @brief comparison: equal
23829     @copydoc operator==(const_reference, const_reference)
23830     */
23831     template<typename ScalarType, typename std::enable_if<
23832                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const_reference lhs,ScalarType rhs)23833     friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23834     {
23835         return lhs == basic_json(rhs);
23836     }
23837 
23838     /*!
23839     @brief comparison: equal
23840     @copydoc operator==(const_reference, const_reference)
23841     */
23842     template<typename ScalarType, typename std::enable_if<
23843                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(ScalarType lhs,const_reference rhs)23844     friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23845     {
23846         return basic_json(lhs) == rhs;
23847     }
23848 
23849     /*!
23850     @brief comparison: not equal
23851 
23852     Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
23853 
23854     @param[in] lhs  first JSON value to consider
23855     @param[in] rhs  second JSON value to consider
23856     @return whether the values @a lhs and @a rhs are not equal
23857 
23858     @complexity Linear.
23859 
23860     @exceptionsafety No-throw guarantee: this function never throws exceptions.
23861 
23862     @liveexample{The example demonstrates comparing several JSON
23863     types.,operator__notequal}
23864 
23865     @since version 1.0.0
23866     */
operator !=(const_reference lhs,const_reference rhs)23867     friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23868     {
23869         return !(lhs == rhs);
23870     }
23871 
23872     /*!
23873     @brief comparison: not equal
23874     @copydoc operator!=(const_reference, const_reference)
23875     */
23876     template<typename ScalarType, typename std::enable_if<
23877                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const_reference lhs,ScalarType rhs)23878     friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23879     {
23880         return lhs != basic_json(rhs);
23881     }
23882 
23883     /*!
23884     @brief comparison: not equal
23885     @copydoc operator!=(const_reference, const_reference)
23886     */
23887     template<typename ScalarType, typename std::enable_if<
23888                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(ScalarType lhs,const_reference rhs)23889     friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23890     {
23891         return basic_json(lhs) != rhs;
23892     }
23893 
23894     /*!
23895     @brief comparison: less than
23896 
23897     Compares whether one JSON value @a lhs is less than another JSON value @a
23898     rhs according to the following rules:
23899     - If @a lhs and @a rhs have the same type, the values are compared using
23900       the default `<` operator.
23901     - Integer and floating-point numbers are automatically converted before
23902       comparison
23903     - In case @a lhs and @a rhs have different types, the values are ignored
23904       and the order of the types is considered, see
23905       @ref operator<(const value_t, const value_t).
23906 
23907     @param[in] lhs  first JSON value to consider
23908     @param[in] rhs  second JSON value to consider
23909     @return whether @a lhs is less than @a rhs
23910 
23911     @complexity Linear.
23912 
23913     @exceptionsafety No-throw guarantee: this function never throws exceptions.
23914 
23915     @liveexample{The example demonstrates comparing several JSON
23916     types.,operator__less}
23917 
23918     @since version 1.0.0
23919     */
operator <(const_reference lhs,const_reference rhs)23920     friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23921     {
23922         const auto lhs_type = lhs.type();
23923         const auto rhs_type = rhs.type();
23924 
23925         if (lhs_type == rhs_type)
23926         {
23927             switch (lhs_type)
23928             {
23929                 case value_t::array:
23930                     // note parentheses are necessary, see
23931                     // https://github.com/nlohmann/json/issues/1530
23932                     return (*lhs.m_value.array) < (*rhs.m_value.array);
23933 
23934                 case value_t::object:
23935                     return (*lhs.m_value.object) < (*rhs.m_value.object);
23936 
23937                 case value_t::null:
23938                     return false;
23939 
23940                 case value_t::string:
23941                     return (*lhs.m_value.string) < (*rhs.m_value.string);
23942 
23943                 case value_t::boolean:
23944                     return (lhs.m_value.boolean) < (rhs.m_value.boolean);
23945 
23946                 case value_t::number_integer:
23947                     return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
23948 
23949                 case value_t::number_unsigned:
23950                     return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
23951 
23952                 case value_t::number_float:
23953                     return (lhs.m_value.number_float) < (rhs.m_value.number_float);
23954 
23955                 case value_t::binary:
23956                     return (*lhs.m_value.binary) < (*rhs.m_value.binary);
23957 
23958                 case value_t::discarded:
23959                 default:
23960                     return false;
23961             }
23962         }
23963         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23964         {
23965             return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
23966         }
23967         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23968         {
23969             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
23970         }
23971         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23972         {
23973             return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
23974         }
23975         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23976         {
23977             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
23978         }
23979         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23980         {
23981             return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23982         }
23983         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23984         {
23985             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
23986         }
23987 
23988         // We only reach this line if we cannot compare values. In that case,
23989         // we compare types. Note we have to call the operator explicitly,
23990         // because MSVC has problems otherwise.
23991         return operator<(lhs_type, rhs_type);
23992     }
23993 
23994     /*!
23995     @brief comparison: less than
23996     @copydoc operator<(const_reference, const_reference)
23997     */
23998     template<typename ScalarType, typename std::enable_if<
23999                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const_reference lhs,ScalarType rhs)24000     friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
24001     {
24002         return lhs < basic_json(rhs);
24003     }
24004 
24005     /*!
24006     @brief comparison: less than
24007     @copydoc operator<(const_reference, const_reference)
24008     */
24009     template<typename ScalarType, typename std::enable_if<
24010                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(ScalarType lhs,const_reference rhs)24011     friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
24012     {
24013         return basic_json(lhs) < rhs;
24014     }
24015 
24016     /*!
24017     @brief comparison: less than or equal
24018 
24019     Compares whether one JSON value @a lhs is less than or equal to another
24020     JSON value by calculating `not (rhs < lhs)`.
24021 
24022     @param[in] lhs  first JSON value to consider
24023     @param[in] rhs  second JSON value to consider
24024     @return whether @a lhs is less than or equal to @a rhs
24025 
24026     @complexity Linear.
24027 
24028     @exceptionsafety No-throw guarantee: this function never throws exceptions.
24029 
24030     @liveexample{The example demonstrates comparing several JSON
24031     types.,operator__greater}
24032 
24033     @since version 1.0.0
24034     */
operator <=(const_reference lhs,const_reference rhs)24035     friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
24036     {
24037         return !(rhs < lhs);
24038     }
24039 
24040     /*!
24041     @brief comparison: less than or equal
24042     @copydoc operator<=(const_reference, const_reference)
24043     */
24044     template<typename ScalarType, typename std::enable_if<
24045                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const_reference lhs,ScalarType rhs)24046     friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
24047     {
24048         return lhs <= basic_json(rhs);
24049     }
24050 
24051     /*!
24052     @brief comparison: less than or equal
24053     @copydoc operator<=(const_reference, const_reference)
24054     */
24055     template<typename ScalarType, typename std::enable_if<
24056                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(ScalarType lhs,const_reference rhs)24057     friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
24058     {
24059         return basic_json(lhs) <= rhs;
24060     }
24061 
24062     /*!
24063     @brief comparison: greater than
24064 
24065     Compares whether one JSON value @a lhs is greater than another
24066     JSON value by calculating `not (lhs <= rhs)`.
24067 
24068     @param[in] lhs  first JSON value to consider
24069     @param[in] rhs  second JSON value to consider
24070     @return whether @a lhs is greater than to @a rhs
24071 
24072     @complexity Linear.
24073 
24074     @exceptionsafety No-throw guarantee: this function never throws exceptions.
24075 
24076     @liveexample{The example demonstrates comparing several JSON
24077     types.,operator__lessequal}
24078 
24079     @since version 1.0.0
24080     */
operator >(const_reference lhs,const_reference rhs)24081     friend bool operator>(const_reference lhs, const_reference rhs) noexcept
24082     {
24083         return !(lhs <= rhs);
24084     }
24085 
24086     /*!
24087     @brief comparison: greater than
24088     @copydoc operator>(const_reference, const_reference)
24089     */
24090     template<typename ScalarType, typename std::enable_if<
24091                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const_reference lhs,ScalarType rhs)24092     friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
24093     {
24094         return lhs > basic_json(rhs);
24095     }
24096 
24097     /*!
24098     @brief comparison: greater than
24099     @copydoc operator>(const_reference, const_reference)
24100     */
24101     template<typename ScalarType, typename std::enable_if<
24102                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(ScalarType lhs,const_reference rhs)24103     friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
24104     {
24105         return basic_json(lhs) > rhs;
24106     }
24107 
24108     /*!
24109     @brief comparison: greater than or equal
24110 
24111     Compares whether one JSON value @a lhs is greater than or equal to another
24112     JSON value by calculating `not (lhs < rhs)`.
24113 
24114     @param[in] lhs  first JSON value to consider
24115     @param[in] rhs  second JSON value to consider
24116     @return whether @a lhs is greater than or equal to @a rhs
24117 
24118     @complexity Linear.
24119 
24120     @exceptionsafety No-throw guarantee: this function never throws exceptions.
24121 
24122     @liveexample{The example demonstrates comparing several JSON
24123     types.,operator__greaterequal}
24124 
24125     @since version 1.0.0
24126     */
operator >=(const_reference lhs,const_reference rhs)24127     friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
24128     {
24129         return !(lhs < rhs);
24130     }
24131 
24132     /*!
24133     @brief comparison: greater than or equal
24134     @copydoc operator>=(const_reference, const_reference)
24135     */
24136     template<typename ScalarType, typename std::enable_if<
24137                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const_reference lhs,ScalarType rhs)24138     friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
24139     {
24140         return lhs >= basic_json(rhs);
24141     }
24142 
24143     /*!
24144     @brief comparison: greater than or equal
24145     @copydoc operator>=(const_reference, const_reference)
24146     */
24147     template<typename ScalarType, typename std::enable_if<
24148                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(ScalarType lhs,const_reference rhs)24149     friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
24150     {
24151         return basic_json(lhs) >= rhs;
24152     }
24153 
24154     /// @}
24155 
24156     ///////////////////
24157     // serialization //
24158     ///////////////////
24159 
24160     /// @name serialization
24161     /// @{
24162 #ifndef JSON_NO_IO
24163     /*!
24164     @brief serialize to stream
24165 
24166     Serialize the given JSON value @a j to the output stream @a o. The JSON
24167     value will be serialized using the @ref dump member function.
24168 
24169     - The indentation of the output can be controlled with the member variable
24170       `width` of the output stream @a o. For instance, using the manipulator
24171       `std::setw(4)` on @a o sets the indentation level to `4` and the
24172       serialization result is the same as calling `dump(4)`.
24173 
24174     - The indentation character can be controlled with the member variable
24175       `fill` of the output stream @a o. For instance, the manipulator
24176       `std::setfill('\\t')` sets indentation to use a tab character rather than
24177       the default space character.
24178 
24179     @param[in,out] o  stream to serialize to
24180     @param[in] j  JSON value to serialize
24181 
24182     @return the stream @a o
24183 
24184     @throw type_error.316 if a string stored inside the JSON value is not
24185                           UTF-8 encoded
24186 
24187     @complexity Linear.
24188 
24189     @liveexample{The example below shows the serialization with different
24190     parameters to `width` to adjust the indentation level.,operator_serialize}
24191 
24192     @since version 1.0.0; indentation character added in version 3.0.0
24193     */
operator <<(std::ostream & o,const basic_json & j)24194     friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
24195     {
24196         // read width member and use it as indentation parameter if nonzero
24197         const bool pretty_print = o.width() > 0;
24198         const auto indentation = pretty_print ? o.width() : 0;
24199 
24200         // reset width to 0 for subsequent calls to this stream
24201         o.width(0);
24202 
24203         // do the actual serialization
24204         serializer s(detail::output_adapter<char>(o), o.fill());
24205         s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
24206         return o;
24207     }
24208 
24209     /*!
24210     @brief serialize to stream
24211     @deprecated This stream operator is deprecated and will be removed in
24212                 future 4.0.0 of the library. Please use
24213                 @ref operator<<(std::ostream&, const basic_json&)
24214                 instead; that is, replace calls like `j >> o;` with `o << j;`.
24215     @since version 1.0.0; deprecated since version 3.0.0
24216     */
24217     JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
operator >>(const basic_json & j,std::ostream & o)24218     friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
24219     {
24220         return o << j;
24221     }
24222 #endif  // JSON_NO_IO
24223     /// @}
24224 
24225 
24226     /////////////////////
24227     // deserialization //
24228     /////////////////////
24229 
24230     /// @name deserialization
24231     /// @{
24232 
24233     /*!
24234     @brief deserialize from a compatible input
24235 
24236     @tparam InputType A compatible input, for instance
24237     - an std::istream object
24238     - a FILE pointer
24239     - a C-style array of characters
24240     - a pointer to a null-terminated string of single byte characters
24241     - an object obj for which begin(obj) and end(obj) produces a valid pair of
24242       iterators.
24243 
24244     @param[in] i  input to read from
24245     @param[in] cb  a parser callback function of type @ref parser_callback_t
24246     which is used to control the deserialization by filtering unwanted values
24247     (optional)
24248     @param[in] allow_exceptions  whether to throw exceptions in case of a
24249     parse error (optional, true by default)
24250     @param[in] ignore_comments  whether comments should be ignored and treated
24251     like whitespace (true) or yield a parse error (true); (optional, false by
24252     default)
24253 
24254     @return deserialized JSON value; in case of a parse error and
24255             @a allow_exceptions set to `false`, the return value will be
24256             value_t::discarded.
24257 
24258     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24259     of input; expected string literal""`
24260     @throw parse_error.102 if to_unicode fails or surrogate error
24261     @throw parse_error.103 if to_unicode fails
24262 
24263     @complexity Linear in the length of the input. The parser is a predictive
24264     LL(1) parser. The complexity can be higher if the parser callback function
24265     @a cb or reading from the input @a i has a super-linear complexity.
24266 
24267     @note A UTF-8 byte order mark is silently ignored.
24268 
24269     @liveexample{The example below demonstrates the `parse()` function reading
24270     from an array.,parse__array__parser_callback_t}
24271 
24272     @liveexample{The example below demonstrates the `parse()` function with
24273     and without callback function.,parse__string__parser_callback_t}
24274 
24275     @liveexample{The example below demonstrates the `parse()` function with
24276     and without callback function.,parse__istream__parser_callback_t}
24277 
24278     @liveexample{The example below demonstrates the `parse()` function reading
24279     from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
24280 
24281     @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to
24282     ignore comments.
24283     */
24284     template<typename InputType>
24285     JSON_HEDLEY_WARN_UNUSED_RESULT
parse(InputType && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)24286     static basic_json parse(InputType&& i,
24287                             const parser_callback_t cb = nullptr,
24288                             const bool allow_exceptions = true,
24289                             const bool ignore_comments = false)
24290     {
24291         basic_json result;
24292         parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
24293         return result;
24294     }
24295 
24296     /*!
24297     @brief deserialize from a pair of character iterators
24298 
24299     The value_type of the iterator must be a integral type with size of 1, 2 or
24300     4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.
24301 
24302     @param[in] first iterator to start of character range
24303     @param[in] last  iterator to end of character range
24304     @param[in] cb  a parser callback function of type @ref parser_callback_t
24305     which is used to control the deserialization by filtering unwanted values
24306     (optional)
24307     @param[in] allow_exceptions  whether to throw exceptions in case of a
24308     parse error (optional, true by default)
24309     @param[in] ignore_comments  whether comments should be ignored and treated
24310     like whitespace (true) or yield a parse error (true); (optional, false by
24311     default)
24312 
24313     @return deserialized JSON value; in case of a parse error and
24314             @a allow_exceptions set to `false`, the return value will be
24315             value_t::discarded.
24316 
24317     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24318     of input; expected string literal""`
24319     @throw parse_error.102 if to_unicode fails or surrogate error
24320     @throw parse_error.103 if to_unicode fails
24321     */
24322     template<typename IteratorType>
24323     JSON_HEDLEY_WARN_UNUSED_RESULT
parse(IteratorType first,IteratorType last,const parser_callback_t cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)24324     static basic_json parse(IteratorType first,
24325                             IteratorType last,
24326                             const parser_callback_t cb = nullptr,
24327                             const bool allow_exceptions = true,
24328                             const bool ignore_comments = false)
24329     {
24330         basic_json result;
24331         parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
24332         return result;
24333     }
24334 
24335     JSON_HEDLEY_WARN_UNUSED_RESULT
24336     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
parse(detail::span_input_adapter && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)24337     static basic_json parse(detail::span_input_adapter&& i,
24338                             const parser_callback_t cb = nullptr,
24339                             const bool allow_exceptions = true,
24340                             const bool ignore_comments = false)
24341     {
24342         basic_json result;
24343         parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
24344         return result;
24345     }
24346 
24347     /*!
24348     @brief check if the input is valid JSON
24349 
24350     Unlike the @ref parse(InputType&&, const parser_callback_t,const bool)
24351     function, this function neither throws an exception in case of invalid JSON
24352     input (i.e., a parse error) nor creates diagnostic information.
24353 
24354     @tparam InputType A compatible input, for instance
24355     - an std::istream object
24356     - a FILE pointer
24357     - a C-style array of characters
24358     - a pointer to a null-terminated string of single byte characters
24359     - an object obj for which begin(obj) and end(obj) produces a valid pair of
24360       iterators.
24361 
24362     @param[in] i input to read from
24363     @param[in] ignore_comments  whether comments should be ignored and treated
24364     like whitespace (true) or yield a parse error (true); (optional, false by
24365     default)
24366 
24367     @return Whether the input read from @a i is valid JSON.
24368 
24369     @complexity Linear in the length of the input. The parser is a predictive
24370     LL(1) parser.
24371 
24372     @note A UTF-8 byte order mark is silently ignored.
24373 
24374     @liveexample{The example below demonstrates the `accept()` function reading
24375     from a string.,accept__string}
24376     */
24377     template<typename InputType>
accept(InputType && i,const bool ignore_comments=false)24378     static bool accept(InputType&& i,
24379                        const bool ignore_comments = false)
24380     {
24381         return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
24382     }
24383 
24384     template<typename IteratorType>
accept(IteratorType first,IteratorType last,const bool ignore_comments=false)24385     static bool accept(IteratorType first, IteratorType last,
24386                        const bool ignore_comments = false)
24387     {
24388         return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
24389     }
24390 
24391     JSON_HEDLEY_WARN_UNUSED_RESULT
24392     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
accept(detail::span_input_adapter && i,const bool ignore_comments=false)24393     static bool accept(detail::span_input_adapter&& i,
24394                        const bool ignore_comments = false)
24395     {
24396         return parser(i.get(), nullptr, false, ignore_comments).accept(true);
24397     }
24398 
24399     /*!
24400     @brief generate SAX events
24401 
24402     The SAX event lister must follow the interface of @ref json_sax.
24403 
24404     This function reads from a compatible input. Examples are:
24405     - an std::istream object
24406     - a FILE pointer
24407     - a C-style array of characters
24408     - a pointer to a null-terminated string of single byte characters
24409     - an object obj for which begin(obj) and end(obj) produces a valid pair of
24410       iterators.
24411 
24412     @param[in] i  input to read from
24413     @param[in,out] sax  SAX event listener
24414     @param[in] format  the format to parse (JSON, CBOR, MessagePack, or UBJSON)
24415     @param[in] strict  whether the input has to be consumed completely
24416     @param[in] ignore_comments  whether comments should be ignored and treated
24417     like whitespace (true) or yield a parse error (true); (optional, false by
24418     default); only applies to the JSON file format.
24419 
24420     @return return value of the last processed SAX event
24421 
24422     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24423     of input; expected string literal""`
24424     @throw parse_error.102 if to_unicode fails or surrogate error
24425     @throw parse_error.103 if to_unicode fails
24426 
24427     @complexity Linear in the length of the input. The parser is a predictive
24428     LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
24429     a super-linear complexity.
24430 
24431     @note A UTF-8 byte order mark is silently ignored.
24432 
24433     @liveexample{The example below demonstrates the `sax_parse()` function
24434     reading from string and processing the events with a user-defined SAX
24435     event consumer.,sax_parse}
24436 
24437     @since version 3.2.0
24438     */
24439     template <typename InputType, typename SAX>
24440     JSON_HEDLEY_NON_NULL(2)
sax_parse(InputType && i,SAX * sax,input_format_t format=input_format_t::json,const bool strict=true,const bool ignore_comments=false)24441     static bool sax_parse(InputType&& i, SAX* sax,
24442                           input_format_t format = input_format_t::json,
24443                           const bool strict = true,
24444                           const bool ignore_comments = false)
24445     {
24446         auto ia = detail::input_adapter(std::forward<InputType>(i));
24447         return format == input_format_t::json
24448                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24449                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24450     }
24451 
24452     template<class IteratorType, class SAX>
24453     JSON_HEDLEY_NON_NULL(3)
sax_parse(IteratorType first,IteratorType last,SAX * sax,input_format_t format=input_format_t::json,const bool strict=true,const bool ignore_comments=false)24454     static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
24455                           input_format_t format = input_format_t::json,
24456                           const bool strict = true,
24457                           const bool ignore_comments = false)
24458     {
24459         auto ia = detail::input_adapter(std::move(first), std::move(last));
24460         return format == input_format_t::json
24461                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24462                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24463     }
24464 
24465     template <typename SAX>
24466     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
24467     JSON_HEDLEY_NON_NULL(2)
sax_parse(detail::span_input_adapter && i,SAX * sax,input_format_t format=input_format_t::json,const bool strict=true,const bool ignore_comments=false)24468     static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
24469                           input_format_t format = input_format_t::json,
24470                           const bool strict = true,
24471                           const bool ignore_comments = false)
24472     {
24473         auto ia = i.get();
24474         return format == input_format_t::json
24475                // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24476                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24477                // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24478                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24479     }
24480 #ifndef JSON_NO_IO
24481     /*!
24482     @brief deserialize from stream
24483     @deprecated This stream operator is deprecated and will be removed in
24484                 version 4.0.0 of the library. Please use
24485                 @ref operator>>(std::istream&, basic_json&)
24486                 instead; that is, replace calls like `j << i;` with `i >> j;`.
24487     @since version 1.0.0; deprecated since version 3.0.0
24488     */
24489     JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
operator <<(basic_json & j,std::istream & i)24490     friend std::istream& operator<<(basic_json& j, std::istream& i)
24491     {
24492         return operator>>(i, j);
24493     }
24494 
24495     /*!
24496     @brief deserialize from stream
24497 
24498     Deserializes an input stream to a JSON value.
24499 
24500     @param[in,out] i  input stream to read a serialized JSON value from
24501     @param[in,out] j  JSON value to write the deserialized input to
24502 
24503     @throw parse_error.101 in case of an unexpected token
24504     @throw parse_error.102 if to_unicode fails or surrogate error
24505     @throw parse_error.103 if to_unicode fails
24506 
24507     @complexity Linear in the length of the input. The parser is a predictive
24508     LL(1) parser.
24509 
24510     @note A UTF-8 byte order mark is silently ignored.
24511 
24512     @liveexample{The example below shows how a JSON value is constructed by
24513     reading a serialization from a stream.,operator_deserialize}
24514 
24515     @sa parse(std::istream&, const parser_callback_t) for a variant with a
24516     parser callback function to filter values while parsing
24517 
24518     @since version 1.0.0
24519     */
operator >>(std::istream & i,basic_json & j)24520     friend std::istream& operator>>(std::istream& i, basic_json& j)
24521     {
24522         parser(detail::input_adapter(i)).parse(false, j);
24523         return i;
24524     }
24525 #endif  // JSON_NO_IO
24526     /// @}
24527 
24528     ///////////////////////////
24529     // convenience functions //
24530     ///////////////////////////
24531 
24532     /*!
24533     @brief return the type as string
24534 
24535     Returns the type name as string to be used in error messages - usually to
24536     indicate that a function was called on a wrong JSON type.
24537 
24538     @return a string representation of a the @a m_type member:
24539             Value type  | return value
24540             ----------- | -------------
24541             null        | `"null"`
24542             boolean     | `"boolean"`
24543             string      | `"string"`
24544             number      | `"number"` (for all number types)
24545             object      | `"object"`
24546             array       | `"array"`
24547             binary      | `"binary"`
24548             discarded   | `"discarded"`
24549 
24550     @exceptionsafety No-throw guarantee: this function never throws exceptions.
24551 
24552     @complexity Constant.
24553 
24554     @liveexample{The following code exemplifies `type_name()` for all JSON
24555     types.,type_name}
24556 
24557     @sa see @ref type() -- return the type of the JSON value
24558     @sa see @ref operator value_t() -- return the type of the JSON value (implicit)
24559 
24560     @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
24561     since 3.0.0
24562     */
24563     JSON_HEDLEY_RETURNS_NON_NULL
type_name() const24564     const char* type_name() const noexcept
24565     {
24566         {
24567             switch (m_type)
24568             {
24569                 case value_t::null:
24570                     return "null";
24571                 case value_t::object:
24572                     return "object";
24573                 case value_t::array:
24574                     return "array";
24575                 case value_t::string:
24576                     return "string";
24577                 case value_t::boolean:
24578                     return "boolean";
24579                 case value_t::binary:
24580                     return "binary";
24581                 case value_t::discarded:
24582                     return "discarded";
24583                 case value_t::number_integer:
24584                 case value_t::number_unsigned:
24585                 case value_t::number_float:
24586                 default:
24587                     return "number";
24588             }
24589         }
24590     }
24591 
24592 
24593   JSON_PRIVATE_UNLESS_TESTED:
24594     //////////////////////
24595     // member variables //
24596     //////////////////////
24597 
24598     /// the type of the current element
24599     value_t m_type = value_t::null;
24600 
24601     /// the value of the current element
24602     json_value m_value = {};
24603 
24604 #if JSON_DIAGNOSTICS
24605     /// a pointer to a parent value (for debugging purposes)
24606     basic_json* m_parent = nullptr;
24607 #endif
24608 
24609     //////////////////////////////////////////
24610     // binary serialization/deserialization //
24611     //////////////////////////////////////////
24612 
24613     /// @name binary serialization/deserialization support
24614     /// @{
24615 
24616   public:
24617     /*!
24618     @brief create a CBOR serialization of a given JSON value
24619 
24620     Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
24621     Binary Object Representation) serialization format. CBOR is a binary
24622     serialization format which aims to be more compact than JSON itself, yet
24623     more efficient to parse.
24624 
24625     The library uses the following mapping from JSON values types to
24626     CBOR types according to the CBOR specification (RFC 7049):
24627 
24628     JSON value type | value/range                                | CBOR type                          | first byte
24629     --------------- | ------------------------------------------ | ---------------------------------- | ---------------
24630     null            | `null`                                     | Null                               | 0xF6
24631     boolean         | `true`                                     | True                               | 0xF5
24632     boolean         | `false`                                    | False                              | 0xF4
24633     number_integer  | -9223372036854775808..-2147483649          | Negative integer (8 bytes follow)  | 0x3B
24634     number_integer  | -2147483648..-32769                        | Negative integer (4 bytes follow)  | 0x3A
24635     number_integer  | -32768..-129                               | Negative integer (2 bytes follow)  | 0x39
24636     number_integer  | -128..-25                                  | Negative integer (1 byte follow)   | 0x38
24637     number_integer  | -24..-1                                    | Negative integer                   | 0x20..0x37
24638     number_integer  | 0..23                                      | Integer                            | 0x00..0x17
24639     number_integer  | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
24640     number_integer  | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
24641     number_integer  | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
24642     number_integer  | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
24643     number_unsigned | 0..23                                      | Integer                            | 0x00..0x17
24644     number_unsigned | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
24645     number_unsigned | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
24646     number_unsigned | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
24647     number_unsigned | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
24648     number_float    | *any value representable by a float*       | Single-Precision Float             | 0xFA
24649     number_float    | *any value NOT representable by a float*   | Double-Precision Float             | 0xFB
24650     string          | *length*: 0..23                            | UTF-8 string                       | 0x60..0x77
24651     string          | *length*: 23..255                          | UTF-8 string (1 byte follow)       | 0x78
24652     string          | *length*: 256..65535                       | UTF-8 string (2 bytes follow)      | 0x79
24653     string          | *length*: 65536..4294967295                | UTF-8 string (4 bytes follow)      | 0x7A
24654     string          | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow)      | 0x7B
24655     array           | *size*: 0..23                              | array                              | 0x80..0x97
24656     array           | *size*: 23..255                            | array (1 byte follow)              | 0x98
24657     array           | *size*: 256..65535                         | array (2 bytes follow)             | 0x99
24658     array           | *size*: 65536..4294967295                  | array (4 bytes follow)             | 0x9A
24659     array           | *size*: 4294967296..18446744073709551615   | array (8 bytes follow)             | 0x9B
24660     object          | *size*: 0..23                              | map                                | 0xA0..0xB7
24661     object          | *size*: 23..255                            | map (1 byte follow)                | 0xB8
24662     object          | *size*: 256..65535                         | map (2 bytes follow)               | 0xB9
24663     object          | *size*: 65536..4294967295                  | map (4 bytes follow)               | 0xBA
24664     object          | *size*: 4294967296..18446744073709551615   | map (8 bytes follow)               | 0xBB
24665     binary          | *size*: 0..23                              | byte string                        | 0x40..0x57
24666     binary          | *size*: 23..255                            | byte string (1 byte follow)        | 0x58
24667     binary          | *size*: 256..65535                         | byte string (2 bytes follow)       | 0x59
24668     binary          | *size*: 65536..4294967295                  | byte string (4 bytes follow)       | 0x5A
24669     binary          | *size*: 4294967296..18446744073709551615   | byte string (8 bytes follow)       | 0x5B
24670 
24671     Binary values with subtype are mapped to tagged values (0xD8..0xDB)
24672     depending on the subtype, followed by a byte string, see "binary" cells
24673     in the table above.
24674 
24675     @note The mapping is **complete** in the sense that any JSON value type
24676           can be converted to a CBOR value.
24677 
24678     @note If NaN or Infinity are stored inside a JSON number, they are
24679           serialized properly. This behavior differs from the @ref dump()
24680           function which serializes NaN or Infinity to `null`.
24681 
24682     @note The following CBOR types are not used in the conversion:
24683           - UTF-8 strings terminated by "break" (0x7F)
24684           - arrays terminated by "break" (0x9F)
24685           - maps terminated by "break" (0xBF)
24686           - byte strings terminated by "break" (0x5F)
24687           - date/time (0xC0..0xC1)
24688           - bignum (0xC2..0xC3)
24689           - decimal fraction (0xC4)
24690           - bigfloat (0xC5)
24691           - expected conversions (0xD5..0xD7)
24692           - simple values (0xE0..0xF3, 0xF8)
24693           - undefined (0xF7)
24694           - half-precision floats (0xF9)
24695           - break (0xFF)
24696 
24697     @param[in] j  JSON value to serialize
24698     @return CBOR serialization as byte vector
24699 
24700     @complexity Linear in the size of the JSON value @a j.
24701 
24702     @liveexample{The example shows the serialization of a JSON value to a byte
24703     vector in CBOR format.,to_cbor}
24704 
24705     @sa http://cbor.io
24706     @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
24707         analogous deserialization
24708     @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
24709     @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
24710              related UBJSON format
24711 
24712     @since version 2.0.9; compact representation of floating-point numbers
24713            since version 3.8.0
24714     */
to_cbor(const basic_json & j)24715     static std::vector<std::uint8_t> to_cbor(const basic_json& j)
24716     {
24717         std::vector<std::uint8_t> result;
24718         to_cbor(j, result);
24719         return result;
24720     }
24721 
to_cbor(const basic_json & j,detail::output_adapter<std::uint8_t> o)24722     static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24723     {
24724         binary_writer<std::uint8_t>(o).write_cbor(j);
24725     }
24726 
to_cbor(const basic_json & j,detail::output_adapter<char> o)24727     static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
24728     {
24729         binary_writer<char>(o).write_cbor(j);
24730     }
24731 
24732     /*!
24733     @brief create a MessagePack serialization of a given JSON value
24734 
24735     Serializes a given JSON value @a j to a byte vector using the MessagePack
24736     serialization format. MessagePack is a binary serialization format which
24737     aims to be more compact than JSON itself, yet more efficient to parse.
24738 
24739     The library uses the following mapping from JSON values types to
24740     MessagePack types according to the MessagePack specification:
24741 
24742     JSON value type | value/range                       | MessagePack type | first byte
24743     --------------- | --------------------------------- | ---------------- | ----------
24744     null            | `null`                            | nil              | 0xC0
24745     boolean         | `true`                            | true             | 0xC3
24746     boolean         | `false`                           | false            | 0xC2
24747     number_integer  | -9223372036854775808..-2147483649 | int64            | 0xD3
24748     number_integer  | -2147483648..-32769               | int32            | 0xD2
24749     number_integer  | -32768..-129                      | int16            | 0xD1
24750     number_integer  | -128..-33                         | int8             | 0xD0
24751     number_integer  | -32..-1                           | negative fixint  | 0xE0..0xFF
24752     number_integer  | 0..127                            | positive fixint  | 0x00..0x7F
24753     number_integer  | 128..255                          | uint 8           | 0xCC
24754     number_integer  | 256..65535                        | uint 16          | 0xCD
24755     number_integer  | 65536..4294967295                 | uint 32          | 0xCE
24756     number_integer  | 4294967296..18446744073709551615  | uint 64          | 0xCF
24757     number_unsigned | 0..127                            | positive fixint  | 0x00..0x7F
24758     number_unsigned | 128..255                          | uint 8           | 0xCC
24759     number_unsigned | 256..65535                        | uint 16          | 0xCD
24760     number_unsigned | 65536..4294967295                 | uint 32          | 0xCE
24761     number_unsigned | 4294967296..18446744073709551615  | uint 64          | 0xCF
24762     number_float    | *any value representable by a float*     | float 32 | 0xCA
24763     number_float    | *any value NOT representable by a float* | float 64 | 0xCB
24764     string          | *length*: 0..31                   | fixstr           | 0xA0..0xBF
24765     string          | *length*: 32..255                 | str 8            | 0xD9
24766     string          | *length*: 256..65535              | str 16           | 0xDA
24767     string          | *length*: 65536..4294967295       | str 32           | 0xDB
24768     array           | *size*: 0..15                     | fixarray         | 0x90..0x9F
24769     array           | *size*: 16..65535                 | array 16         | 0xDC
24770     array           | *size*: 65536..4294967295         | array 32         | 0xDD
24771     object          | *size*: 0..15                     | fix map          | 0x80..0x8F
24772     object          | *size*: 16..65535                 | map 16           | 0xDE
24773     object          | *size*: 65536..4294967295         | map 32           | 0xDF
24774     binary          | *size*: 0..255                    | bin 8            | 0xC4
24775     binary          | *size*: 256..65535                | bin 16           | 0xC5
24776     binary          | *size*: 65536..4294967295         | bin 32           | 0xC6
24777 
24778     @note The mapping is **complete** in the sense that any JSON value type
24779           can be converted to a MessagePack value.
24780 
24781     @note The following values can **not** be converted to a MessagePack value:
24782           - strings with more than 4294967295 bytes
24783           - byte strings with more than 4294967295 bytes
24784           - arrays with more than 4294967295 elements
24785           - objects with more than 4294967295 elements
24786 
24787     @note Any MessagePack output created @ref to_msgpack can be successfully
24788           parsed by @ref from_msgpack.
24789 
24790     @note If NaN or Infinity are stored inside a JSON number, they are
24791           serialized properly. This behavior differs from the @ref dump()
24792           function which serializes NaN or Infinity to `null`.
24793 
24794     @param[in] j  JSON value to serialize
24795     @return MessagePack serialization as byte vector
24796 
24797     @complexity Linear in the size of the JSON value @a j.
24798 
24799     @liveexample{The example shows the serialization of a JSON value to a byte
24800     vector in MessagePack format.,to_msgpack}
24801 
24802     @sa http://msgpack.org
24803     @sa see @ref from_msgpack for the analogous deserialization
24804     @sa see @ref to_cbor(const basic_json& for the related CBOR format
24805     @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
24806              related UBJSON format
24807 
24808     @since version 2.0.9
24809     */
to_msgpack(const basic_json & j)24810     static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
24811     {
24812         std::vector<std::uint8_t> result;
24813         to_msgpack(j, result);
24814         return result;
24815     }
24816 
to_msgpack(const basic_json & j,detail::output_adapter<std::uint8_t> o)24817     static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24818     {
24819         binary_writer<std::uint8_t>(o).write_msgpack(j);
24820     }
24821 
to_msgpack(const basic_json & j,detail::output_adapter<char> o)24822     static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
24823     {
24824         binary_writer<char>(o).write_msgpack(j);
24825     }
24826 
24827     /*!
24828     @brief create a UBJSON serialization of a given JSON value
24829 
24830     Serializes a given JSON value @a j to a byte vector using the UBJSON
24831     (Universal Binary JSON) serialization format. UBJSON aims to be more compact
24832     than JSON itself, yet more efficient to parse.
24833 
24834     The library uses the following mapping from JSON values types to
24835     UBJSON types according to the UBJSON specification:
24836 
24837     JSON value type | value/range                       | UBJSON type | marker
24838     --------------- | --------------------------------- | ----------- | ------
24839     null            | `null`                            | null        | `Z`
24840     boolean         | `true`                            | true        | `T`
24841     boolean         | `false`                           | false       | `F`
24842     number_integer  | -9223372036854775808..-2147483649 | int64       | `L`
24843     number_integer  | -2147483648..-32769               | int32       | `l`
24844     number_integer  | -32768..-129                      | int16       | `I`
24845     number_integer  | -128..127                         | int8        | `i`
24846     number_integer  | 128..255                          | uint8       | `U`
24847     number_integer  | 256..32767                        | int16       | `I`
24848     number_integer  | 32768..2147483647                 | int32       | `l`
24849     number_integer  | 2147483648..9223372036854775807   | int64       | `L`
24850     number_unsigned | 0..127                            | int8        | `i`
24851     number_unsigned | 128..255                          | uint8       | `U`
24852     number_unsigned | 256..32767                        | int16       | `I`
24853     number_unsigned | 32768..2147483647                 | int32       | `l`
24854     number_unsigned | 2147483648..9223372036854775807   | int64       | `L`
24855     number_unsigned | 2147483649..18446744073709551615  | high-precision | `H`
24856     number_float    | *any value*                       | float64     | `D`
24857     string          | *with shortest length indicator*  | string      | `S`
24858     array           | *see notes on optimized format*   | array       | `[`
24859     object          | *see notes on optimized format*   | map         | `{`
24860 
24861     @note The mapping is **complete** in the sense that any JSON value type
24862           can be converted to a UBJSON value.
24863 
24864     @note The following values can **not** be converted to a UBJSON value:
24865           - strings with more than 9223372036854775807 bytes (theoretical)
24866 
24867     @note The following markers are not used in the conversion:
24868           - `Z`: no-op values are not created.
24869           - `C`: single-byte strings are serialized with `S` markers.
24870 
24871     @note Any UBJSON output created @ref to_ubjson can be successfully parsed
24872           by @ref from_ubjson.
24873 
24874     @note If NaN or Infinity are stored inside a JSON number, they are
24875           serialized properly. This behavior differs from the @ref dump()
24876           function which serializes NaN or Infinity to `null`.
24877 
24878     @note The optimized formats for containers are supported: Parameter
24879           @a use_size adds size information to the beginning of a container and
24880           removes the closing marker. Parameter @a use_type further checks
24881           whether all elements of a container have the same type and adds the
24882           type marker to the beginning of the container. The @a use_type
24883           parameter must only be used together with @a use_size = true. Note
24884           that @a use_size = true alone may result in larger representations -
24885           the benefit of this parameter is that the receiving side is
24886           immediately informed on the number of elements of the container.
24887 
24888     @note If the JSON data contains the binary type, the value stored is a list
24889           of integers, as suggested by the UBJSON documentation.  In particular,
24890           this means that serialization and the deserialization of a JSON
24891           containing binary values into UBJSON and back will result in a
24892           different JSON object.
24893 
24894     @param[in] j  JSON value to serialize
24895     @param[in] use_size  whether to add size annotations to container types
24896     @param[in] use_type  whether to add type annotations to container types
24897                          (must be combined with @a use_size = true)
24898     @return UBJSON serialization as byte vector
24899 
24900     @complexity Linear in the size of the JSON value @a j.
24901 
24902     @liveexample{The example shows the serialization of a JSON value to a byte
24903     vector in UBJSON format.,to_ubjson}
24904 
24905     @sa http://ubjson.org
24906     @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
24907         analogous deserialization
24908     @sa see @ref to_cbor(const basic_json& for the related CBOR format
24909     @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
24910 
24911     @since version 3.1.0
24912     */
to_ubjson(const basic_json & j,const bool use_size=false,const bool use_type=false)24913     static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
24914             const bool use_size = false,
24915             const bool use_type = false)
24916     {
24917         std::vector<std::uint8_t> result;
24918         to_ubjson(j, result, use_size, use_type);
24919         return result;
24920     }
24921 
to_ubjson(const basic_json & j,detail::output_adapter<std::uint8_t> o,const bool use_size=false,const bool use_type=false)24922     static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,
24923                           const bool use_size = false, const bool use_type = false)
24924     {
24925         binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
24926     }
24927 
to_ubjson(const basic_json & j,detail::output_adapter<char> o,const bool use_size=false,const bool use_type=false)24928     static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
24929                           const bool use_size = false, const bool use_type = false)
24930     {
24931         binary_writer<char>(o).write_ubjson(j, use_size, use_type);
24932     }
24933 
24934 
24935     /*!
24936     @brief Serializes the given JSON object `j` to BSON and returns a vector
24937            containing the corresponding BSON-representation.
24938 
24939     BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
24940     stored as a single entity (a so-called document).
24941 
24942     The library uses the following mapping from JSON values types to BSON types:
24943 
24944     JSON value type | value/range                       | BSON type   | marker
24945     --------------- | --------------------------------- | ----------- | ------
24946     null            | `null`                            | null        | 0x0A
24947     boolean         | `true`, `false`                   | boolean     | 0x08
24948     number_integer  | -9223372036854775808..-2147483649 | int64       | 0x12
24949     number_integer  | -2147483648..2147483647           | int32       | 0x10
24950     number_integer  | 2147483648..9223372036854775807   | int64       | 0x12
24951     number_unsigned | 0..2147483647                     | int32       | 0x10
24952     number_unsigned | 2147483648..9223372036854775807   | int64       | 0x12
24953     number_unsigned | 9223372036854775808..18446744073709551615| --   | --
24954     number_float    | *any value*                       | double      | 0x01
24955     string          | *any value*                       | string      | 0x02
24956     array           | *any value*                       | document    | 0x04
24957     object          | *any value*                       | document    | 0x03
24958     binary          | *any value*                       | binary      | 0x05
24959 
24960     @warning The mapping is **incomplete**, since only JSON-objects (and things
24961     contained therein) can be serialized to BSON.
24962     Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
24963     and the keys may not contain U+0000, since they are serialized a
24964     zero-terminated c-strings.
24965 
24966     @throw out_of_range.407  if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
24967     @throw out_of_range.409  if a key in `j` contains a NULL (U+0000)
24968     @throw type_error.317    if `!j.is_object()`
24969 
24970     @pre The input `j` is required to be an object: `j.is_object() == true`.
24971 
24972     @note Any BSON output created via @ref to_bson can be successfully parsed
24973           by @ref from_bson.
24974 
24975     @param[in] j  JSON value to serialize
24976     @return BSON serialization as byte vector
24977 
24978     @complexity Linear in the size of the JSON value @a j.
24979 
24980     @liveexample{The example shows the serialization of a JSON value to a byte
24981     vector in BSON format.,to_bson}
24982 
24983     @sa http://bsonspec.org/spec.html
24984     @sa see @ref from_bson(detail::input_adapter&&, const bool strict) for the
24985         analogous deserialization
24986     @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
24987              related UBJSON format
24988     @sa see @ref to_cbor(const basic_json&) for the related CBOR format
24989     @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
24990     */
to_bson(const basic_json & j)24991     static std::vector<std::uint8_t> to_bson(const basic_json& j)
24992     {
24993         std::vector<std::uint8_t> result;
24994         to_bson(j, result);
24995         return result;
24996     }
24997 
24998     /*!
24999     @brief Serializes the given JSON object `j` to BSON and forwards the
25000            corresponding BSON-representation to the given output_adapter `o`.
25001     @param j The JSON object to convert to BSON.
25002     @param o The output adapter that receives the binary BSON representation.
25003     @pre The input `j` shall be an object: `j.is_object() == true`
25004     @sa see @ref to_bson(const basic_json&)
25005     */
to_bson(const basic_json & j,detail::output_adapter<std::uint8_t> o)25006     static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)
25007     {
25008         binary_writer<std::uint8_t>(o).write_bson(j);
25009     }
25010 
25011     /*!
25012     @copydoc to_bson(const basic_json&, detail::output_adapter<std::uint8_t>)
25013     */
to_bson(const basic_json & j,detail::output_adapter<char> o)25014     static void to_bson(const basic_json& j, detail::output_adapter<char> o)
25015     {
25016         binary_writer<char>(o).write_bson(j);
25017     }
25018 
25019 
25020     /*!
25021     @brief create a JSON value from an input in CBOR format
25022 
25023     Deserializes a given input @a i to a JSON value using the CBOR (Concise
25024     Binary Object Representation) serialization format.
25025 
25026     The library maps CBOR types to JSON value types as follows:
25027 
25028     CBOR type              | JSON value type | first byte
25029     ---------------------- | --------------- | ----------
25030     Integer                | number_unsigned | 0x00..0x17
25031     Unsigned integer       | number_unsigned | 0x18
25032     Unsigned integer       | number_unsigned | 0x19
25033     Unsigned integer       | number_unsigned | 0x1A
25034     Unsigned integer       | number_unsigned | 0x1B
25035     Negative integer       | number_integer  | 0x20..0x37
25036     Negative integer       | number_integer  | 0x38
25037     Negative integer       | number_integer  | 0x39
25038     Negative integer       | number_integer  | 0x3A
25039     Negative integer       | number_integer  | 0x3B
25040     Byte string            | binary          | 0x40..0x57
25041     Byte string            | binary          | 0x58
25042     Byte string            | binary          | 0x59
25043     Byte string            | binary          | 0x5A
25044     Byte string            | binary          | 0x5B
25045     UTF-8 string           | string          | 0x60..0x77
25046     UTF-8 string           | string          | 0x78
25047     UTF-8 string           | string          | 0x79
25048     UTF-8 string           | string          | 0x7A
25049     UTF-8 string           | string          | 0x7B
25050     UTF-8 string           | string          | 0x7F
25051     array                  | array           | 0x80..0x97
25052     array                  | array           | 0x98
25053     array                  | array           | 0x99
25054     array                  | array           | 0x9A
25055     array                  | array           | 0x9B
25056     array                  | array           | 0x9F
25057     map                    | object          | 0xA0..0xB7
25058     map                    | object          | 0xB8
25059     map                    | object          | 0xB9
25060     map                    | object          | 0xBA
25061     map                    | object          | 0xBB
25062     map                    | object          | 0xBF
25063     False                  | `false`         | 0xF4
25064     True                   | `true`          | 0xF5
25065     Null                   | `null`          | 0xF6
25066     Half-Precision Float   | number_float    | 0xF9
25067     Single-Precision Float | number_float    | 0xFA
25068     Double-Precision Float | number_float    | 0xFB
25069 
25070     @warning The mapping is **incomplete** in the sense that not all CBOR
25071              types can be converted to a JSON value. The following CBOR types
25072              are not supported and will yield parse errors (parse_error.112):
25073              - date/time (0xC0..0xC1)
25074              - bignum (0xC2..0xC3)
25075              - decimal fraction (0xC4)
25076              - bigfloat (0xC5)
25077              - expected conversions (0xD5..0xD7)
25078              - simple values (0xE0..0xF3, 0xF8)
25079              - undefined (0xF7)
25080 
25081     @warning CBOR allows map keys of any type, whereas JSON only allows
25082              strings as keys in object values. Therefore, CBOR maps with keys
25083              other than UTF-8 strings are rejected (parse_error.113).
25084 
25085     @note Any CBOR output created @ref to_cbor can be successfully parsed by
25086           @ref from_cbor.
25087 
25088     @param[in] i  an input in CBOR format convertible to an input adapter
25089     @param[in] strict  whether to expect the input to be consumed until EOF
25090                        (true by default)
25091     @param[in] allow_exceptions  whether to throw exceptions in case of a
25092     parse error (optional, true by default)
25093     @param[in] tag_handler how to treat CBOR tags (optional, error by default)
25094 
25095     @return deserialized JSON value; in case of a parse error and
25096             @a allow_exceptions set to `false`, the return value will be
25097             value_t::discarded.
25098 
25099     @throw parse_error.110 if the given input ends prematurely or the end of
25100     file was not reached when @a strict was set to true
25101     @throw parse_error.112 if unsupported features from CBOR were
25102     used in the given input @a v or if the input is not valid CBOR
25103     @throw parse_error.113 if a string was expected as map key, but not found
25104 
25105     @complexity Linear in the size of the input @a i.
25106 
25107     @liveexample{The example shows the deserialization of a byte vector in CBOR
25108     format to a JSON value.,from_cbor}
25109 
25110     @sa http://cbor.io
25111     @sa see @ref to_cbor(const basic_json&) for the analogous serialization
25112     @sa see @ref from_msgpack(InputType&&, const bool, const bool) for the
25113         related MessagePack format
25114     @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
25115         related UBJSON format
25116 
25117     @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
25118            consume input adapters, removed start_index parameter, and added
25119            @a strict parameter since 3.0.0; added @a allow_exceptions parameter
25120            since 3.2.0; added @a tag_handler parameter since 3.9.0.
25121     */
25122     template<typename InputType>
25123     JSON_HEDLEY_WARN_UNUSED_RESULT
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)25124     static basic_json from_cbor(InputType&& i,
25125                                 const bool strict = true,
25126                                 const bool allow_exceptions = true,
25127                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25128     {
25129         basic_json result;
25130         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25131         auto ia = detail::input_adapter(std::forward<InputType>(i));
25132         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25133         return res ? result : basic_json(value_t::discarded);
25134     }
25135 
25136     /*!
25137     @copydoc from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t)
25138     */
25139     template<typename IteratorType>
25140     JSON_HEDLEY_WARN_UNUSED_RESULT
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)25141     static basic_json from_cbor(IteratorType first, IteratorType last,
25142                                 const bool strict = true,
25143                                 const bool allow_exceptions = true,
25144                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25145     {
25146         basic_json result;
25147         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25148         auto ia = detail::input_adapter(std::move(first), std::move(last));
25149         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25150         return res ? result : basic_json(value_t::discarded);
25151     }
25152 
25153     template<typename T>
25154     JSON_HEDLEY_WARN_UNUSED_RESULT
25155     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
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)25156     static basic_json from_cbor(const T* ptr, std::size_t len,
25157                                 const bool strict = true,
25158                                 const bool allow_exceptions = true,
25159                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25160     {
25161         return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
25162     }
25163 
25164 
25165     JSON_HEDLEY_WARN_UNUSED_RESULT
25166     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
from_cbor(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true,const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)25167     static basic_json from_cbor(detail::span_input_adapter&& i,
25168                                 const bool strict = true,
25169                                 const bool allow_exceptions = true,
25170                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25171     {
25172         basic_json result;
25173         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25174         auto ia = i.get();
25175         // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25176         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25177         return res ? result : basic_json(value_t::discarded);
25178     }
25179 
25180     /*!
25181     @brief create a JSON value from an input in MessagePack format
25182 
25183     Deserializes a given input @a i to a JSON value using the MessagePack
25184     serialization format.
25185 
25186     The library maps MessagePack types to JSON value types as follows:
25187 
25188     MessagePack type | JSON value type | first byte
25189     ---------------- | --------------- | ----------
25190     positive fixint  | number_unsigned | 0x00..0x7F
25191     fixmap           | object          | 0x80..0x8F
25192     fixarray         | array           | 0x90..0x9F
25193     fixstr           | string          | 0xA0..0xBF
25194     nil              | `null`          | 0xC0
25195     false            | `false`         | 0xC2
25196     true             | `true`          | 0xC3
25197     float 32         | number_float    | 0xCA
25198     float 64         | number_float    | 0xCB
25199     uint 8           | number_unsigned | 0xCC
25200     uint 16          | number_unsigned | 0xCD
25201     uint 32          | number_unsigned | 0xCE
25202     uint 64          | number_unsigned | 0xCF
25203     int 8            | number_integer  | 0xD0
25204     int 16           | number_integer  | 0xD1
25205     int 32           | number_integer  | 0xD2
25206     int 64           | number_integer  | 0xD3
25207     str 8            | string          | 0xD9
25208     str 16           | string          | 0xDA
25209     str 32           | string          | 0xDB
25210     array 16         | array           | 0xDC
25211     array 32         | array           | 0xDD
25212     map 16           | object          | 0xDE
25213     map 32           | object          | 0xDF
25214     bin 8            | binary          | 0xC4
25215     bin 16           | binary          | 0xC5
25216     bin 32           | binary          | 0xC6
25217     ext 8            | binary          | 0xC7
25218     ext 16           | binary          | 0xC8
25219     ext 32           | binary          | 0xC9
25220     fixext 1         | binary          | 0xD4
25221     fixext 2         | binary          | 0xD5
25222     fixext 4         | binary          | 0xD6
25223     fixext 8         | binary          | 0xD7
25224     fixext 16        | binary          | 0xD8
25225     negative fixint  | number_integer  | 0xE0-0xFF
25226 
25227     @note Any MessagePack output created @ref to_msgpack can be successfully
25228           parsed by @ref from_msgpack.
25229 
25230     @param[in] i  an input in MessagePack format convertible to an input
25231                   adapter
25232     @param[in] strict  whether to expect the input to be consumed until EOF
25233                        (true by default)
25234     @param[in] allow_exceptions  whether to throw exceptions in case of a
25235     parse error (optional, true by default)
25236 
25237     @return deserialized JSON value; in case of a parse error and
25238             @a allow_exceptions set to `false`, the return value will be
25239             value_t::discarded.
25240 
25241     @throw parse_error.110 if the given input ends prematurely or the end of
25242     file was not reached when @a strict was set to true
25243     @throw parse_error.112 if unsupported features from MessagePack were
25244     used in the given input @a i or if the input is not valid MessagePack
25245     @throw parse_error.113 if a string was expected as map key, but not found
25246 
25247     @complexity Linear in the size of the input @a i.
25248 
25249     @liveexample{The example shows the deserialization of a byte vector in
25250     MessagePack format to a JSON value.,from_msgpack}
25251 
25252     @sa http://msgpack.org
25253     @sa see @ref to_msgpack(const basic_json&) for the analogous serialization
25254     @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25255         related CBOR format
25256     @sa see @ref from_ubjson(InputType&&, const bool, const bool) for
25257         the related UBJSON format
25258     @sa see @ref from_bson(InputType&&, const bool, const bool) for
25259         the related BSON format
25260 
25261     @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
25262            consume input adapters, removed start_index parameter, and added
25263            @a strict parameter since 3.0.0; added @a allow_exceptions parameter
25264            since 3.2.0
25265     */
25266     template<typename InputType>
25267     JSON_HEDLEY_WARN_UNUSED_RESULT
from_msgpack(InputType && i,const bool strict=true,const bool allow_exceptions=true)25268     static basic_json from_msgpack(InputType&& i,
25269                                    const bool strict = true,
25270                                    const bool allow_exceptions = true)
25271     {
25272         basic_json result;
25273         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25274         auto ia = detail::input_adapter(std::forward<InputType>(i));
25275         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25276         return res ? result : basic_json(value_t::discarded);
25277     }
25278 
25279     /*!
25280     @copydoc from_msgpack(InputType&&, const bool, const bool)
25281     */
25282     template<typename IteratorType>
25283     JSON_HEDLEY_WARN_UNUSED_RESULT
from_msgpack(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)25284     static basic_json from_msgpack(IteratorType first, IteratorType last,
25285                                    const bool strict = true,
25286                                    const bool allow_exceptions = true)
25287     {
25288         basic_json result;
25289         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25290         auto ia = detail::input_adapter(std::move(first), std::move(last));
25291         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25292         return res ? result : basic_json(value_t::discarded);
25293     }
25294 
25295 
25296     template<typename T>
25297     JSON_HEDLEY_WARN_UNUSED_RESULT
25298     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
from_msgpack(const T * ptr,std::size_t len,const bool strict=true,const bool allow_exceptions=true)25299     static basic_json from_msgpack(const T* ptr, std::size_t len,
25300                                    const bool strict = true,
25301                                    const bool allow_exceptions = true)
25302     {
25303         return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
25304     }
25305 
25306     JSON_HEDLEY_WARN_UNUSED_RESULT
25307     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
from_msgpack(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true)25308     static basic_json from_msgpack(detail::span_input_adapter&& i,
25309                                    const bool strict = true,
25310                                    const bool allow_exceptions = true)
25311     {
25312         basic_json result;
25313         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25314         auto ia = i.get();
25315         // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25316         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25317         return res ? result : basic_json(value_t::discarded);
25318     }
25319 
25320 
25321     /*!
25322     @brief create a JSON value from an input in UBJSON format
25323 
25324     Deserializes a given input @a i to a JSON value using the UBJSON (Universal
25325     Binary JSON) serialization format.
25326 
25327     The library maps UBJSON types to JSON value types as follows:
25328 
25329     UBJSON type | JSON value type                         | marker
25330     ----------- | --------------------------------------- | ------
25331     no-op       | *no value, next value is read*          | `N`
25332     null        | `null`                                  | `Z`
25333     false       | `false`                                 | `F`
25334     true        | `true`                                  | `T`
25335     float32     | number_float                            | `d`
25336     float64     | number_float                            | `D`
25337     uint8       | number_unsigned                         | `U`
25338     int8        | number_integer                          | `i`
25339     int16       | number_integer                          | `I`
25340     int32       | number_integer                          | `l`
25341     int64       | number_integer                          | `L`
25342     high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H'
25343     string      | string                                  | `S`
25344     char        | string                                  | `C`
25345     array       | array (optimized values are supported)  | `[`
25346     object      | object (optimized values are supported) | `{`
25347 
25348     @note The mapping is **complete** in the sense that any UBJSON value can
25349           be converted to a JSON value.
25350 
25351     @param[in] i  an input in UBJSON format convertible to an input adapter
25352     @param[in] strict  whether to expect the input to be consumed until EOF
25353                        (true by default)
25354     @param[in] allow_exceptions  whether to throw exceptions in case of a
25355     parse error (optional, true by default)
25356 
25357     @return deserialized JSON value; in case of a parse error and
25358             @a allow_exceptions set to `false`, the return value will be
25359             value_t::discarded.
25360 
25361     @throw parse_error.110 if the given input ends prematurely or the end of
25362     file was not reached when @a strict was set to true
25363     @throw parse_error.112 if a parse error occurs
25364     @throw parse_error.113 if a string could not be parsed successfully
25365 
25366     @complexity Linear in the size of the input @a i.
25367 
25368     @liveexample{The example shows the deserialization of a byte vector in
25369     UBJSON format to a JSON value.,from_ubjson}
25370 
25371     @sa http://ubjson.org
25372     @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
25373              analogous serialization
25374     @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25375         related CBOR format
25376     @sa see @ref from_msgpack(InputType&&, const bool, const bool) for
25377         the related MessagePack format
25378     @sa see @ref from_bson(InputType&&, const bool, const bool) for
25379         the related BSON format
25380 
25381     @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
25382     */
25383     template<typename InputType>
25384     JSON_HEDLEY_WARN_UNUSED_RESULT
from_ubjson(InputType && i,const bool strict=true,const bool allow_exceptions=true)25385     static basic_json from_ubjson(InputType&& i,
25386                                   const bool strict = true,
25387                                   const bool allow_exceptions = true)
25388     {
25389         basic_json result;
25390         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25391         auto ia = detail::input_adapter(std::forward<InputType>(i));
25392         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25393         return res ? result : basic_json(value_t::discarded);
25394     }
25395 
25396     /*!
25397     @copydoc from_ubjson(InputType&&, const bool, const bool)
25398     */
25399     template<typename IteratorType>
25400     JSON_HEDLEY_WARN_UNUSED_RESULT
from_ubjson(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)25401     static basic_json from_ubjson(IteratorType first, IteratorType last,
25402                                   const bool strict = true,
25403                                   const bool allow_exceptions = true)
25404     {
25405         basic_json result;
25406         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25407         auto ia = detail::input_adapter(std::move(first), std::move(last));
25408         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25409         return res ? result : basic_json(value_t::discarded);
25410     }
25411 
25412     template<typename T>
25413     JSON_HEDLEY_WARN_UNUSED_RESULT
25414     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
from_ubjson(const T * ptr,std::size_t len,const bool strict=true,const bool allow_exceptions=true)25415     static basic_json from_ubjson(const T* ptr, std::size_t len,
25416                                   const bool strict = true,
25417                                   const bool allow_exceptions = true)
25418     {
25419         return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
25420     }
25421 
25422     JSON_HEDLEY_WARN_UNUSED_RESULT
25423     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
from_ubjson(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true)25424     static basic_json from_ubjson(detail::span_input_adapter&& i,
25425                                   const bool strict = true,
25426                                   const bool allow_exceptions = true)
25427     {
25428         basic_json result;
25429         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25430         auto ia = i.get();
25431         // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25432         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25433         return res ? result : basic_json(value_t::discarded);
25434     }
25435 
25436 
25437     /*!
25438     @brief Create a JSON value from an input in BSON format
25439 
25440     Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
25441     serialization format.
25442 
25443     The library maps BSON record types to JSON value types as follows:
25444 
25445     BSON type       | BSON marker byte | JSON value type
25446     --------------- | ---------------- | ---------------------------
25447     double          | 0x01             | number_float
25448     string          | 0x02             | string
25449     document        | 0x03             | object
25450     array           | 0x04             | array
25451     binary          | 0x05             | binary
25452     undefined       | 0x06             | still unsupported
25453     ObjectId        | 0x07             | still unsupported
25454     boolean         | 0x08             | boolean
25455     UTC Date-Time   | 0x09             | still unsupported
25456     null            | 0x0A             | null
25457     Regular Expr.   | 0x0B             | still unsupported
25458     DB Pointer      | 0x0C             | still unsupported
25459     JavaScript Code | 0x0D             | still unsupported
25460     Symbol          | 0x0E             | still unsupported
25461     JavaScript Code | 0x0F             | still unsupported
25462     int32           | 0x10             | number_integer
25463     Timestamp       | 0x11             | still unsupported
25464     128-bit decimal float | 0x13       | still unsupported
25465     Max Key         | 0x7F             | still unsupported
25466     Min Key         | 0xFF             | still unsupported
25467 
25468     @warning The mapping is **incomplete**. The unsupported mappings
25469              are indicated in the table above.
25470 
25471     @param[in] i  an input in BSON format convertible to an input adapter
25472     @param[in] strict  whether to expect the input to be consumed until EOF
25473                        (true by default)
25474     @param[in] allow_exceptions  whether to throw exceptions in case of a
25475     parse error (optional, true by default)
25476 
25477     @return deserialized JSON value; in case of a parse error and
25478             @a allow_exceptions set to `false`, the return value will be
25479             value_t::discarded.
25480 
25481     @throw parse_error.114 if an unsupported BSON record type is encountered
25482 
25483     @complexity Linear in the size of the input @a i.
25484 
25485     @liveexample{The example shows the deserialization of a byte vector in
25486     BSON format to a JSON value.,from_bson}
25487 
25488     @sa http://bsonspec.org/spec.html
25489     @sa see @ref to_bson(const basic_json&) for the analogous serialization
25490     @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25491         related CBOR format
25492     @sa see @ref from_msgpack(InputType&&, const bool, const bool) for
25493         the related MessagePack format
25494     @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
25495         related UBJSON format
25496     */
25497     template<typename InputType>
25498     JSON_HEDLEY_WARN_UNUSED_RESULT
from_bson(InputType && i,const bool strict=true,const bool allow_exceptions=true)25499     static basic_json from_bson(InputType&& i,
25500                                 const bool strict = true,
25501                                 const bool allow_exceptions = true)
25502     {
25503         basic_json result;
25504         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25505         auto ia = detail::input_adapter(std::forward<InputType>(i));
25506         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25507         return res ? result : basic_json(value_t::discarded);
25508     }
25509 
25510     /*!
25511     @copydoc from_bson(InputType&&, const bool, const bool)
25512     */
25513     template<typename IteratorType>
25514     JSON_HEDLEY_WARN_UNUSED_RESULT
from_bson(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)25515     static basic_json from_bson(IteratorType first, IteratorType last,
25516                                 const bool strict = true,
25517                                 const bool allow_exceptions = true)
25518     {
25519         basic_json result;
25520         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25521         auto ia = detail::input_adapter(std::move(first), std::move(last));
25522         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25523         return res ? result : basic_json(value_t::discarded);
25524     }
25525 
25526     template<typename T>
25527     JSON_HEDLEY_WARN_UNUSED_RESULT
25528     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
from_bson(const T * ptr,std::size_t len,const bool strict=true,const bool allow_exceptions=true)25529     static basic_json from_bson(const T* ptr, std::size_t len,
25530                                 const bool strict = true,
25531                                 const bool allow_exceptions = true)
25532     {
25533         return from_bson(ptr, ptr + len, strict, allow_exceptions);
25534     }
25535 
25536     JSON_HEDLEY_WARN_UNUSED_RESULT
25537     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
from_bson(detail::span_input_adapter && i,const bool strict=true,const bool allow_exceptions=true)25538     static basic_json from_bson(detail::span_input_adapter&& i,
25539                                 const bool strict = true,
25540                                 const bool allow_exceptions = true)
25541     {
25542         basic_json result;
25543         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25544         auto ia = i.get();
25545         // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25546         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25547         return res ? result : basic_json(value_t::discarded);
25548     }
25549     /// @}
25550 
25551     //////////////////////////
25552     // JSON Pointer support //
25553     //////////////////////////
25554 
25555     /// @name JSON Pointer functions
25556     /// @{
25557 
25558     /*!
25559     @brief access specified element via JSON Pointer
25560 
25561     Uses a JSON pointer to retrieve a reference to the respective JSON value.
25562     No bound checking is performed. Similar to @ref operator[](const typename
25563     object_t::key_type&), `null` values are created in arrays and objects if
25564     necessary.
25565 
25566     In particular:
25567     - If the JSON pointer points to an object key that does not exist, it
25568       is created an filled with a `null` value before a reference to it
25569       is returned.
25570     - If the JSON pointer points to an array index that does not exist, it
25571       is created an filled with a `null` value before a reference to it
25572       is returned. All indices between the current maximum and the given
25573       index are also filled with `null`.
25574     - The special value `-` is treated as a synonym for the index past the
25575       end.
25576 
25577     @param[in] ptr  a JSON pointer
25578 
25579     @return reference to the element pointed to by @a ptr
25580 
25581     @complexity Constant.
25582 
25583     @throw parse_error.106   if an array index begins with '0'
25584     @throw parse_error.109   if an array index was not a number
25585     @throw out_of_range.404  if the JSON pointer can not be resolved
25586 
25587     @liveexample{The behavior is shown in the example.,operatorjson_pointer}
25588 
25589     @since version 2.0.0
25590     */
operator [](const json_pointer & ptr)25591     reference operator[](const json_pointer& ptr)
25592     {
25593         return ptr.get_unchecked(this);
25594     }
25595 
25596     /*!
25597     @brief access specified element via JSON Pointer
25598 
25599     Uses a JSON pointer to retrieve a reference to the respective JSON value.
25600     No bound checking is performed. The function does not change the JSON
25601     value; no `null` values are created. In particular, the special value
25602     `-` yields an exception.
25603 
25604     @param[in] ptr  JSON pointer to the desired element
25605 
25606     @return const reference to the element pointed to by @a ptr
25607 
25608     @complexity Constant.
25609 
25610     @throw parse_error.106   if an array index begins with '0'
25611     @throw parse_error.109   if an array index was not a number
25612     @throw out_of_range.402  if the array index '-' is used
25613     @throw out_of_range.404  if the JSON pointer can not be resolved
25614 
25615     @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
25616 
25617     @since version 2.0.0
25618     */
operator [](const json_pointer & ptr) const25619     const_reference operator[](const json_pointer& ptr) const
25620     {
25621         return ptr.get_unchecked(this);
25622     }
25623 
25624     /*!
25625     @brief access specified element via JSON Pointer
25626 
25627     Returns a reference to the element at with specified JSON pointer @a ptr,
25628     with bounds checking.
25629 
25630     @param[in] ptr  JSON pointer to the desired element
25631 
25632     @return reference to the element pointed to by @a ptr
25633 
25634     @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
25635     begins with '0'. See example below.
25636 
25637     @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
25638     is not a number. See example below.
25639 
25640     @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
25641     is out of range. See example below.
25642 
25643     @throw out_of_range.402 if the array index '-' is used in the passed JSON
25644     pointer @a ptr. As `at` provides checked access (and no elements are
25645     implicitly inserted), the index '-' is always invalid. See example below.
25646 
25647     @throw out_of_range.403 if the JSON pointer describes a key of an object
25648     which cannot be found. See example below.
25649 
25650     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
25651     See example below.
25652 
25653     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
25654     changes in the JSON value.
25655 
25656     @complexity Constant.
25657 
25658     @since version 2.0.0
25659 
25660     @liveexample{The behavior is shown in the example.,at_json_pointer}
25661     */
at(const json_pointer & ptr)25662     reference at(const json_pointer& ptr)
25663     {
25664         return ptr.get_checked(this);
25665     }
25666 
25667     /*!
25668     @brief access specified element via JSON Pointer
25669 
25670     Returns a const reference to the element at with specified JSON pointer @a
25671     ptr, with bounds checking.
25672 
25673     @param[in] ptr  JSON pointer to the desired element
25674 
25675     @return reference to the element pointed to by @a ptr
25676 
25677     @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
25678     begins with '0'. See example below.
25679 
25680     @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
25681     is not a number. See example below.
25682 
25683     @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
25684     is out of range. See example below.
25685 
25686     @throw out_of_range.402 if the array index '-' is used in the passed JSON
25687     pointer @a ptr. As `at` provides checked access (and no elements are
25688     implicitly inserted), the index '-' is always invalid. See example below.
25689 
25690     @throw out_of_range.403 if the JSON pointer describes a key of an object
25691     which cannot be found. See example below.
25692 
25693     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
25694     See example below.
25695 
25696     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
25697     changes in the JSON value.
25698 
25699     @complexity Constant.
25700 
25701     @since version 2.0.0
25702 
25703     @liveexample{The behavior is shown in the example.,at_json_pointer_const}
25704     */
at(const json_pointer & ptr) const25705     const_reference at(const json_pointer& ptr) const
25706     {
25707         return ptr.get_checked(this);
25708     }
25709 
25710     /*!
25711     @brief return flattened JSON value
25712 
25713     The function creates a JSON object whose keys are JSON pointers (see [RFC
25714     6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
25715     primitive. The original JSON value can be restored using the @ref
25716     unflatten() function.
25717 
25718     @return an object that maps JSON pointers to primitive values
25719 
25720     @note Empty objects and arrays are flattened to `null` and will not be
25721           reconstructed correctly by the @ref unflatten() function.
25722 
25723     @complexity Linear in the size the JSON value.
25724 
25725     @liveexample{The following code shows how a JSON object is flattened to an
25726     object whose keys consist of JSON pointers.,flatten}
25727 
25728     @sa see @ref unflatten() for the reverse function
25729 
25730     @since version 2.0.0
25731     */
flatten() const25732     basic_json flatten() const
25733     {
25734         basic_json result(value_t::object);
25735         json_pointer::flatten("", *this, result);
25736         return result;
25737     }
25738 
25739     /*!
25740     @brief unflatten a previously flattened JSON value
25741 
25742     The function restores the arbitrary nesting of a JSON value that has been
25743     flattened before using the @ref flatten() function. The JSON value must
25744     meet certain constraints:
25745     1. The value must be an object.
25746     2. The keys must be JSON pointers (see
25747        [RFC 6901](https://tools.ietf.org/html/rfc6901))
25748     3. The mapped values must be primitive JSON types.
25749 
25750     @return the original JSON from a flattened version
25751 
25752     @note Empty objects and arrays are flattened by @ref flatten() to `null`
25753           values and can not unflattened to their original type. Apart from
25754           this example, for a JSON value `j`, the following is always true:
25755           `j == j.flatten().unflatten()`.
25756 
25757     @complexity Linear in the size the JSON value.
25758 
25759     @throw type_error.314  if value is not an object
25760     @throw type_error.315  if object values are not primitive
25761 
25762     @liveexample{The following code shows how a flattened JSON object is
25763     unflattened into the original nested JSON object.,unflatten}
25764 
25765     @sa see @ref flatten() for the reverse function
25766 
25767     @since version 2.0.0
25768     */
unflatten() const25769     basic_json unflatten() const
25770     {
25771         return json_pointer::unflatten(*this);
25772     }
25773 
25774     /// @}
25775 
25776     //////////////////////////
25777     // JSON Patch functions //
25778     //////////////////////////
25779 
25780     /// @name JSON Patch functions
25781     /// @{
25782 
25783     /*!
25784     @brief applies a JSON patch
25785 
25786     [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
25787     expressing a sequence of operations to apply to a JSON) document. With
25788     this function, a JSON Patch is applied to the current JSON value by
25789     executing all operations from the patch.
25790 
25791     @param[in] json_patch  JSON patch document
25792     @return patched document
25793 
25794     @note The application of a patch is atomic: Either all operations succeed
25795           and the patched document is returned or an exception is thrown. In
25796           any case, the original value is not changed: the patch is applied
25797           to a copy of the value.
25798 
25799     @throw parse_error.104 if the JSON patch does not consist of an array of
25800     objects
25801 
25802     @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
25803     attributes are missing); example: `"operation add must have member path"`
25804 
25805     @throw out_of_range.401 if an array index is out of range.
25806 
25807     @throw out_of_range.403 if a JSON pointer inside the patch could not be
25808     resolved successfully in the current JSON value; example: `"key baz not
25809     found"`
25810 
25811     @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
25812     "move")
25813 
25814     @throw other_error.501 if "test" operation was unsuccessful
25815 
25816     @complexity Linear in the size of the JSON value and the length of the
25817     JSON patch. As usually only a fraction of the JSON value is affected by
25818     the patch, the complexity can usually be neglected.
25819 
25820     @liveexample{The following code shows how a JSON patch is applied to a
25821     value.,patch}
25822 
25823     @sa see @ref diff -- create a JSON patch by comparing two JSON values
25824 
25825     @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
25826     @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
25827 
25828     @since version 2.0.0
25829     */
patch(const basic_json & json_patch) const25830     basic_json patch(const basic_json& json_patch) const
25831     {
25832         // make a working copy to apply the patch to
25833         basic_json result = *this;
25834 
25835         // the valid JSON Patch operations
25836         enum class patch_operations {add, remove, replace, move, copy, test, invalid};
25837 
25838         const auto get_op = [](const std::string & op)
25839         {
25840             if (op == "add")
25841             {
25842                 return patch_operations::add;
25843             }
25844             if (op == "remove")
25845             {
25846                 return patch_operations::remove;
25847             }
25848             if (op == "replace")
25849             {
25850                 return patch_operations::replace;
25851             }
25852             if (op == "move")
25853             {
25854                 return patch_operations::move;
25855             }
25856             if (op == "copy")
25857             {
25858                 return patch_operations::copy;
25859             }
25860             if (op == "test")
25861             {
25862                 return patch_operations::test;
25863             }
25864 
25865             return patch_operations::invalid;
25866         };
25867 
25868         // wrapper for "add" operation; add value at ptr
25869         const auto operation_add = [&result](json_pointer & ptr, basic_json val)
25870         {
25871             // adding to the root of the target document means replacing it
25872             if (ptr.empty())
25873             {
25874                 result = val;
25875                 return;
25876             }
25877 
25878             // make sure the top element of the pointer exists
25879             json_pointer top_pointer = ptr.top();
25880             if (top_pointer != ptr)
25881             {
25882                 result.at(top_pointer);
25883             }
25884 
25885             // get reference to parent of JSON pointer ptr
25886             const auto last_path = ptr.back();
25887             ptr.pop_back();
25888             basic_json& parent = result[ptr];
25889 
25890             switch (parent.m_type)
25891             {
25892                 case value_t::null:
25893                 case value_t::object:
25894                 {
25895                     // use operator[] to add value
25896                     parent[last_path] = val;
25897                     break;
25898                 }
25899 
25900                 case value_t::array:
25901                 {
25902                     if (last_path == "-")
25903                     {
25904                         // special case: append to back
25905                         parent.push_back(val);
25906                     }
25907                     else
25908                     {
25909                         const auto idx = json_pointer::array_index(last_path);
25910                         if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
25911                         {
25912                             // avoid undefined behavior
25913                             JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
25914                         }
25915 
25916                         // default case: insert add offset
25917                         parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
25918                     }
25919                     break;
25920                 }
25921 
25922                 // if there exists a parent it cannot be primitive
25923                 case value_t::string: // LCOV_EXCL_LINE
25924                 case value_t::boolean: // LCOV_EXCL_LINE
25925                 case value_t::number_integer: // LCOV_EXCL_LINE
25926                 case value_t::number_unsigned: // LCOV_EXCL_LINE
25927                 case value_t::number_float: // LCOV_EXCL_LINE
25928                 case value_t::binary: // LCOV_EXCL_LINE
25929                 case value_t::discarded: // LCOV_EXCL_LINE
25930                 default:            // LCOV_EXCL_LINE
25931                     JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
25932             }
25933         };
25934 
25935         // wrapper for "remove" operation; remove value at ptr
25936         const auto operation_remove = [this, &result](json_pointer & ptr)
25937         {
25938             // get reference to parent of JSON pointer ptr
25939             const auto last_path = ptr.back();
25940             ptr.pop_back();
25941             basic_json& parent = result.at(ptr);
25942 
25943             // remove child
25944             if (parent.is_object())
25945             {
25946                 // perform range check
25947                 auto it = parent.find(last_path);
25948                 if (JSON_HEDLEY_LIKELY(it != parent.end()))
25949                 {
25950                     parent.erase(it);
25951                 }
25952                 else
25953                 {
25954                     JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
25955                 }
25956             }
25957             else if (parent.is_array())
25958             {
25959                 // note erase performs range check
25960                 parent.erase(json_pointer::array_index(last_path));
25961             }
25962         };
25963 
25964         // type check: top level value must be an array
25965         if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
25966         {
25967             JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
25968         }
25969 
25970         // iterate and apply the operations
25971         for (const auto& val : json_patch)
25972         {
25973             // wrapper to get a value for an operation
25974             const auto get_value = [&val](const std::string & op,
25975                                           const std::string & member,
25976                                           bool string_type) -> basic_json &
25977             {
25978                 // find value
25979                 auto it = val.m_value.object->find(member);
25980 
25981                 // context-sensitive error message
25982                 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
25983 
25984                 // check if desired value is present
25985                 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
25986                 {
25987                     // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25988                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
25989                 }
25990 
25991                 // check if result is of type string
25992                 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
25993                 {
25994                     // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25995                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
25996                 }
25997 
25998                 // no error: return value
25999                 return it->second;
26000             };
26001 
26002             // type check: every element of the array must be an object
26003             if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
26004             {
26005                 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
26006             }
26007 
26008             // collect mandatory members
26009             const auto op = get_value("op", "op", true).template get<std::string>();
26010             const auto path = get_value(op, "path", true).template get<std::string>();
26011             json_pointer ptr(path);
26012 
26013             switch (get_op(op))
26014             {
26015                 case patch_operations::add:
26016                 {
26017                     operation_add(ptr, get_value("add", "value", false));
26018                     break;
26019                 }
26020 
26021                 case patch_operations::remove:
26022                 {
26023                     operation_remove(ptr);
26024                     break;
26025                 }
26026 
26027                 case patch_operations::replace:
26028                 {
26029                     // the "path" location must exist - use at()
26030                     result.at(ptr) = get_value("replace", "value", false);
26031                     break;
26032                 }
26033 
26034                 case patch_operations::move:
26035                 {
26036                     const auto from_path = get_value("move", "from", true).template get<std::string>();
26037                     json_pointer from_ptr(from_path);
26038 
26039                     // the "from" location must exist - use at()
26040                     basic_json v = result.at(from_ptr);
26041 
26042                     // The move operation is functionally identical to a
26043                     // "remove" operation on the "from" location, followed
26044                     // immediately by an "add" operation at the target
26045                     // location with the value that was just removed.
26046                     operation_remove(from_ptr);
26047                     operation_add(ptr, v);
26048                     break;
26049                 }
26050 
26051                 case patch_operations::copy:
26052                 {
26053                     const auto from_path = get_value("copy", "from", true).template get<std::string>();
26054                     const json_pointer from_ptr(from_path);
26055 
26056                     // the "from" location must exist - use at()
26057                     basic_json v = result.at(from_ptr);
26058 
26059                     // The copy is functionally identical to an "add"
26060                     // operation at the target location using the value
26061                     // specified in the "from" member.
26062                     operation_add(ptr, v);
26063                     break;
26064                 }
26065 
26066                 case patch_operations::test:
26067                 {
26068                     bool success = false;
26069                     JSON_TRY
26070                     {
26071                         // check if "value" matches the one at "path"
26072                         // the "path" location must exist - use at()
26073                         success = (result.at(ptr) == get_value("test", "value", false));
26074                     }
26075                     JSON_INTERNAL_CATCH (out_of_range&)
26076                     {
26077                         // ignore out of range errors: success remains false
26078                     }
26079 
26080                     // throw an exception if test fails
26081                     if (JSON_HEDLEY_UNLIKELY(!success))
26082                     {
26083                         JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
26084                     }
26085 
26086                     break;
26087                 }
26088 
26089                 case patch_operations::invalid:
26090                 default:
26091                 {
26092                     // op must be "add", "remove", "replace", "move", "copy", or
26093                     // "test"
26094                     JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
26095                 }
26096             }
26097         }
26098 
26099         return result;
26100     }
26101 
26102     /*!
26103     @brief creates a diff as a JSON patch
26104 
26105     Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
26106     be changed into the value @a target by calling @ref patch function.
26107 
26108     @invariant For two JSON values @a source and @a target, the following code
26109     yields always `true`:
26110     @code {.cpp}
26111     source.patch(diff(source, target)) == target;
26112     @endcode
26113 
26114     @note Currently, only `remove`, `add`, and `replace` operations are
26115           generated.
26116 
26117     @param[in] source  JSON value to compare from
26118     @param[in] target  JSON value to compare against
26119     @param[in] path    helper value to create JSON pointers
26120 
26121     @return a JSON patch to convert the @a source to @a target
26122 
26123     @complexity Linear in the lengths of @a source and @a target.
26124 
26125     @liveexample{The following code shows how a JSON patch is created as a
26126     diff for two JSON values.,diff}
26127 
26128     @sa see @ref patch -- apply a JSON patch
26129     @sa see @ref merge_patch -- apply a JSON Merge Patch
26130 
26131     @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
26132 
26133     @since version 2.0.0
26134     */
26135     JSON_HEDLEY_WARN_UNUSED_RESULT
diff(const basic_json & source,const basic_json & target,const std::string & path="")26136     static basic_json diff(const basic_json& source, const basic_json& target,
26137                            const std::string& path = "")
26138     {
26139         // the patch
26140         basic_json result(value_t::array);
26141 
26142         // if the values are the same, return empty patch
26143         if (source == target)
26144         {
26145             return result;
26146         }
26147 
26148         if (source.type() != target.type())
26149         {
26150             // different types: replace value
26151             result.push_back(
26152             {
26153                 {"op", "replace"}, {"path", path}, {"value", target}
26154             });
26155             return result;
26156         }
26157 
26158         switch (source.type())
26159         {
26160             case value_t::array:
26161             {
26162                 // first pass: traverse common elements
26163                 std::size_t i = 0;
26164                 while (i < source.size() && i < target.size())
26165                 {
26166                     // recursive call to compare array values at index i
26167                     auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
26168                     result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26169                     ++i;
26170                 }
26171 
26172                 // i now reached the end of at least one array
26173                 // in a second pass, traverse the remaining elements
26174 
26175                 // remove my remaining elements
26176                 const auto end_index = static_cast<difference_type>(result.size());
26177                 while (i < source.size())
26178                 {
26179                     // add operations in reverse order to avoid invalid
26180                     // indices
26181                     result.insert(result.begin() + end_index, object(
26182                     {
26183                         {"op", "remove"},
26184                         {"path", path + "/" + std::to_string(i)}
26185                     }));
26186                     ++i;
26187                 }
26188 
26189                 // add other remaining elements
26190                 while (i < target.size())
26191                 {
26192                     result.push_back(
26193                     {
26194                         {"op", "add"},
26195                         {"path", path + "/-"},
26196                         {"value", target[i]}
26197                     });
26198                     ++i;
26199                 }
26200 
26201                 break;
26202             }
26203 
26204             case value_t::object:
26205             {
26206                 // first pass: traverse this object's elements
26207                 for (auto it = source.cbegin(); it != source.cend(); ++it)
26208                 {
26209                     // escape the key name to be used in a JSON patch
26210                     const auto path_key = path + "/" + detail::escape(it.key());
26211 
26212                     if (target.find(it.key()) != target.end())
26213                     {
26214                         // recursive call to compare object values at key it
26215                         auto temp_diff = diff(it.value(), target[it.key()], path_key);
26216                         result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26217                     }
26218                     else
26219                     {
26220                         // found a key that is not in o -> remove it
26221                         result.push_back(object(
26222                         {
26223                             {"op", "remove"}, {"path", path_key}
26224                         }));
26225                     }
26226                 }
26227 
26228                 // second pass: traverse other object's elements
26229                 for (auto it = target.cbegin(); it != target.cend(); ++it)
26230                 {
26231                     if (source.find(it.key()) == source.end())
26232                     {
26233                         // found a key that is not in this -> add it
26234                         const auto path_key = path + "/" + detail::escape(it.key());
26235                         result.push_back(
26236                         {
26237                             {"op", "add"}, {"path", path_key},
26238                             {"value", it.value()}
26239                         });
26240                     }
26241                 }
26242 
26243                 break;
26244             }
26245 
26246             case value_t::null:
26247             case value_t::string:
26248             case value_t::boolean:
26249             case value_t::number_integer:
26250             case value_t::number_unsigned:
26251             case value_t::number_float:
26252             case value_t::binary:
26253             case value_t::discarded:
26254             default:
26255             {
26256                 // both primitive type: replace value
26257                 result.push_back(
26258                 {
26259                     {"op", "replace"}, {"path", path}, {"value", target}
26260                 });
26261                 break;
26262             }
26263         }
26264 
26265         return result;
26266     }
26267 
26268     /// @}
26269 
26270     ////////////////////////////////
26271     // JSON Merge Patch functions //
26272     ////////////////////////////////
26273 
26274     /// @name JSON Merge Patch functions
26275     /// @{
26276 
26277     /*!
26278     @brief applies a JSON Merge Patch
26279 
26280     The merge patch format is primarily intended for use with the HTTP PATCH
26281     method as a means of describing a set of modifications to a target
26282     resource's content. This function applies a merge patch to the current
26283     JSON value.
26284 
26285     The function implements the following algorithm from Section 2 of
26286     [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
26287 
26288     ```
26289     define MergePatch(Target, Patch):
26290       if Patch is an Object:
26291         if Target is not an Object:
26292           Target = {} // Ignore the contents and set it to an empty Object
26293         for each Name/Value pair in Patch:
26294           if Value is null:
26295             if Name exists in Target:
26296               remove the Name/Value pair from Target
26297           else:
26298             Target[Name] = MergePatch(Target[Name], Value)
26299         return Target
26300       else:
26301         return Patch
26302     ```
26303 
26304     Thereby, `Target` is the current object; that is, the patch is applied to
26305     the current value.
26306 
26307     @param[in] apply_patch  the patch to apply
26308 
26309     @complexity Linear in the lengths of @a patch.
26310 
26311     @liveexample{The following code shows how a JSON Merge Patch is applied to
26312     a JSON document.,merge_patch}
26313 
26314     @sa see @ref patch -- apply a JSON patch
26315     @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
26316 
26317     @since version 3.0.0
26318     */
merge_patch(const basic_json & apply_patch)26319     void merge_patch(const basic_json& apply_patch)
26320     {
26321         if (apply_patch.is_object())
26322         {
26323             if (!is_object())
26324             {
26325                 *this = object();
26326             }
26327             for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
26328             {
26329                 if (it.value().is_null())
26330                 {
26331                     erase(it.key());
26332                 }
26333                 else
26334                 {
26335                     operator[](it.key()).merge_patch(it.value());
26336                 }
26337             }
26338         }
26339         else
26340         {
26341             *this = apply_patch;
26342         }
26343     }
26344 
26345     /// @}
26346 };
26347 
26348 /*!
26349 @brief user-defined to_string function for JSON values
26350 
26351 This function implements a user-defined to_string  for JSON objects.
26352 
26353 @param[in] j  a JSON object
26354 @return a std::string object
26355 */
26356 
26357 NLOHMANN_BASIC_JSON_TPL_DECLARATION
to_string(const NLOHMANN_BASIC_JSON_TPL & j)26358 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
26359 {
26360     return j.dump();
26361 }
26362 } // namespace nlohmann
26363 
26364 ///////////////////////
26365 // nonmember support //
26366 ///////////////////////
26367 
26368 // specialization of std::swap, and std::hash
26369 namespace std
26370 {
26371 
26372 /// hash value for JSON objects
26373 template<>
26374 struct hash<nlohmann::json>
26375 {
26376     /*!
26377     @brief return a hash value for a JSON object
26378 
26379     @since version 1.0.0
26380     */
operator ()std::hash26381     std::size_t operator()(const nlohmann::json& j) const
26382     {
26383         return nlohmann::detail::hash(j);
26384     }
26385 };
26386 
26387 /// specialization for std::less<value_t>
26388 /// @note: do not remove the space after '<',
26389 ///        see https://github.com/nlohmann/json/pull/679
26390 template<>
26391 struct less<::nlohmann::detail::value_t>
26392 {
26393     /*!
26394     @brief compare two value_t enum values
26395     @since version 3.0.0
26396     */
operator ()std::less26397     bool operator()(nlohmann::detail::value_t lhs,
26398                     nlohmann::detail::value_t rhs) const noexcept
26399     {
26400         return nlohmann::detail::operator<(lhs, rhs);
26401     }
26402 };
26403 
26404 // C++20 prohibit function specialization in the std namespace.
26405 #ifndef JSON_HAS_CPP_20
26406 
26407 /*!
26408 @brief exchanges the values of two JSON objects
26409 
26410 @since version 1.0.0
26411 */
26412 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)26413 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
26414     is_nothrow_move_constructible<nlohmann::json>::value&&  // NOLINT(misc-redundant-expression)
26415     is_nothrow_move_assignable<nlohmann::json>::value
26416                               )
26417 {
26418     j1.swap(j2);
26419 }
26420 
26421 #endif
26422 
26423 } // namespace std
26424 
26425 /*!
26426 @brief user-defined string literal for JSON values
26427 
26428 This operator implements a user-defined string literal for JSON objects. It
26429 can be used by adding `"_json"` to a string literal and returns a JSON object
26430 if no parse error occurred.
26431 
26432 @param[in] s  a string representation of a JSON object
26433 @param[in] n  the length of string @a s
26434 @return a JSON object
26435 
26436 @since version 1.0.0
26437 */
26438 JSON_HEDLEY_NON_NULL(1)
operator ""_json(const char * s,std::size_t n)26439 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
26440 {
26441     return nlohmann::json::parse(s, s + n);
26442 }
26443 
26444 /*!
26445 @brief user-defined string literal for JSON pointer
26446 
26447 This operator implements a user-defined string literal for JSON Pointers. It
26448 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
26449 object if no parse error occurred.
26450 
26451 @param[in] s  a string representation of a JSON Pointer
26452 @param[in] n  the length of string @a s
26453 @return a JSON pointer object
26454 
26455 @since version 2.0.0
26456 */
26457 JSON_HEDLEY_NON_NULL(1)
operator ""_json_pointer(const char * s,std::size_t n)26458 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
26459 {
26460     return nlohmann::json::json_pointer(std::string(s, n));
26461 }
26462 
26463 // #include <nlohmann/detail/macro_unscope.hpp>
26464 
26465 
26466 // restore clang diagnostic settings
26467 #if defined(__clang__)
26468     #pragma clang diagnostic pop
26469 #endif
26470 
26471 // clean up
26472 #undef JSON_ASSERT
26473 #undef JSON_INTERNAL_CATCH
26474 #undef JSON_CATCH
26475 #undef JSON_THROW
26476 #undef JSON_TRY
26477 #undef JSON_PRIVATE_UNLESS_TESTED
26478 #undef JSON_HAS_CPP_11
26479 #undef JSON_HAS_CPP_14
26480 #undef JSON_HAS_CPP_17
26481 #undef JSON_HAS_CPP_20
26482 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
26483 #undef NLOHMANN_BASIC_JSON_TPL
26484 #undef JSON_EXPLICIT
26485 
26486 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
26487 
26488 
26489 #undef JSON_HEDLEY_ALWAYS_INLINE
26490 #undef JSON_HEDLEY_ARM_VERSION
26491 #undef JSON_HEDLEY_ARM_VERSION_CHECK
26492 #undef JSON_HEDLEY_ARRAY_PARAM
26493 #undef JSON_HEDLEY_ASSUME
26494 #undef JSON_HEDLEY_BEGIN_C_DECLS
26495 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
26496 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
26497 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
26498 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
26499 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
26500 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
26501 #undef JSON_HEDLEY_CLANG_HAS_WARNING
26502 #undef JSON_HEDLEY_COMPCERT_VERSION
26503 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
26504 #undef JSON_HEDLEY_CONCAT
26505 #undef JSON_HEDLEY_CONCAT3
26506 #undef JSON_HEDLEY_CONCAT3_EX
26507 #undef JSON_HEDLEY_CONCAT_EX
26508 #undef JSON_HEDLEY_CONST
26509 #undef JSON_HEDLEY_CONSTEXPR
26510 #undef JSON_HEDLEY_CONST_CAST
26511 #undef JSON_HEDLEY_CPP_CAST
26512 #undef JSON_HEDLEY_CRAY_VERSION
26513 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
26514 #undef JSON_HEDLEY_C_DECL
26515 #undef JSON_HEDLEY_DEPRECATED
26516 #undef JSON_HEDLEY_DEPRECATED_FOR
26517 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
26518 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
26519 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
26520 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
26521 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
26522 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
26523 #undef JSON_HEDLEY_DIAGNOSTIC_POP
26524 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
26525 #undef JSON_HEDLEY_DMC_VERSION
26526 #undef JSON_HEDLEY_DMC_VERSION_CHECK
26527 #undef JSON_HEDLEY_EMPTY_BASES
26528 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
26529 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
26530 #undef JSON_HEDLEY_END_C_DECLS
26531 #undef JSON_HEDLEY_FLAGS
26532 #undef JSON_HEDLEY_FLAGS_CAST
26533 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
26534 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
26535 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
26536 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
26537 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
26538 #undef JSON_HEDLEY_GCC_HAS_FEATURE
26539 #undef JSON_HEDLEY_GCC_HAS_WARNING
26540 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
26541 #undef JSON_HEDLEY_GCC_VERSION
26542 #undef JSON_HEDLEY_GCC_VERSION_CHECK
26543 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
26544 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
26545 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
26546 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
26547 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
26548 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
26549 #undef JSON_HEDLEY_GNUC_HAS_WARNING
26550 #undef JSON_HEDLEY_GNUC_VERSION
26551 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
26552 #undef JSON_HEDLEY_HAS_ATTRIBUTE
26553 #undef JSON_HEDLEY_HAS_BUILTIN
26554 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
26555 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
26556 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
26557 #undef JSON_HEDLEY_HAS_EXTENSION
26558 #undef JSON_HEDLEY_HAS_FEATURE
26559 #undef JSON_HEDLEY_HAS_WARNING
26560 #undef JSON_HEDLEY_IAR_VERSION
26561 #undef JSON_HEDLEY_IAR_VERSION_CHECK
26562 #undef JSON_HEDLEY_IBM_VERSION
26563 #undef JSON_HEDLEY_IBM_VERSION_CHECK
26564 #undef JSON_HEDLEY_IMPORT
26565 #undef JSON_HEDLEY_INLINE
26566 #undef JSON_HEDLEY_INTEL_CL_VERSION
26567 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
26568 #undef JSON_HEDLEY_INTEL_VERSION
26569 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
26570 #undef JSON_HEDLEY_IS_CONSTANT
26571 #undef JSON_HEDLEY_IS_CONSTEXPR_
26572 #undef JSON_HEDLEY_LIKELY
26573 #undef JSON_HEDLEY_MALLOC
26574 #undef JSON_HEDLEY_MCST_LCC_VERSION
26575 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
26576 #undef JSON_HEDLEY_MESSAGE
26577 #undef JSON_HEDLEY_MSVC_VERSION
26578 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
26579 #undef JSON_HEDLEY_NEVER_INLINE
26580 #undef JSON_HEDLEY_NON_NULL
26581 #undef JSON_HEDLEY_NO_ESCAPE
26582 #undef JSON_HEDLEY_NO_RETURN
26583 #undef JSON_HEDLEY_NO_THROW
26584 #undef JSON_HEDLEY_NULL
26585 #undef JSON_HEDLEY_PELLES_VERSION
26586 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
26587 #undef JSON_HEDLEY_PGI_VERSION
26588 #undef JSON_HEDLEY_PGI_VERSION_CHECK
26589 #undef JSON_HEDLEY_PREDICT
26590 #undef JSON_HEDLEY_PRINTF_FORMAT
26591 #undef JSON_HEDLEY_PRIVATE
26592 #undef JSON_HEDLEY_PUBLIC
26593 #undef JSON_HEDLEY_PURE
26594 #undef JSON_HEDLEY_REINTERPRET_CAST
26595 #undef JSON_HEDLEY_REQUIRE
26596 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
26597 #undef JSON_HEDLEY_REQUIRE_MSG
26598 #undef JSON_HEDLEY_RESTRICT
26599 #undef JSON_HEDLEY_RETURNS_NON_NULL
26600 #undef JSON_HEDLEY_SENTINEL
26601 #undef JSON_HEDLEY_STATIC_ASSERT
26602 #undef JSON_HEDLEY_STATIC_CAST
26603 #undef JSON_HEDLEY_STRINGIFY
26604 #undef JSON_HEDLEY_STRINGIFY_EX
26605 #undef JSON_HEDLEY_SUNPRO_VERSION
26606 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
26607 #undef JSON_HEDLEY_TINYC_VERSION
26608 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
26609 #undef JSON_HEDLEY_TI_ARMCL_VERSION
26610 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
26611 #undef JSON_HEDLEY_TI_CL2000_VERSION
26612 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
26613 #undef JSON_HEDLEY_TI_CL430_VERSION
26614 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
26615 #undef JSON_HEDLEY_TI_CL6X_VERSION
26616 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
26617 #undef JSON_HEDLEY_TI_CL7X_VERSION
26618 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
26619 #undef JSON_HEDLEY_TI_CLPRU_VERSION
26620 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
26621 #undef JSON_HEDLEY_TI_VERSION
26622 #undef JSON_HEDLEY_TI_VERSION_CHECK
26623 #undef JSON_HEDLEY_UNAVAILABLE
26624 #undef JSON_HEDLEY_UNLIKELY
26625 #undef JSON_HEDLEY_UNPREDICTABLE
26626 #undef JSON_HEDLEY_UNREACHABLE
26627 #undef JSON_HEDLEY_UNREACHABLE_RETURN
26628 #undef JSON_HEDLEY_VERSION
26629 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
26630 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
26631 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
26632 #undef JSON_HEDLEY_VERSION_ENCODE
26633 #undef JSON_HEDLEY_WARNING
26634 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
26635 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
26636 #undef JSON_HEDLEY_FALL_THROUGH
26637 
26638 
26639 
26640 #endif  // INCLUDE_NLOHMANN_JSON_HPP_
26641