1 /*
2     __ _____ _____ _____
3  __|  |   __|     |   | |  JSON for Modern C++
4 |  |  |__   |  |  | | | |  version 3.10.4
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 4
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> // declval, 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 // #include <nlohmann/detail/meta/detected.hpp>
2218 
2219 
2220 #include <type_traits>
2221 
2222 // #include <nlohmann/detail/meta/void_t.hpp>
2223 
2224 
2225 namespace nlohmann
2226 {
2227 namespace detail
2228 {
2229 template<typename ...Ts> struct make_void
2230 {
2231     using type = void;
2232 };
2233 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2234 } // namespace detail
2235 }  // namespace nlohmann
2236 
2237 
2238 // https://en.cppreference.com/w/cpp/experimental/is_detected
2239 namespace nlohmann
2240 {
2241 namespace detail
2242 {
2243 struct nonesuch
2244 {
2245     nonesuch() = delete;
2246     ~nonesuch() = delete;
2247     nonesuch(nonesuch const&) = delete;
2248     nonesuch(nonesuch const&&) = delete;
2249     void operator=(nonesuch const&) = delete;
2250     void operator=(nonesuch&&) = delete;
2251 };
2252 
2253 template<class Default,
2254          class AlwaysVoid,
2255          template<class...> class Op,
2256          class... Args>
2257 struct detector
2258 {
2259     using value_t = std::false_type;
2260     using type = Default;
2261 };
2262 
2263 template<class Default, template<class...> class Op, class... Args>
2264 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2265 {
2266     using value_t = std::true_type;
2267     using type = Op<Args...>;
2268 };
2269 
2270 template<template<class...> class Op, class... Args>
2271 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2272 
2273 template<template<class...> class Op, class... Args>
2274 struct is_detected_lazy : is_detected<Op, Args...> { };
2275 
2276 template<template<class...> class Op, class... Args>
2277 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2278 
2279 template<class Default, template<class...> class Op, class... Args>
2280 using detected_or = detector<Default, void, Op, Args...>;
2281 
2282 template<class Default, template<class...> class Op, class... Args>
2283 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2284 
2285 template<class Expected, template<class...> class Op, class... Args>
2286 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2287 
2288 template<class To, template<class...> class Op, class... Args>
2289 using is_detected_convertible =
2290     std::is_convertible<detected_t<Op, Args...>, To>;
2291 }  // namespace detail
2292 }  // namespace nlohmann
2293 
2294 
2295 // This file contains all internal macro definitions
2296 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2297 
2298 // exclude unsupported compilers
2299 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2300     #if defined(__clang__)
2301         #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2302             #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2303         #endif
2304     #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2305         #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2306             #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2307         #endif
2308     #endif
2309 #endif
2310 
2311 // C++ language standard detection
2312 // if the user manually specified the used c++ version this is skipped
2313 #if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2314     #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2315         #define JSON_HAS_CPP_20
2316         #define JSON_HAS_CPP_17
2317         #define JSON_HAS_CPP_14
2318     #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2319         #define JSON_HAS_CPP_17
2320         #define JSON_HAS_CPP_14
2321     #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2322         #define JSON_HAS_CPP_14
2323     #endif
2324     // the cpp 11 flag is always specified because it is the minimal required version
2325     #define JSON_HAS_CPP_11
2326 #endif
2327 
2328 // disable documentation warnings on clang
2329 #if defined(__clang__)
2330     #pragma clang diagnostic push
2331     #pragma clang diagnostic ignored "-Wdocumentation"
2332     #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2333 #endif
2334 
2335 // allow to disable exceptions
2336 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2337     #define JSON_THROW(exception) throw exception
2338     #define JSON_TRY try
2339     #define JSON_CATCH(exception) catch(exception)
2340     #define JSON_INTERNAL_CATCH(exception) catch(exception)
2341 #else
2342     #include <cstdlib>
2343     #define JSON_THROW(exception) std::abort()
2344     #define JSON_TRY if(true)
2345     #define JSON_CATCH(exception) if(false)
2346     #define JSON_INTERNAL_CATCH(exception) if(false)
2347 #endif
2348 
2349 // override exception macros
2350 #if defined(JSON_THROW_USER)
2351     #undef JSON_THROW
2352     #define JSON_THROW JSON_THROW_USER
2353 #endif
2354 #if defined(JSON_TRY_USER)
2355     #undef JSON_TRY
2356     #define JSON_TRY JSON_TRY_USER
2357 #endif
2358 #if defined(JSON_CATCH_USER)
2359     #undef JSON_CATCH
2360     #define JSON_CATCH JSON_CATCH_USER
2361     #undef JSON_INTERNAL_CATCH
2362     #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2363 #endif
2364 #if defined(JSON_INTERNAL_CATCH_USER)
2365     #undef JSON_INTERNAL_CATCH
2366     #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2367 #endif
2368 
2369 // allow to override assert
2370 #if !defined(JSON_ASSERT)
2371     #include <cassert> // assert
2372     #define JSON_ASSERT(x) assert(x)
2373 #endif
2374 
2375 // allow to access some private functions (needed by the test suite)
2376 #if defined(JSON_TESTS_PRIVATE)
2377     #define JSON_PRIVATE_UNLESS_TESTED public
2378 #else
2379     #define JSON_PRIVATE_UNLESS_TESTED private
2380 #endif
2381 
2382 /*!
2383 @brief macro to briefly define a mapping between an enum and JSON
2384 @def NLOHMANN_JSON_SERIALIZE_ENUM
2385 @since version 3.4.0
2386 */
2387 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)                                            \
2388     template<typename BasicJsonType>                                                            \
2389     inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)                                   \
2390     {                                                                                           \
2391         static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
2392         static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
2393         auto it = std::find_if(std::begin(m), std::end(m),                                      \
2394                                [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool  \
2395         {                                                                                       \
2396             return ej_pair.first == e;                                                          \
2397         });                                                                                     \
2398         j = ((it != std::end(m)) ? it : std::begin(m))->second;                                 \
2399     }                                                                                           \
2400     template<typename BasicJsonType>                                                            \
2401     inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)                                 \
2402     {                                                                                           \
2403         static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");          \
2404         static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                     \
2405         auto it = std::find_if(std::begin(m), std::end(m),                                      \
2406                                [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2407         {                                                                                       \
2408             return ej_pair.second == j;                                                         \
2409         });                                                                                     \
2410         e = ((it != std::end(m)) ? it : std::begin(m))->first;                                  \
2411     }
2412 
2413 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2414 // may be removed in the future once the class is split.
2415 
2416 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \
2417     template<template<typename, typename, typename...> class ObjectType,   \
2418              template<typename, typename...> class ArrayType,              \
2419              class StringType, class BooleanType, class NumberIntegerType, \
2420              class NumberUnsignedType, class NumberFloatType,              \
2421              template<typename> class AllocatorType,                       \
2422              template<typename, typename = void> class JSONSerializer,     \
2423              class BinaryType>
2424 
2425 #define NLOHMANN_BASIC_JSON_TPL                                            \
2426     basic_json<ObjectType, ArrayType, StringType, BooleanType,             \
2427     NumberIntegerType, NumberUnsignedType, NumberFloatType,                \
2428     AllocatorType, JSONSerializer, BinaryType>
2429 
2430 // Macros to simplify conversion from/to types
2431 
2432 #define NLOHMANN_JSON_EXPAND( x ) x
2433 #define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2434 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2435         NLOHMANN_JSON_PASTE64, \
2436         NLOHMANN_JSON_PASTE63, \
2437         NLOHMANN_JSON_PASTE62, \
2438         NLOHMANN_JSON_PASTE61, \
2439         NLOHMANN_JSON_PASTE60, \
2440         NLOHMANN_JSON_PASTE59, \
2441         NLOHMANN_JSON_PASTE58, \
2442         NLOHMANN_JSON_PASTE57, \
2443         NLOHMANN_JSON_PASTE56, \
2444         NLOHMANN_JSON_PASTE55, \
2445         NLOHMANN_JSON_PASTE54, \
2446         NLOHMANN_JSON_PASTE53, \
2447         NLOHMANN_JSON_PASTE52, \
2448         NLOHMANN_JSON_PASTE51, \
2449         NLOHMANN_JSON_PASTE50, \
2450         NLOHMANN_JSON_PASTE49, \
2451         NLOHMANN_JSON_PASTE48, \
2452         NLOHMANN_JSON_PASTE47, \
2453         NLOHMANN_JSON_PASTE46, \
2454         NLOHMANN_JSON_PASTE45, \
2455         NLOHMANN_JSON_PASTE44, \
2456         NLOHMANN_JSON_PASTE43, \
2457         NLOHMANN_JSON_PASTE42, \
2458         NLOHMANN_JSON_PASTE41, \
2459         NLOHMANN_JSON_PASTE40, \
2460         NLOHMANN_JSON_PASTE39, \
2461         NLOHMANN_JSON_PASTE38, \
2462         NLOHMANN_JSON_PASTE37, \
2463         NLOHMANN_JSON_PASTE36, \
2464         NLOHMANN_JSON_PASTE35, \
2465         NLOHMANN_JSON_PASTE34, \
2466         NLOHMANN_JSON_PASTE33, \
2467         NLOHMANN_JSON_PASTE32, \
2468         NLOHMANN_JSON_PASTE31, \
2469         NLOHMANN_JSON_PASTE30, \
2470         NLOHMANN_JSON_PASTE29, \
2471         NLOHMANN_JSON_PASTE28, \
2472         NLOHMANN_JSON_PASTE27, \
2473         NLOHMANN_JSON_PASTE26, \
2474         NLOHMANN_JSON_PASTE25, \
2475         NLOHMANN_JSON_PASTE24, \
2476         NLOHMANN_JSON_PASTE23, \
2477         NLOHMANN_JSON_PASTE22, \
2478         NLOHMANN_JSON_PASTE21, \
2479         NLOHMANN_JSON_PASTE20, \
2480         NLOHMANN_JSON_PASTE19, \
2481         NLOHMANN_JSON_PASTE18, \
2482         NLOHMANN_JSON_PASTE17, \
2483         NLOHMANN_JSON_PASTE16, \
2484         NLOHMANN_JSON_PASTE15, \
2485         NLOHMANN_JSON_PASTE14, \
2486         NLOHMANN_JSON_PASTE13, \
2487         NLOHMANN_JSON_PASTE12, \
2488         NLOHMANN_JSON_PASTE11, \
2489         NLOHMANN_JSON_PASTE10, \
2490         NLOHMANN_JSON_PASTE9, \
2491         NLOHMANN_JSON_PASTE8, \
2492         NLOHMANN_JSON_PASTE7, \
2493         NLOHMANN_JSON_PASTE6, \
2494         NLOHMANN_JSON_PASTE5, \
2495         NLOHMANN_JSON_PASTE4, \
2496         NLOHMANN_JSON_PASTE3, \
2497         NLOHMANN_JSON_PASTE2, \
2498         NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2499 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2500 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2501 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2502 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2503 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2504 #define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2505 #define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2506 #define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2507 #define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2508 #define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2509 #define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2510 #define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2511 #define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2512 #define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2513 #define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2514 #define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2515 #define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2516 #define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2517 #define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2518 #define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2519 #define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2520 #define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2521 #define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2522 #define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2523 #define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2524 #define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2525 #define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2526 #define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2527 #define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2528 #define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2529 #define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2530 #define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2531 #define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2532 #define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2533 #define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2534 #define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2535 #define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2536 #define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2537 #define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2538 #define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2539 #define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2540 #define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2541 #define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2542 #define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2543 #define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2544 #define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2545 #define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2546 #define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2547 #define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2548 #define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2549 #define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2550 #define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2551 #define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2552 #define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2553 #define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2554 #define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2555 #define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2556 #define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2557 #define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2558 #define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2559 #define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2560 #define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2561 #define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2562 
2563 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2564 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2565 
2566 /*!
2567 @brief macro
2568 @def NLOHMANN_DEFINE_TYPE_INTRUSIVE
2569 @since version 3.9.0
2570 */
2571 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...)  \
2572     friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2573     friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2574 
2575 /*!
2576 @brief macro
2577 @def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE
2578 @since version 3.9.0
2579 */
2580 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...)  \
2581     inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2582     inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2583 
2584 
2585 // inspired from https://stackoverflow.com/a/26745591
2586 // allows to call any std function as if (e.g. with begin):
2587 // using std::begin; begin(x);
2588 //
2589 // it allows using the detected idiom to retrieve the return type
2590 // of such an expression
2591 #define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)                                 \
2592     namespace detail {                                                            \
2593     using std::std_name;                                                          \
2594     \
2595     template<typename... T>                                                       \
2596     using result_of_##std_name = decltype(std_name(std::declval<T>()...));        \
2597     }                                                                             \
2598     \
2599     namespace detail2 {                                                           \
2600     struct std_name##_tag                                                         \
2601     {                                                                             \
2602     };                                                                            \
2603     \
2604     template<typename... T>                                                       \
2605     std_name##_tag std_name(T&&...);                                              \
2606     \
2607     template<typename... T>                                                       \
2608     using result_of_##std_name = decltype(std_name(std::declval<T>()...));        \
2609     \
2610     template<typename... T>                                                       \
2611     struct would_call_std_##std_name                                              \
2612     {                                                                             \
2613         static constexpr auto const value = ::nlohmann::detail::                  \
2614                                             is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2615     };                                                                            \
2616     } /* namespace detail2 */ \
2617     \
2618     template<typename... T>                                                       \
2619     struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...>   \
2620     {                                                                             \
2621     }
2622 
2623 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2624     #define JSON_USE_IMPLICIT_CONVERSIONS 1
2625 #endif
2626 
2627 #if JSON_USE_IMPLICIT_CONVERSIONS
2628     #define JSON_EXPLICIT
2629 #else
2630     #define JSON_EXPLICIT explicit
2631 #endif
2632 
2633 #ifndef JSON_DIAGNOSTICS
2634     #define JSON_DIAGNOSTICS 0
2635 #endif
2636 
2637 
2638 namespace nlohmann
2639 {
2640 namespace detail
2641 {
2642 
2643 /*!
2644 @brief replace all occurrences of a substring by another string
2645 
2646 @param[in,out] s  the string to manipulate; changed so that all
2647                occurrences of @a f are replaced with @a t
2648 @param[in]     f  the substring to replace with @a t
2649 @param[in]     t  the string to replace @a f
2650 
2651 @pre The search string @a f must not be empty. **This precondition is
2652 enforced with an assertion.**
2653 
2654 @since version 2.0.0
2655 */
replace_substring(std::string & s,const std::string & f,const std::string & t)2656 inline void replace_substring(std::string& s, const std::string& f,
2657                               const std::string& t)
2658 {
2659     JSON_ASSERT(!f.empty());
2660     for (auto pos = s.find(f);                // find first occurrence of f
2661             pos != std::string::npos;         // make sure f was found
2662             s.replace(pos, f.size(), t),      // replace with t, and
2663             pos = s.find(f, pos + t.size()))  // find next occurrence of f
2664     {}
2665 }
2666 
2667 /*!
2668  * @brief string escaping as described in RFC 6901 (Sect. 4)
2669  * @param[in] s string to escape
2670  * @return    escaped string
2671  *
2672  * Note the order of escaping "~" to "~0" and "/" to "~1" is important.
2673  */
escape(std::string s)2674 inline std::string escape(std::string s)
2675 {
2676     replace_substring(s, "~", "~0");
2677     replace_substring(s, "/", "~1");
2678     return s;
2679 }
2680 
2681 /*!
2682  * @brief string unescaping as described in RFC 6901 (Sect. 4)
2683  * @param[in] s string to unescape
2684  * @return    unescaped string
2685  *
2686  * Note the order of escaping "~1" to "/" and "~0" to "~" is important.
2687  */
unescape(std::string & s)2688 static void unescape(std::string& s)
2689 {
2690     replace_substring(s, "~1", "/");
2691     replace_substring(s, "~0", "~");
2692 }
2693 
2694 } // namespace detail
2695 } // namespace nlohmann
2696 
2697 // #include <nlohmann/detail/input/position_t.hpp>
2698 
2699 
2700 #include <cstddef> // size_t
2701 
2702 namespace nlohmann
2703 {
2704 namespace detail
2705 {
2706 /// struct to capture the start position of the current token
2707 struct position_t
2708 {
2709     /// the total number of characters read
2710     std::size_t chars_read_total = 0;
2711     /// the number of characters read in the current line
2712     std::size_t chars_read_current_line = 0;
2713     /// the number of lines read
2714     std::size_t lines_read = 0;
2715 
2716     /// conversion to size_t to preserve SAX interface
operator size_tnlohmann::detail::position_t2717     constexpr operator size_t() const
2718     {
2719         return chars_read_total;
2720     }
2721 };
2722 
2723 } // namespace detail
2724 } // namespace nlohmann
2725 
2726 // #include <nlohmann/detail/macro_scope.hpp>
2727 
2728 
2729 namespace nlohmann
2730 {
2731 namespace detail
2732 {
2733 ////////////////
2734 // exceptions //
2735 ////////////////
2736 
2737 /*!
2738 @brief general exception of the @ref basic_json class
2739 
2740 This class is an extension of `std::exception` objects with a member @a id for
2741 exception ids. It is used as the base class for all exceptions thrown by the
2742 @ref basic_json class. This class can hence be used as "wildcard" to catch
2743 exceptions.
2744 
2745 Subclasses:
2746 - @ref parse_error for exceptions indicating a parse error
2747 - @ref invalid_iterator for exceptions indicating errors with iterators
2748 - @ref type_error for exceptions indicating executing a member function with
2749                   a wrong type
2750 - @ref out_of_range for exceptions indicating access out of the defined range
2751 - @ref other_error for exceptions indicating other library errors
2752 
2753 @internal
2754 @note To have nothrow-copy-constructible exceptions, we internally use
2755       `std::runtime_error` which can cope with arbitrary-length error messages.
2756       Intermediate strings are built with static functions and then passed to
2757       the actual constructor.
2758 @endinternal
2759 
2760 @liveexample{The following code shows how arbitrary library exceptions can be
2761 caught.,exception}
2762 
2763 @since version 3.0.0
2764 */
2765 class exception : public std::exception
2766 {
2767   public:
2768     /// returns the explanatory string
what() const2769     const char* what() const noexcept override
2770     {
2771         return m.what();
2772     }
2773 
2774     /// the id of the exception
2775     const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
2776 
2777   protected:
2778     JSON_HEDLEY_NON_NULL(3)
exception(int id_,const char * what_arg)2779     exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2780 
name(const std::string & ename,int id_)2781     static std::string name(const std::string& ename, int id_)
2782     {
2783         return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2784     }
2785 
2786     template<typename BasicJsonType>
diagnostics(const BasicJsonType & leaf_element)2787     static std::string diagnostics(const BasicJsonType& leaf_element)
2788     {
2789 #if JSON_DIAGNOSTICS
2790         std::vector<std::string> tokens;
2791         for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
2792         {
2793             switch (current->m_parent->type())
2794             {
2795                 case value_t::array:
2796                 {
2797                     for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
2798                     {
2799                         if (&current->m_parent->m_value.array->operator[](i) == current)
2800                         {
2801                             tokens.emplace_back(std::to_string(i));
2802                             break;
2803                         }
2804                     }
2805                     break;
2806                 }
2807 
2808                 case value_t::object:
2809                 {
2810                     for (const auto& element : *current->m_parent->m_value.object)
2811                     {
2812                         if (&element.second == current)
2813                         {
2814                             tokens.emplace_back(element.first.c_str());
2815                             break;
2816                         }
2817                     }
2818                     break;
2819                 }
2820 
2821                 case value_t::null: // LCOV_EXCL_LINE
2822                 case value_t::string: // LCOV_EXCL_LINE
2823                 case value_t::boolean: // LCOV_EXCL_LINE
2824                 case value_t::number_integer: // LCOV_EXCL_LINE
2825                 case value_t::number_unsigned: // LCOV_EXCL_LINE
2826                 case value_t::number_float: // LCOV_EXCL_LINE
2827                 case value_t::binary: // LCOV_EXCL_LINE
2828                 case value_t::discarded: // LCOV_EXCL_LINE
2829                 default:   // LCOV_EXCL_LINE
2830                     break; // LCOV_EXCL_LINE
2831             }
2832         }
2833 
2834         if (tokens.empty())
2835         {
2836             return "";
2837         }
2838 
2839         return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
2840                                      [](const std::string & a, const std::string & b)
2841         {
2842             return a + "/" + detail::escape(b);
2843         }) + ") ";
2844 #else
2845         static_cast<void>(leaf_element);
2846         return "";
2847 #endif
2848     }
2849 
2850   private:
2851     /// an exception object as storage for error messages
2852     std::runtime_error m;
2853 };
2854 
2855 /*!
2856 @brief exception indicating a parse error
2857 
2858 This exception is thrown by the library when a parse error occurs. Parse errors
2859 can occur during the deserialization of JSON text, CBOR, MessagePack, as well
2860 as when using JSON Patch.
2861 
2862 Member @a byte holds the byte index of the last read character in the input
2863 file.
2864 
2865 Exceptions have ids 1xx.
2866 
2867 name / id                      | example message | description
2868 ------------------------------ | --------------- | -------------------------
2869 json.exception.parse_error.101 | parse error at 2: unexpected end of input; expected string literal | This error indicates a syntax error while deserializing a JSON text. The error message describes that an unexpected token (character) was encountered, and the member @a byte indicates the error position.
2870 json.exception.parse_error.102 | parse error at 14: missing or wrong low surrogate | JSON uses the `\uxxxx` format to describe Unicode characters. Code points above above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.
2871 json.exception.parse_error.103 | parse error: code points above 0x10FFFF are invalid | Unicode supports code points up to 0x10FFFF. Code points above 0x10FFFF are invalid.
2872 json.exception.parse_error.104 | parse error: JSON patch must be an array of objects | [RFC 6902](https://tools.ietf.org/html/rfc6902) requires a JSON Patch document to be a JSON document that represents an array of objects.
2873 json.exception.parse_error.105 | parse error: operation must have string member 'op' | An operation of a JSON Patch document must contain exactly one "op" member, whose value indicates the operation to perform. Its value must be one of "add", "remove", "replace", "move", "copy", or "test"; other values are errors.
2874 json.exception.parse_error.106 | parse error: array index '01' must not begin with '0' | An array index in a JSON Pointer ([RFC 6901](https://tools.ietf.org/html/rfc6901)) may be `0` or any number without a leading `0`.
2875 json.exception.parse_error.107 | parse error: JSON pointer must be empty or begin with '/' - was: 'foo' | A JSON Pointer must be a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a `/` character.
2876 json.exception.parse_error.108 | parse error: escape character '~' must be followed with '0' or '1' | In a JSON Pointer, only `~0` and `~1` are valid escape sequences.
2877 json.exception.parse_error.109 | parse error: array index 'one' is not a number | A JSON Pointer array index must be a number.
2878 json.exception.parse_error.110 | parse error at 1: cannot read 2 bytes from vector | When parsing CBOR or MessagePack, the byte vector ends before the complete value has been read.
2879 json.exception.parse_error.112 | parse error at 1: error reading CBOR; last byte: 0xF8 | Not all types of CBOR or MessagePack are supported. This exception occurs if an unsupported byte was read.
2880 json.exception.parse_error.113 | parse error at 2: expected a CBOR string; last byte: 0x98 | While parsing a map key, a value that is not a string has been read.
2881 json.exception.parse_error.114 | parse error: Unsupported BSON record type 0x0F | The parsing of the corresponding BSON record type is not implemented (yet).
2882 json.exception.parse_error.115 | parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A | A UBJSON high-precision number could not be parsed.
2883 
2884 @note For an input with n bytes, 1 is the index of the first character and n+1
2885       is the index of the terminating null byte or the end of file. This also
2886       holds true when reading a byte vector (CBOR or MessagePack).
2887 
2888 @liveexample{The following code shows how a `parse_error` exception can be
2889 caught.,parse_error}
2890 
2891 @sa - @ref exception for the base class of the library exceptions
2892 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
2893 @sa - @ref type_error for exceptions indicating executing a member function with
2894                     a wrong type
2895 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2896 @sa - @ref other_error for exceptions indicating other library errors
2897 
2898 @since version 3.0.0
2899 */
2900 class parse_error : public exception
2901 {
2902   public:
2903     /*!
2904     @brief create a parse error exception
2905     @param[in] id_       the id of the exception
2906     @param[in] pos       the position where the error occurred (or with
2907                          chars_read_total=0 if the position cannot be
2908                          determined)
2909     @param[in] what_arg  the explanatory string
2910     @return parse_error object
2911     */
2912     template<typename BasicJsonType>
create(int id_,const position_t & pos,const std::string & what_arg,const BasicJsonType & context)2913     static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
2914     {
2915         std::string w = exception::name("parse_error", id_) + "parse error" +
2916                         position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
2917         return parse_error(id_, pos.chars_read_total, w.c_str());
2918     }
2919 
2920     template<typename BasicJsonType>
create(int id_,std::size_t byte_,const std::string & what_arg,const BasicJsonType & context)2921     static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
2922     {
2923         std::string w = exception::name("parse_error", id_) + "parse error" +
2924                         (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2925                         ": " + exception::diagnostics(context) + what_arg;
2926         return parse_error(id_, byte_, w.c_str());
2927     }
2928 
2929     /*!
2930     @brief byte index of the parse error
2931 
2932     The byte index of the last read character in the input file.
2933 
2934     @note For an input with n bytes, 1 is the index of the first character and
2935           n+1 is the index of the terminating null byte or the end of file.
2936           This also holds true when reading a byte vector (CBOR or MessagePack).
2937     */
2938     const std::size_t byte;
2939 
2940   private:
parse_error(int id_,std::size_t byte_,const char * what_arg)2941     parse_error(int id_, std::size_t byte_, const char* what_arg)
2942         : exception(id_, what_arg), byte(byte_) {}
2943 
position_string(const position_t & pos)2944     static std::string position_string(const position_t& pos)
2945     {
2946         return " at line " + std::to_string(pos.lines_read + 1) +
2947                ", column " + std::to_string(pos.chars_read_current_line);
2948     }
2949 };
2950 
2951 /*!
2952 @brief exception indicating errors with iterators
2953 
2954 This exception is thrown if iterators passed to a library function do not match
2955 the expected semantics.
2956 
2957 Exceptions have ids 2xx.
2958 
2959 name / id                           | example message | description
2960 ----------------------------------- | --------------- | -------------------------
2961 json.exception.invalid_iterator.201 | iterators are not compatible | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
2962 json.exception.invalid_iterator.202 | iterator does not fit current value | In an erase or insert function, the passed iterator @a pos does not belong to the JSON value for which the function was called. It hence does not define a valid position for the deletion/insertion.
2963 json.exception.invalid_iterator.203 | iterators do not fit current value | Either iterator passed to function @ref erase(IteratorType first, IteratorType last) does not belong to the JSON value from which values shall be erased. It hence does not define a valid range to delete values from.
2964 json.exception.invalid_iterator.204 | iterators out of range | When an iterator range for a primitive type (number, boolean, or string) is passed to a constructor or an erase function, this range has to be exactly (@ref begin(), @ref end()), because this is the only way the single stored value is expressed. All other ranges are invalid.
2965 json.exception.invalid_iterator.205 | iterator out of range | When an iterator for a primitive type (number, boolean, or string) is passed to an erase function, the iterator has to be the @ref begin() iterator, because it is the only way to address the stored value. All other iterators are invalid.
2966 json.exception.invalid_iterator.206 | cannot construct with iterators from null | The iterators passed to constructor @ref basic_json(InputIT first, InputIT last) belong to a JSON null value and hence to not define a valid range.
2967 json.exception.invalid_iterator.207 | cannot use key() for non-object iterators | The key() member function can only be used on iterators belonging to a JSON object, because other types do not have a concept of a key.
2968 json.exception.invalid_iterator.208 | cannot use operator[] for object iterators | The operator[] to specify a concrete offset cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
2969 json.exception.invalid_iterator.209 | cannot use offsets with object iterators | The offset operators (+, -, +=, -=) cannot be used on iterators belonging to a JSON object, because JSON objects are unordered.
2970 json.exception.invalid_iterator.210 | iterators do not fit | The iterator range passed to the insert function are not compatible, meaning they do not belong to the same container. Therefore, the range (@a first, @a last) is invalid.
2971 json.exception.invalid_iterator.211 | passed iterators may not belong to container | The iterator range passed to the insert function must not be a subrange of the container to insert to.
2972 json.exception.invalid_iterator.212 | cannot compare iterators of different containers | When two iterators are compared, they must belong to the same container.
2973 json.exception.invalid_iterator.213 | cannot compare order of object iterators | The order of object iterators cannot be compared, because JSON objects are unordered.
2974 json.exception.invalid_iterator.214 | cannot get value | Cannot get value for iterator: Either the iterator belongs to a null value or it is an iterator to a primitive type (number, boolean, or string), but the iterator is different to @ref begin().
2975 
2976 @liveexample{The following code shows how an `invalid_iterator` exception can be
2977 caught.,invalid_iterator}
2978 
2979 @sa - @ref exception for the base class of the library exceptions
2980 @sa - @ref parse_error for exceptions indicating a parse error
2981 @sa - @ref type_error for exceptions indicating executing a member function with
2982                     a wrong type
2983 @sa - @ref out_of_range for exceptions indicating access out of the defined range
2984 @sa - @ref other_error for exceptions indicating other library errors
2985 
2986 @since version 3.0.0
2987 */
2988 class invalid_iterator : public exception
2989 {
2990   public:
2991     template<typename BasicJsonType>
create(int id_,const std::string & what_arg,const BasicJsonType & context)2992     static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
2993     {
2994         std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
2995         return invalid_iterator(id_, w.c_str());
2996     }
2997 
2998   private:
2999     JSON_HEDLEY_NON_NULL(3)
invalid_iterator(int id_,const char * what_arg)3000     invalid_iterator(int id_, const char* what_arg)
3001         : exception(id_, what_arg) {}
3002 };
3003 
3004 /*!
3005 @brief exception indicating executing a member function with a wrong type
3006 
3007 This exception is thrown in case of a type error; that is, a library function is
3008 executed on a JSON value whose type does not match the expected semantics.
3009 
3010 Exceptions have ids 3xx.
3011 
3012 name / id                     | example message | description
3013 ----------------------------- | --------------- | -------------------------
3014 json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead.
3015 json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types.
3016 json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &.
3017 json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types.
3018 json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types.
3019 json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types.
3020 json.exception.type_error.307 | cannot use erase() with string | The @ref erase() member functions can only be executed for certain JSON types.
3021 json.exception.type_error.308 | cannot use push_back() with string | The @ref push_back() and @ref operator+= member functions can only be executed for certain JSON types.
3022 json.exception.type_error.309 | cannot use insert() with | The @ref insert() member functions can only be executed for certain JSON types.
3023 json.exception.type_error.310 | cannot use swap() with number | The @ref swap() member functions can only be executed for certain JSON types.
3024 json.exception.type_error.311 | cannot use emplace_back() with string | The @ref emplace_back() member function can only be executed for certain JSON types.
3025 json.exception.type_error.312 | cannot use update() with string | The @ref update() member functions can only be executed for certain JSON types.
3026 json.exception.type_error.313 | invalid value to unflatten | The @ref unflatten function converts an object whose keys are JSON Pointers back into an arbitrary nested JSON value. The JSON Pointers must not overlap, because then the resulting value would not be well defined.
3027 json.exception.type_error.314 | only objects can be unflattened | The @ref unflatten function only works for an object whose keys are JSON Pointers.
3028 json.exception.type_error.315 | values in object must be primitive | The @ref unflatten function only works for an object whose keys are JSON Pointers and whose values are primitive.
3029 json.exception.type_error.316 | invalid UTF-8 byte at index 10: 0x7E | The @ref dump function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. |
3030 json.exception.type_error.317 | JSON value cannot be serialized to requested format | The dynamic type of the object cannot be represented in the requested serialization format (e.g. a raw `true` or `null` JSON object cannot be serialized to BSON) |
3031 
3032 @liveexample{The following code shows how a `type_error` exception can be
3033 caught.,type_error}
3034 
3035 @sa - @ref exception for the base class of the library exceptions
3036 @sa - @ref parse_error for exceptions indicating a parse error
3037 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
3038 @sa - @ref out_of_range for exceptions indicating access out of the defined range
3039 @sa - @ref other_error for exceptions indicating other library errors
3040 
3041 @since version 3.0.0
3042 */
3043 class type_error : public exception
3044 {
3045   public:
3046     template<typename BasicJsonType>
create(int id_,const std::string & what_arg,const BasicJsonType & context)3047     static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3048     {
3049         std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
3050         return type_error(id_, w.c_str());
3051     }
3052 
3053   private:
3054     JSON_HEDLEY_NON_NULL(3)
type_error(int id_,const char * what_arg)3055     type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3056 };
3057 
3058 /*!
3059 @brief exception indicating access out of the defined range
3060 
3061 This exception is thrown in case a library function is called on an input
3062 parameter that exceeds the expected range, for instance in case of array
3063 indices or nonexisting object keys.
3064 
3065 Exceptions have ids 4xx.
3066 
3067 name / id                       | example message | description
3068 ------------------------------- | --------------- | -------------------------
3069 json.exception.out_of_range.401 | array index 3 is out of range | The provided array index @a i is larger than @a size-1.
3070 json.exception.out_of_range.402 | array index '-' (3) is out of range | The special array index `-` in a JSON Pointer never describes a valid element of the array, but the index past the end. That is, it can only be used to add elements at this position, but not to read it.
3071 json.exception.out_of_range.403 | key 'foo' not found | The provided key was not found in the JSON object.
3072 json.exception.out_of_range.404 | unresolved reference token 'foo' | A reference token in a JSON Pointer could not be resolved.
3073 json.exception.out_of_range.405 | JSON pointer has no parent | The JSON Patch operations 'remove' and 'add' can not be applied to the root element of the JSON value.
3074 json.exception.out_of_range.406 | number overflow parsing '10E1000' | A parsed number could not be stored as without changing it to NaN or INF.
3075 json.exception.out_of_range.407 | number overflow serializing '9223372036854775808' | UBJSON and BSON only support integer numbers up to 9223372036854775807. (until version 3.8.0) |
3076 json.exception.out_of_range.408 | excessive array size: 8658170730974374167 | The size (following `#`) of an UBJSON array or object exceeds the maximal capacity. |
3077 json.exception.out_of_range.409 | BSON key cannot contain code point U+0000 (at byte 2) | Key identifiers to be serialized to BSON cannot contain code point U+0000, since the key is stored as zero-terminated c-string |
3078 
3079 @liveexample{The following code shows how an `out_of_range` exception can be
3080 caught.,out_of_range}
3081 
3082 @sa - @ref exception for the base class of the library exceptions
3083 @sa - @ref parse_error for exceptions indicating a parse error
3084 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
3085 @sa - @ref type_error for exceptions indicating executing a member function with
3086                     a wrong type
3087 @sa - @ref other_error for exceptions indicating other library errors
3088 
3089 @since version 3.0.0
3090 */
3091 class out_of_range : public exception
3092 {
3093   public:
3094     template<typename BasicJsonType>
create(int id_,const std::string & what_arg,const BasicJsonType & context)3095     static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
3096     {
3097         std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
3098         return out_of_range(id_, w.c_str());
3099     }
3100 
3101   private:
3102     JSON_HEDLEY_NON_NULL(3)
out_of_range(int id_,const char * what_arg)3103     out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
3104 };
3105 
3106 /*!
3107 @brief exception indicating other library errors
3108 
3109 This exception is thrown in case of errors that cannot be classified with the
3110 other exception types.
3111 
3112 Exceptions have ids 5xx.
3113 
3114 name / id                      | example message | description
3115 ------------------------------ | --------------- | -------------------------
3116 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
3117 
3118 @sa - @ref exception for the base class of the library exceptions
3119 @sa - @ref parse_error for exceptions indicating a parse error
3120 @sa - @ref invalid_iterator for exceptions indicating errors with iterators
3121 @sa - @ref type_error for exceptions indicating executing a member function with
3122                     a wrong type
3123 @sa - @ref out_of_range for exceptions indicating access out of the defined range
3124 
3125 @liveexample{The following code shows how an `other_error` exception can be
3126 caught.,other_error}
3127 
3128 @since version 3.0.0
3129 */
3130 class other_error : public exception
3131 {
3132   public:
3133     template<typename BasicJsonType>
create(int id_,const std::string & what_arg,const BasicJsonType & context)3134     static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3135     {
3136         std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
3137         return other_error(id_, w.c_str());
3138     }
3139 
3140   private:
3141     JSON_HEDLEY_NON_NULL(3)
other_error(int id_,const char * what_arg)3142     other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3143 };
3144 }  // namespace detail
3145 }  // namespace nlohmann
3146 
3147 // #include <nlohmann/detail/macro_scope.hpp>
3148 
3149 // #include <nlohmann/detail/meta/cpp_future.hpp>
3150 
3151 
3152 #include <cstddef> // size_t
3153 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3154 #include <utility> // index_sequence, make_index_sequence, index_sequence_for
3155 
3156 // #include <nlohmann/detail/macro_scope.hpp>
3157 
3158 
3159 namespace nlohmann
3160 {
3161 namespace detail
3162 {
3163 
3164 template<typename T>
3165 using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3166 
3167 #ifdef JSON_HAS_CPP_14
3168 
3169 // the following utilities are natively available in C++14
3170 using std::enable_if_t;
3171 using std::index_sequence;
3172 using std::make_index_sequence;
3173 using std::index_sequence_for;
3174 
3175 #else
3176 
3177 // alias templates to reduce boilerplate
3178 template<bool B, typename T = void>
3179 using enable_if_t = typename std::enable_if<B, T>::type;
3180 
3181 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3182 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3183 
3184 //// START OF CODE FROM GOOGLE ABSEIL
3185 
3186 // integer_sequence
3187 //
3188 // Class template representing a compile-time integer sequence. An instantiation
3189 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3190 // type through its template arguments (which is a common need when
3191 // working with C++11 variadic templates). `absl::integer_sequence` is designed
3192 // to be a drop-in replacement for C++14's `std::integer_sequence`.
3193 //
3194 // Example:
3195 //
3196 //   template< class T, T... Ints >
3197 //   void user_function(integer_sequence<T, Ints...>);
3198 //
3199 //   int main()
3200 //   {
3201 //     // user_function's `T` will be deduced to `int` and `Ints...`
3202 //     // will be deduced to `0, 1, 2, 3, 4`.
3203 //     user_function(make_integer_sequence<int, 5>());
3204 //   }
3205 template <typename T, T... Ints>
3206 struct integer_sequence
3207 {
3208     using value_type = T;
sizenlohmann::detail::integer_sequence3209     static constexpr std::size_t size() noexcept
3210     {
3211         return sizeof...(Ints);
3212     }
3213 };
3214 
3215 // index_sequence
3216 //
3217 // A helper template for an `integer_sequence` of `size_t`,
3218 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3219 // `std::index_sequence`.
3220 template <size_t... Ints>
3221 using index_sequence = integer_sequence<size_t, Ints...>;
3222 
3223 namespace utility_internal
3224 {
3225 
3226 template <typename Seq, size_t SeqSize, size_t Rem>
3227 struct Extend;
3228 
3229 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3230 template <typename T, T... Ints, size_t SeqSize>
3231 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3232 {
3233     using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3234 };
3235 
3236 template <typename T, T... Ints, size_t SeqSize>
3237 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3238 {
3239     using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3240 };
3241 
3242 // Recursion helper for 'make_integer_sequence<T, N>'.
3243 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3244 template <typename T, size_t N>
3245 struct Gen
3246 {
3247     using type =
3248         typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3249 };
3250 
3251 template <typename T>
3252 struct Gen<T, 0>
3253 {
3254     using type = integer_sequence<T>;
3255 };
3256 
3257 }  // namespace utility_internal
3258 
3259 // Compile-time sequences of integers
3260 
3261 // make_integer_sequence
3262 //
3263 // This template alias is equivalent to
3264 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3265 // replacement for C++14's `std::make_integer_sequence`.
3266 template <typename T, T N>
3267 using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
3268 
3269 // make_index_sequence
3270 //
3271 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3272 // and is designed to be a drop-in replacement for C++14's
3273 // `std::make_index_sequence`.
3274 template <size_t N>
3275 using make_index_sequence = make_integer_sequence<size_t, N>;
3276 
3277 // index_sequence_for
3278 //
3279 // Converts a typename pack into an index sequence of the same length, and
3280 // is designed to be a drop-in replacement for C++14's
3281 // `std::index_sequence_for()`
3282 template <typename... Ts>
3283 using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
3284 
3285 //// END OF CODE FROM GOOGLE ABSEIL
3286 
3287 #endif
3288 
3289 // dispatch utility (taken from ranges-v3)
3290 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3291 template<> struct priority_tag<0> {};
3292 
3293 // taken from ranges-v3
3294 template<typename T>
3295 struct static_const
3296 {
3297     static constexpr T value{};
3298 };
3299 
3300 template<typename T>
3301 constexpr T static_const<T>::value;
3302 
3303 }  // namespace detail
3304 }  // namespace nlohmann
3305 
3306 // #include <nlohmann/detail/meta/identity_tag.hpp>
3307 
3308 
3309 namespace nlohmann
3310 {
3311 namespace detail
3312 {
3313 // dispatching helper struct
3314 template <class T> struct identity_tag {};
3315 }  // namespace detail
3316 }  // namespace nlohmann
3317 
3318 // #include <nlohmann/detail/meta/type_traits.hpp>
3319 
3320 
3321 #include <limits> // numeric_limits
3322 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3323 #include <utility> // declval
3324 #include <tuple> // tuple
3325 
3326 // #include <nlohmann/detail/macro_scope.hpp>
3327 
3328 
3329 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3330 
3331 
3332 #include <iterator> // random_access_iterator_tag
3333 
3334 // #include <nlohmann/detail/meta/void_t.hpp>
3335 
3336 // #include <nlohmann/detail/meta/cpp_future.hpp>
3337 
3338 
3339 namespace nlohmann
3340 {
3341 namespace detail
3342 {
3343 template<typename It, typename = void>
3344 struct iterator_types {};
3345 
3346 template<typename It>
3347 struct iterator_types <
3348     It,
3349     void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3350     typename It::reference, typename It::iterator_category >>
3351 {
3352     using difference_type = typename It::difference_type;
3353     using value_type = typename It::value_type;
3354     using pointer = typename It::pointer;
3355     using reference = typename It::reference;
3356     using iterator_category = typename It::iterator_category;
3357 };
3358 
3359 // This is required as some compilers implement std::iterator_traits in a way that
3360 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3361 template<typename T, typename = void>
3362 struct iterator_traits
3363 {
3364 };
3365 
3366 template<typename T>
3367 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3368             : iterator_types<T>
3369 {
3370 };
3371 
3372 template<typename T>
3373 struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
3374 {
3375     using iterator_category = std::random_access_iterator_tag;
3376     using value_type = T;
3377     using difference_type = ptrdiff_t;
3378     using pointer = T*;
3379     using reference = T&;
3380 };
3381 } // namespace detail
3382 } // namespace nlohmann
3383 
3384 // #include <nlohmann/detail/meta/call_std/begin.hpp>
3385 
3386 
3387 // #include <nlohmann/detail/macro_scope.hpp>
3388 
3389 
3390 namespace nlohmann
3391 {
3392 NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin);
3393 } // namespace nlohmann
3394 
3395 // #include <nlohmann/detail/meta/call_std/end.hpp>
3396 
3397 
3398 // #include <nlohmann/detail/macro_scope.hpp>
3399 
3400 
3401 namespace nlohmann
3402 {
3403 NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end);
3404 }  // namespace nlohmann
3405 
3406 // #include <nlohmann/detail/meta/cpp_future.hpp>
3407 
3408 // #include <nlohmann/detail/meta/detected.hpp>
3409 
3410 // #include <nlohmann/json_fwd.hpp>
3411 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3412 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3413 
3414 #include <cstdint> // int64_t, uint64_t
3415 #include <map> // map
3416 #include <memory> // allocator
3417 #include <string> // string
3418 #include <vector> // vector
3419 
3420 /*!
3421 @brief namespace for Niels Lohmann
3422 @see https://github.com/nlohmann
3423 @since version 1.0.0
3424 */
3425 namespace nlohmann
3426 {
3427 /*!
3428 @brief default JSONSerializer template argument
3429 
3430 This serializer ignores the template arguments and uses ADL
3431 ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl))
3432 for serialization.
3433 */
3434 template<typename T = void, typename SFINAE = void>
3435 struct adl_serializer;
3436 
3437 template<template<typename U, typename V, typename... Args> class ObjectType =
3438          std::map,
3439          template<typename U, typename... Args> class ArrayType = std::vector,
3440          class StringType = std::string, class BooleanType = bool,
3441          class NumberIntegerType = std::int64_t,
3442          class NumberUnsignedType = std::uint64_t,
3443          class NumberFloatType = double,
3444          template<typename U> class AllocatorType = std::allocator,
3445          template<typename T, typename SFINAE = void> class JSONSerializer =
3446          adl_serializer,
3447          class BinaryType = std::vector<std::uint8_t>>
3448 class basic_json;
3449 
3450 /*!
3451 @brief JSON Pointer
3452 
3453 A JSON pointer defines a string syntax for identifying a specific value
3454 within a JSON document. It can be used with functions `at` and
3455 `operator[]`. Furthermore, JSON pointers are the base for JSON patches.
3456 
3457 @sa [RFC 6901](https://tools.ietf.org/html/rfc6901)
3458 
3459 @since version 2.0.0
3460 */
3461 template<typename BasicJsonType>
3462 class json_pointer;
3463 
3464 /*!
3465 @brief default JSON class
3466 
3467 This type is the default specialization of the @ref basic_json class which
3468 uses the standard template types.
3469 
3470 @since version 1.0.0
3471 */
3472 using json = basic_json<>;
3473 
3474 template<class Key, class T, class IgnoredLess, class Allocator>
3475 struct ordered_map;
3476 
3477 /*!
3478 @brief ordered JSON class
3479 
3480 This type preserves the insertion order of object keys.
3481 
3482 @since version 3.9.0
3483 */
3484 using ordered_json = basic_json<nlohmann::ordered_map>;
3485 
3486 }  // namespace nlohmann
3487 
3488 #endif  // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3489 
3490 
3491 namespace nlohmann
3492 {
3493 /*!
3494 @brief detail namespace with internal helper functions
3495 
3496 This namespace collects functions that should not be exposed,
3497 implementations of some @ref basic_json methods, and meta-programming helpers.
3498 
3499 @since version 2.1.0
3500 */
3501 namespace detail
3502 {
3503 /////////////
3504 // helpers //
3505 /////////////
3506 
3507 // Note to maintainers:
3508 //
3509 // Every trait in this file expects a non CV-qualified type.
3510 // The only exceptions are in the 'aliases for detected' section
3511 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3512 //
3513 // In this case, T has to be properly CV-qualified to constraint the function arguments
3514 // (e.g. to_json(BasicJsonType&, const T&))
3515 
3516 template<typename> struct is_basic_json : std::false_type {};
3517 
3518 NLOHMANN_BASIC_JSON_TPL_DECLARATION
3519 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3520 
3521 //////////////////////
3522 // json_ref helpers //
3523 //////////////////////
3524 
3525 template<typename>
3526 class json_ref;
3527 
3528 template<typename>
3529 struct is_json_ref : std::false_type {};
3530 
3531 template<typename T>
3532 struct is_json_ref<json_ref<T>> : std::true_type {};
3533 
3534 //////////////////////////
3535 // aliases for detected //
3536 //////////////////////////
3537 
3538 template<typename T>
3539 using mapped_type_t = typename T::mapped_type;
3540 
3541 template<typename T>
3542 using key_type_t = typename T::key_type;
3543 
3544 template<typename T>
3545 using value_type_t = typename T::value_type;
3546 
3547 template<typename T>
3548 using difference_type_t = typename T::difference_type;
3549 
3550 template<typename T>
3551 using pointer_t = typename T::pointer;
3552 
3553 template<typename T>
3554 using reference_t = typename T::reference;
3555 
3556 template<typename T>
3557 using iterator_category_t = typename T::iterator_category;
3558 
3559 template<typename T, typename... Args>
3560 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3561 
3562 template<typename T, typename... Args>
3563 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3564 
3565 template<typename T, typename U>
3566 using get_template_function = decltype(std::declval<T>().template get<U>());
3567 
3568 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3569 template<typename BasicJsonType, typename T, typename = void>
3570 struct has_from_json : std::false_type {};
3571 
3572 // trait checking if j.get<T> is valid
3573 // use this trait instead of std::is_constructible or std::is_convertible,
3574 // both rely on, or make use of implicit conversions, and thus fail when T
3575 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3576 template <typename BasicJsonType, typename T>
3577 struct is_getable
3578 {
3579     static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3580 };
3581 
3582 template<typename BasicJsonType, typename T>
3583 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3584 {
3585     using serializer = typename BasicJsonType::template json_serializer<T, void>;
3586 
3587     static constexpr bool value =
3588         is_detected_exact<void, from_json_function, serializer,
3589         const BasicJsonType&, T&>::value;
3590 };
3591 
3592 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3593 // this overload is used for non-default-constructible user-defined-types
3594 template<typename BasicJsonType, typename T, typename = void>
3595 struct has_non_default_from_json : std::false_type {};
3596 
3597 template<typename BasicJsonType, typename T>
3598 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3599 {
3600     using serializer = typename BasicJsonType::template json_serializer<T, void>;
3601 
3602     static constexpr bool value =
3603         is_detected_exact<T, from_json_function, serializer,
3604         const BasicJsonType&>::value;
3605 };
3606 
3607 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3608 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3609 template<typename BasicJsonType, typename T, typename = void>
3610 struct has_to_json : std::false_type {};
3611 
3612 template<typename BasicJsonType, typename T>
3613 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3614 {
3615     using serializer = typename BasicJsonType::template json_serializer<T, void>;
3616 
3617     static constexpr bool value =
3618         is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3619         T>::value;
3620 };
3621 
3622 
3623 ///////////////////
3624 // is_ functions //
3625 ///////////////////
3626 
3627 // https://en.cppreference.com/w/cpp/types/conjunction
3628 template<class...> struct conjunction : std::true_type { };
3629 template<class B1> struct conjunction<B1> : B1 { };
3630 template<class B1, class... Bn>
3631 struct conjunction<B1, Bn...>
3632 : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3633 
3634 // https://en.cppreference.com/w/cpp/types/negation
3635 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3636 
3637 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3638 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3639 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3640 template <typename T>
3641 struct is_default_constructible : std::is_default_constructible<T> {};
3642 
3643 template <typename T1, typename T2>
3644 struct is_default_constructible<std::pair<T1, T2>>
3645             : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3646 
3647 template <typename T1, typename T2>
3648 struct is_default_constructible<const std::pair<T1, T2>>
3649             : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3650 
3651 template <typename... Ts>
3652 struct is_default_constructible<std::tuple<Ts...>>
3653             : conjunction<is_default_constructible<Ts>...> {};
3654 
3655 template <typename... Ts>
3656 struct is_default_constructible<const std::tuple<Ts...>>
3657             : conjunction<is_default_constructible<Ts>...> {};
3658 
3659 
3660 template <typename T, typename... Args>
3661 struct is_constructible : std::is_constructible<T, Args...> {};
3662 
3663 template <typename T1, typename T2>
3664 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3665 
3666 template <typename T1, typename T2>
3667 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3668 
3669 template <typename... Ts>
3670 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3671 
3672 template <typename... Ts>
3673 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3674 
3675 
3676 template<typename T, typename = void>
3677 struct is_iterator_traits : std::false_type {};
3678 
3679 template<typename T>
3680 struct is_iterator_traits<iterator_traits<T>>
3681 {
3682   private:
3683     using traits = iterator_traits<T>;
3684 
3685   public:
3686     static constexpr auto value =
3687         is_detected<value_type_t, traits>::value &&
3688         is_detected<difference_type_t, traits>::value &&
3689         is_detected<pointer_t, traits>::value &&
3690         is_detected<iterator_category_t, traits>::value &&
3691         is_detected<reference_t, traits>::value;
3692 };
3693 
3694 template<typename T>
3695 struct is_range
3696 {
3697   private:
3698     using t_ref = typename std::add_lvalue_reference<T>::type;
3699 
3700     using iterator = detected_t<result_of_begin, t_ref>;
3701     using sentinel = detected_t<result_of_end, t_ref>;
3702 
3703     // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3704     // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3705     // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3706     static constexpr auto is_iterator_begin =
3707         is_iterator_traits<iterator_traits<iterator>>::value;
3708 
3709   public:
3710     static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3711 };
3712 
3713 template<typename R>
3714 using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3715 
3716 template<typename T>
3717 using range_value_t = value_type_t<iterator_traits<iterator_t<T>>>;
3718 
3719 // The following implementation of is_complete_type is taken from
3720 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3721 // and is written by Xiang Fan who agreed to using it in this library.
3722 
3723 template<typename T, typename = void>
3724 struct is_complete_type : std::false_type {};
3725 
3726 template<typename T>
3727 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3728 
3729 template<typename BasicJsonType, typename CompatibleObjectType,
3730          typename = void>
3731 struct is_compatible_object_type_impl : std::false_type {};
3732 
3733 template<typename BasicJsonType, typename CompatibleObjectType>
3734 struct is_compatible_object_type_impl <
3735     BasicJsonType, CompatibleObjectType,
3736     enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3737     is_detected<key_type_t, CompatibleObjectType>::value >>
3738 {
3739     using object_t = typename BasicJsonType::object_t;
3740 
3741     // macOS's is_constructible does not play well with nonesuch...
3742     static constexpr bool value =
3743         is_constructible<typename object_t::key_type,
3744         typename CompatibleObjectType::key_type>::value &&
3745         is_constructible<typename object_t::mapped_type,
3746         typename CompatibleObjectType::mapped_type>::value;
3747 };
3748 
3749 template<typename BasicJsonType, typename CompatibleObjectType>
3750 struct is_compatible_object_type
3751     : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3752 
3753 template<typename BasicJsonType, typename ConstructibleObjectType,
3754          typename = void>
3755 struct is_constructible_object_type_impl : std::false_type {};
3756 
3757 template<typename BasicJsonType, typename ConstructibleObjectType>
3758 struct is_constructible_object_type_impl <
3759     BasicJsonType, ConstructibleObjectType,
3760     enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3761     is_detected<key_type_t, ConstructibleObjectType>::value >>
3762 {
3763     using object_t = typename BasicJsonType::object_t;
3764 
3765     static constexpr bool value =
3766         (is_default_constructible<ConstructibleObjectType>::value &&
3767          (std::is_move_assignable<ConstructibleObjectType>::value ||
3768           std::is_copy_assignable<ConstructibleObjectType>::value) &&
3769          (is_constructible<typename ConstructibleObjectType::key_type,
3770           typename object_t::key_type>::value &&
3771           std::is_same <
3772           typename object_t::mapped_type,
3773           typename ConstructibleObjectType::mapped_type >::value)) ||
3774         (has_from_json<BasicJsonType,
3775          typename ConstructibleObjectType::mapped_type>::value ||
3776          has_non_default_from_json <
3777          BasicJsonType,
3778          typename ConstructibleObjectType::mapped_type >::value);
3779 };
3780 
3781 template<typename BasicJsonType, typename ConstructibleObjectType>
3782 struct is_constructible_object_type
3783     : is_constructible_object_type_impl<BasicJsonType,
3784       ConstructibleObjectType> {};
3785 
3786 template<typename BasicJsonType, typename CompatibleStringType>
3787 struct is_compatible_string_type
3788 {
3789     static constexpr auto value =
3790         is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3791 };
3792 
3793 template<typename BasicJsonType, typename ConstructibleStringType>
3794 struct is_constructible_string_type
3795 {
3796     static constexpr auto value =
3797         is_constructible<ConstructibleStringType,
3798         typename BasicJsonType::string_t>::value;
3799 };
3800 
3801 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3802 struct is_compatible_array_type_impl : std::false_type {};
3803 
3804 template<typename BasicJsonType, typename CompatibleArrayType>
3805 struct is_compatible_array_type_impl <
3806     BasicJsonType, CompatibleArrayType,
3807     enable_if_t <
3808     is_detected<iterator_t, CompatibleArrayType>::value&&
3809     is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
3810 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3811 // c.f. https://github.com/nlohmann/json/pull/3073
3812     !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3813 {
3814     static constexpr bool value =
3815         is_constructible<BasicJsonType,
3816         range_value_t<CompatibleArrayType>>::value;
3817 };
3818 
3819 template<typename BasicJsonType, typename CompatibleArrayType>
3820 struct is_compatible_array_type
3821     : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3822 
3823 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3824 struct is_constructible_array_type_impl : std::false_type {};
3825 
3826 template<typename BasicJsonType, typename ConstructibleArrayType>
3827 struct is_constructible_array_type_impl <
3828     BasicJsonType, ConstructibleArrayType,
3829     enable_if_t<std::is_same<ConstructibleArrayType,
3830     typename BasicJsonType::value_type>::value >>
3831             : std::true_type {};
3832 
3833 template<typename BasicJsonType, typename ConstructibleArrayType>
3834 struct is_constructible_array_type_impl <
3835     BasicJsonType, ConstructibleArrayType,
3836     enable_if_t < !std::is_same<ConstructibleArrayType,
3837     typename BasicJsonType::value_type>::value&&
3838     !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3839     is_default_constructible<ConstructibleArrayType>::value&&
3840 (std::is_move_assignable<ConstructibleArrayType>::value ||
3841  std::is_copy_assignable<ConstructibleArrayType>::value)&&
3842 is_detected<iterator_t, ConstructibleArrayType>::value&&
3843 is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3844 is_detected<range_value_t, ConstructibleArrayType>::value&&
3845 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3846 // c.f. https://github.com/nlohmann/json/pull/3073
3847 !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3848         is_complete_type <
3849         detected_t<range_value_t, ConstructibleArrayType >>::value >>
3850 {
3851     using value_type = range_value_t<ConstructibleArrayType>;
3852 
3853     static constexpr bool value =
3854         std::is_same<value_type,
3855         typename BasicJsonType::array_t::value_type>::value ||
3856         has_from_json<BasicJsonType,
3857         value_type>::value ||
3858         has_non_default_from_json <
3859         BasicJsonType,
3860         value_type >::value;
3861 };
3862 
3863 template<typename BasicJsonType, typename ConstructibleArrayType>
3864 struct is_constructible_array_type
3865     : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3866 
3867 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3868          typename = void>
3869 struct is_compatible_integer_type_impl : std::false_type {};
3870 
3871 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3872 struct is_compatible_integer_type_impl <
3873     RealIntegerType, CompatibleNumberIntegerType,
3874     enable_if_t < std::is_integral<RealIntegerType>::value&&
3875     std::is_integral<CompatibleNumberIntegerType>::value&&
3876     !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3877 {
3878     // is there an assert somewhere on overflows?
3879     using RealLimits = std::numeric_limits<RealIntegerType>;
3880     using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3881 
3882     static constexpr auto value =
3883         is_constructible<RealIntegerType,
3884         CompatibleNumberIntegerType>::value &&
3885         CompatibleLimits::is_integer &&
3886         RealLimits::is_signed == CompatibleLimits::is_signed;
3887 };
3888 
3889 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3890 struct is_compatible_integer_type
3891     : is_compatible_integer_type_impl<RealIntegerType,
3892       CompatibleNumberIntegerType> {};
3893 
3894 template<typename BasicJsonType, typename CompatibleType, typename = void>
3895 struct is_compatible_type_impl: std::false_type {};
3896 
3897 template<typename BasicJsonType, typename CompatibleType>
3898 struct is_compatible_type_impl <
3899     BasicJsonType, CompatibleType,
3900     enable_if_t<is_complete_type<CompatibleType>::value >>
3901 {
3902     static constexpr bool value =
3903         has_to_json<BasicJsonType, CompatibleType>::value;
3904 };
3905 
3906 template<typename BasicJsonType, typename CompatibleType>
3907 struct is_compatible_type
3908     : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3909 
3910 template<typename T1, typename T2>
3911 struct is_constructible_tuple : std::false_type {};
3912 
3913 template<typename T1, typename... Args>
3914 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3915 
3916 // a naive helper to check if a type is an ordered_map (exploits the fact that
3917 // ordered_map inherits capacity() from std::vector)
3918 template <typename T>
3919 struct is_ordered_map
3920 {
3921     using one = char;
3922 
3923     struct two
3924     {
3925         char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3926     };
3927 
3928     template <typename C> static one test( decltype(&C::capacity) ) ;
3929     template <typename C> static two test(...);
3930 
3931     enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3932 };
3933 
3934 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3935 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3936 T conditional_static_cast(U value)
3937 {
3938     return static_cast<T>(value);
3939 }
3940 
3941 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3942 T conditional_static_cast(U value)
3943 {
3944     return value;
3945 }
3946 
3947 }  // namespace detail
3948 }  // namespace nlohmann
3949 
3950 // #include <nlohmann/detail/value_t.hpp>
3951 
3952 
3953 #ifdef JSON_HAS_CPP_17
3954     #include <filesystem>
3955 #endif
3956 
3957 namespace nlohmann
3958 {
3959 namespace detail
3960 {
3961 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename std::nullptr_t & n)3962 void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3963 {
3964     if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3965     {
3966         JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
3967     }
3968     n = nullptr;
3969 }
3970 
3971 // overloads for basic_json template parameters
3972 template < typename BasicJsonType, typename ArithmeticType,
3973            enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3974                          !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3975                          int > = 0 >
get_arithmetic_value(const BasicJsonType & j,ArithmeticType & val)3976 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3977 {
3978     switch (static_cast<value_t>(j))
3979     {
3980         case value_t::number_unsigned:
3981         {
3982             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3983             break;
3984         }
3985         case value_t::number_integer:
3986         {
3987             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3988             break;
3989         }
3990         case value_t::number_float:
3991         {
3992             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3993             break;
3994         }
3995 
3996         case value_t::null:
3997         case value_t::object:
3998         case value_t::array:
3999         case value_t::string:
4000         case value_t::boolean:
4001         case value_t::binary:
4002         case value_t::discarded:
4003         default:
4004             JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4005     }
4006 }
4007 
4008 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::boolean_t & b)4009 void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4010 {
4011     if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4012     {
4013         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
4014     }
4015     b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4016 }
4017 
4018 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::string_t & s)4019 void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4020 {
4021     if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4022     {
4023         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4024     }
4025     s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4026 }
4027 
4028 template <
4029     typename BasicJsonType, typename ConstructibleStringType,
4030     enable_if_t <
4031         is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
4032         !std::is_same<typename BasicJsonType::string_t,
4033                       ConstructibleStringType>::value,
4034         int > = 0 >
from_json(const BasicJsonType & j,ConstructibleStringType & s)4035 void from_json(const BasicJsonType& j, ConstructibleStringType& s)
4036 {
4037     if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4038     {
4039         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4040     }
4041 
4042     s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4043 }
4044 
4045 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_float_t & val)4046 void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4047 {
4048     get_arithmetic_value(j, val);
4049 }
4050 
4051 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_unsigned_t & val)4052 void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4053 {
4054     get_arithmetic_value(j, val);
4055 }
4056 
4057 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::number_integer_t & val)4058 void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4059 {
4060     get_arithmetic_value(j, val);
4061 }
4062 
4063 template<typename BasicJsonType, typename EnumType,
4064          enable_if_t<std::is_enum<EnumType>::value, int> = 0>
from_json(const BasicJsonType & j,EnumType & e)4065 void from_json(const BasicJsonType& j, EnumType& e)
4066 {
4067     typename std::underlying_type<EnumType>::type val;
4068     get_arithmetic_value(j, val);
4069     e = static_cast<EnumType>(val);
4070 }
4071 
4072 // forward_list doesn't have an insert method
4073 template<typename BasicJsonType, typename T, typename Allocator,
4074          enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::forward_list<T,Allocator> & l)4075 void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4076 {
4077     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4078     {
4079         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4080     }
4081     l.clear();
4082     std::transform(j.rbegin(), j.rend(),
4083                    std::front_inserter(l), [](const BasicJsonType & i)
4084     {
4085         return i.template get<T>();
4086     });
4087 }
4088 
4089 // valarray doesn't have an insert method
4090 template<typename BasicJsonType, typename T,
4091          enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
from_json(const BasicJsonType & j,std::valarray<T> & l)4092 void from_json(const BasicJsonType& j, std::valarray<T>& l)
4093 {
4094     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4095     {
4096         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4097     }
4098     l.resize(j.size());
4099     std::transform(j.begin(), j.end(), std::begin(l),
4100                    [](const BasicJsonType & elem)
4101     {
4102         return elem.template get<T>();
4103     });
4104 }
4105 
4106 template<typename BasicJsonType, typename T, std::size_t N>
from_json(const BasicJsonType & j,T (& arr)[N])4107 auto from_json(const BasicJsonType& j, T (&arr)[N])  // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4108 -> decltype(j.template get<T>(), void())
4109 {
4110     for (std::size_t i = 0; i < N; ++i)
4111     {
4112         arr[i] = j.at(i).template get<T>();
4113     }
4114 }
4115 
4116 template<typename BasicJsonType>
from_json_array_impl(const BasicJsonType & j,typename BasicJsonType::array_t & arr,priority_tag<3>)4117 void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4118 {
4119     arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4120 }
4121 
4122 template<typename BasicJsonType, typename T, std::size_t N>
from_json_array_impl(const BasicJsonType & j,std::array<T,N> & arr,priority_tag<2>)4123 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4124                           priority_tag<2> /*unused*/)
4125 -> decltype(j.template get<T>(), void())
4126 {
4127     for (std::size_t i = 0; i < N; ++i)
4128     {
4129         arr[i] = j.at(i).template get<T>();
4130     }
4131 }
4132 
4133 template<typename BasicJsonType, typename ConstructibleArrayType,
4134          enable_if_t<
4135              std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4136              int> = 0>
from_json_array_impl(const BasicJsonType & j,ConstructibleArrayType & arr,priority_tag<1>)4137 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4138 -> decltype(
4139     arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4140     j.template get<typename ConstructibleArrayType::value_type>(),
4141     void())
4142 {
4143     using std::end;
4144 
4145     ConstructibleArrayType ret;
4146     ret.reserve(j.size());
4147     std::transform(j.begin(), j.end(),
4148                    std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4149     {
4150         // get<BasicJsonType>() returns *this, this won't call a from_json
4151         // method when value_type is BasicJsonType
4152         return i.template get<typename ConstructibleArrayType::value_type>();
4153     });
4154     arr = std::move(ret);
4155 }
4156 
4157 template<typename BasicJsonType, typename ConstructibleArrayType,
4158          enable_if_t<
4159              std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4160              int> = 0>
from_json_array_impl(const BasicJsonType & j,ConstructibleArrayType & arr,priority_tag<0>)4161 void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4162                           priority_tag<0> /*unused*/)
4163 {
4164     using std::end;
4165 
4166     ConstructibleArrayType ret;
4167     std::transform(
4168         j.begin(), j.end(), std::inserter(ret, end(ret)),
4169         [](const BasicJsonType & i)
4170     {
4171         // get<BasicJsonType>() returns *this, this won't call a from_json
4172         // method when value_type is BasicJsonType
4173         return i.template get<typename ConstructibleArrayType::value_type>();
4174     });
4175     arr = std::move(ret);
4176 }
4177 
4178 template < typename BasicJsonType, typename ConstructibleArrayType,
4179            enable_if_t <
4180                is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4181                !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4182                !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
4183                !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4184                !is_basic_json<ConstructibleArrayType>::value,
4185                int > = 0 >
from_json(const BasicJsonType & j,ConstructibleArrayType & arr)4186 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4187 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4188 j.template get<typename ConstructibleArrayType::value_type>(),
4189 void())
4190 {
4191     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4192     {
4193         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4194     }
4195 
4196     from_json_array_impl(j, arr, priority_tag<3> {});
4197 }
4198 
4199 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...>)4200 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4201         identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4202 {
4203     return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4204 }
4205 
4206 template < typename BasicJsonType, typename T, std::size_t N >
from_json(BasicJsonType && j,identity_tag<std::array<T,N>> tag)4207 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4208 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4209 {
4210     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4211     {
4212         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4213     }
4214 
4215     return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4216 }
4217 
4218 template<typename BasicJsonType>
from_json(const BasicJsonType & j,typename BasicJsonType::binary_t & bin)4219 void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4220 {
4221     if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4222     {
4223         JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
4224     }
4225 
4226     bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4227 }
4228 
4229 template<typename BasicJsonType, typename ConstructibleObjectType,
4230          enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
from_json(const BasicJsonType & j,ConstructibleObjectType & obj)4231 void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4232 {
4233     if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4234     {
4235         JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
4236     }
4237 
4238     ConstructibleObjectType ret;
4239     const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4240     using value_type = typename ConstructibleObjectType::value_type;
4241     std::transform(
4242         inner_object->begin(), inner_object->end(),
4243         std::inserter(ret, ret.begin()),
4244         [](typename BasicJsonType::object_t::value_type const & p)
4245     {
4246         return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4247     });
4248     obj = std::move(ret);
4249 }
4250 
4251 // overload for arithmetic types, not chosen for basic_json template arguments
4252 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4253 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4254 // an arithmetic type?
4255 template < typename BasicJsonType, typename ArithmeticType,
4256            enable_if_t <
4257                std::is_arithmetic<ArithmeticType>::value&&
4258                !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4259                !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4260                !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4261                !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4262                int > = 0 >
from_json(const BasicJsonType & j,ArithmeticType & val)4263 void from_json(const BasicJsonType& j, ArithmeticType& val)
4264 {
4265     switch (static_cast<value_t>(j))
4266     {
4267         case value_t::number_unsigned:
4268         {
4269             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4270             break;
4271         }
4272         case value_t::number_integer:
4273         {
4274             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4275             break;
4276         }
4277         case value_t::number_float:
4278         {
4279             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4280             break;
4281         }
4282         case value_t::boolean:
4283         {
4284             val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4285             break;
4286         }
4287 
4288         case value_t::null:
4289         case value_t::object:
4290         case value_t::array:
4291         case value_t::string:
4292         case value_t::binary:
4293         case value_t::discarded:
4294         default:
4295             JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4296     }
4297 }
4298 
4299 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
from_json_tuple_impl_base(BasicJsonType && j,index_sequence<Idx...>)4300 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4301 {
4302     return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4303 }
4304 
4305 template < typename BasicJsonType, class A1, class A2 >
from_json_tuple_impl(BasicJsonType && j,identity_tag<std::pair<A1,A2>>,priority_tag<0>)4306 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4307 {
4308     return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4309             std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4310 }
4311 
4312 template<typename BasicJsonType, typename A1, typename A2>
from_json_tuple_impl(BasicJsonType && j,std::pair<A1,A2> & p,priority_tag<1>)4313 void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4314 {
4315     p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4316 }
4317 
4318 template<typename BasicJsonType, typename... Args>
from_json_tuple_impl(BasicJsonType && j,identity_tag<std::tuple<Args...>>,priority_tag<2>)4319 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4320 {
4321     return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4322 }
4323 
4324 template<typename BasicJsonType, typename... Args>
from_json_tuple_impl(BasicJsonType && j,std::tuple<Args...> & t,priority_tag<3>)4325 void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4326 {
4327     t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4328 }
4329 
4330 template<typename BasicJsonType, typename TupleRelated>
from_json(BasicJsonType && j,TupleRelated && t)4331 auto from_json(BasicJsonType&& j, TupleRelated&& t)
4332 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4333 {
4334     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4335     {
4336         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4337     }
4338 
4339     return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4340 }
4341 
4342 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4343            typename = enable_if_t < !std::is_constructible <
4344                                         typename BasicJsonType::string_t, Key >::value >>
from_json(const BasicJsonType & j,std::map<Key,Value,Compare,Allocator> & m)4345 void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4346 {
4347     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4348     {
4349         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4350     }
4351     m.clear();
4352     for (const auto& p : j)
4353     {
4354         if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4355         {
4356             JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4357         }
4358         m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4359     }
4360 }
4361 
4362 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4363            typename = enable_if_t < !std::is_constructible <
4364                                         typename BasicJsonType::string_t, Key >::value >>
from_json(const BasicJsonType & j,std::unordered_map<Key,Value,Hash,KeyEqual,Allocator> & m)4365 void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4366 {
4367     if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4368     {
4369         JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4370     }
4371     m.clear();
4372     for (const auto& p : j)
4373     {
4374         if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4375         {
4376             JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4377         }
4378         m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4379     }
4380 }
4381 
4382 #ifdef JSON_HAS_CPP_17
4383 template<typename BasicJsonType>
from_json(const BasicJsonType & j,std::filesystem::path & p)4384 void from_json(const BasicJsonType& j, std::filesystem::path& p)
4385 {
4386     if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4387     {
4388         JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4389     }
4390     p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4391 }
4392 #endif
4393 
4394 struct from_json_fn
4395 {
4396     template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::from_json_fn4397     auto operator()(const BasicJsonType& j, T&& val) const
4398     noexcept(noexcept(from_json(j, std::forward<T>(val))))
4399     -> decltype(from_json(j, std::forward<T>(val)))
4400     {
4401         return from_json(j, std::forward<T>(val));
4402     }
4403 };
4404 }  // namespace detail
4405 
4406 /// namespace to hold default `from_json` function
4407 /// to see why this is required:
4408 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
4409 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4410 {
4411 constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4412 } // namespace
4413 } // namespace nlohmann
4414 
4415 // #include <nlohmann/detail/conversions/to_json.hpp>
4416 
4417 
4418 #include <algorithm> // copy
4419 #include <iterator> // begin, end
4420 #include <string> // string
4421 #include <tuple> // tuple, get
4422 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4423 #include <utility> // move, forward, declval, pair
4424 #include <valarray> // valarray
4425 #include <vector> // vector
4426 
4427 // #include <nlohmann/detail/macro_scope.hpp>
4428 
4429 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4430 
4431 
4432 #include <cstddef> // size_t
4433 #include <iterator> // input_iterator_tag
4434 #include <string> // string, to_string
4435 #include <tuple> // tuple_size, get, tuple_element
4436 #include <utility> // move
4437 
4438 // #include <nlohmann/detail/meta/type_traits.hpp>
4439 
4440 // #include <nlohmann/detail/value_t.hpp>
4441 
4442 
4443 namespace nlohmann
4444 {
4445 namespace detail
4446 {
4447 template<typename string_type>
int_to_string(string_type & target,std::size_t value)4448 void int_to_string( string_type& target, std::size_t value )
4449 {
4450     // For ADL
4451     using std::to_string;
4452     target = to_string(value);
4453 }
4454 template<typename IteratorType> class iteration_proxy_value
4455 {
4456   public:
4457     using difference_type = std::ptrdiff_t;
4458     using value_type = iteration_proxy_value;
4459     using pointer = value_type * ;
4460     using reference = value_type & ;
4461     using iterator_category = std::input_iterator_tag;
4462     using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4463 
4464   private:
4465     /// the iterator
4466     IteratorType anchor;
4467     /// an index for arrays (used to create key names)
4468     std::size_t array_index = 0;
4469     /// last stringified array index
4470     mutable std::size_t array_index_last = 0;
4471     /// a string representation of the array index
4472     mutable string_type array_index_str = "0";
4473     /// an empty string (to return a reference for primitive values)
4474     const string_type empty_str{};
4475 
4476   public:
iteration_proxy_value(IteratorType it)4477     explicit iteration_proxy_value(IteratorType it) noexcept
4478         : anchor(std::move(it))
4479     {}
4480 
4481     /// dereference operator (needed for range-based for)
operator *()4482     iteration_proxy_value& operator*()
4483     {
4484         return *this;
4485     }
4486 
4487     /// increment operator (needed for range-based for)
operator ++()4488     iteration_proxy_value& operator++()
4489     {
4490         ++anchor;
4491         ++array_index;
4492 
4493         return *this;
4494     }
4495 
4496     /// equality operator (needed for InputIterator)
operator ==(const iteration_proxy_value & o) const4497     bool operator==(const iteration_proxy_value& o) const
4498     {
4499         return anchor == o.anchor;
4500     }
4501 
4502     /// inequality operator (needed for range-based for)
operator !=(const iteration_proxy_value & o) const4503     bool operator!=(const iteration_proxy_value& o) const
4504     {
4505         return anchor != o.anchor;
4506     }
4507 
4508     /// return key of the iterator
key() const4509     const string_type& key() const
4510     {
4511         JSON_ASSERT(anchor.m_object != nullptr);
4512 
4513         switch (anchor.m_object->type())
4514         {
4515             // use integer array index as key
4516             case value_t::array:
4517             {
4518                 if (array_index != array_index_last)
4519                 {
4520                     int_to_string( array_index_str, array_index );
4521                     array_index_last = array_index;
4522                 }
4523                 return array_index_str;
4524             }
4525 
4526             // use key from the object
4527             case value_t::object:
4528                 return anchor.key();
4529 
4530             // use an empty key for all primitive types
4531             case value_t::null:
4532             case value_t::string:
4533             case value_t::boolean:
4534             case value_t::number_integer:
4535             case value_t::number_unsigned:
4536             case value_t::number_float:
4537             case value_t::binary:
4538             case value_t::discarded:
4539             default:
4540                 return empty_str;
4541         }
4542     }
4543 
4544     /// return value of the iterator
value() const4545     typename IteratorType::reference value() const
4546     {
4547         return anchor.value();
4548     }
4549 };
4550 
4551 /// proxy class for the items() function
4552 template<typename IteratorType> class iteration_proxy
4553 {
4554   private:
4555     /// the container to iterate
4556     typename IteratorType::reference container;
4557 
4558   public:
4559     /// construct iteration proxy from a container
iteration_proxy(typename IteratorType::reference cont)4560     explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4561         : container(cont) {}
4562 
4563     /// return iterator begin (needed for range-based for)
begin()4564     iteration_proxy_value<IteratorType> begin() noexcept
4565     {
4566         return iteration_proxy_value<IteratorType>(container.begin());
4567     }
4568 
4569     /// return iterator end (needed for range-based for)
end()4570     iteration_proxy_value<IteratorType> end() noexcept
4571     {
4572         return iteration_proxy_value<IteratorType>(container.end());
4573     }
4574 };
4575 // Structured Bindings Support
4576 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4577 // And see https://github.com/nlohmann/json/pull/1391
4578 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
get(const nlohmann::detail::iteration_proxy_value<IteratorType> & i)4579 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
4580 {
4581     return i.key();
4582 }
4583 // Structured Bindings Support
4584 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4585 // And see https://github.com/nlohmann/json/pull/1391
4586 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
get(const nlohmann::detail::iteration_proxy_value<IteratorType> & i)4587 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4588 {
4589     return i.value();
4590 }
4591 }  // namespace detail
4592 }  // namespace nlohmann
4593 
4594 // The Addition to the STD Namespace is required to add
4595 // Structured Bindings Support to the iteration_proxy_value class
4596 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4597 // And see https://github.com/nlohmann/json/pull/1391
4598 namespace std
4599 {
4600 #if defined(__clang__)
4601     // Fix: https://github.com/nlohmann/json/issues/1401
4602     #pragma clang diagnostic push
4603     #pragma clang diagnostic ignored "-Wmismatched-tags"
4604 #endif
4605 template<typename IteratorType>
4606 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4607             : public std::integral_constant<std::size_t, 2> {};
4608 
4609 template<std::size_t N, typename IteratorType>
4610 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4611 {
4612   public:
4613     using type = decltype(
4614                      get<N>(std::declval <
4615                             ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
4616 };
4617 #if defined(__clang__)
4618     #pragma clang diagnostic pop
4619 #endif
4620 } // namespace std
4621 
4622 // #include <nlohmann/detail/meta/cpp_future.hpp>
4623 
4624 // #include <nlohmann/detail/meta/type_traits.hpp>
4625 
4626 // #include <nlohmann/detail/value_t.hpp>
4627 
4628 
4629 #ifdef JSON_HAS_CPP_17
4630     #include <filesystem>
4631 #endif
4632 
4633 namespace nlohmann
4634 {
4635 namespace detail
4636 {
4637 //////////////////
4638 // constructors //
4639 //////////////////
4640 
4641 /*
4642  * Note all external_constructor<>::construct functions need to call
4643  * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4644  * allocated value (e.g., a string). See bug issue
4645  * https://github.com/nlohmann/json/issues/2865 for more information.
4646  */
4647 
4648 template<value_t> struct external_constructor;
4649 
4650 template<>
4651 struct external_constructor<value_t::boolean>
4652 {
4653     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4654     static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4655     {
4656         j.m_value.destroy(j.m_type);
4657         j.m_type = value_t::boolean;
4658         j.m_value = b;
4659         j.assert_invariant();
4660     }
4661 };
4662 
4663 template<>
4664 struct external_constructor<value_t::string>
4665 {
4666     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4667     static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4668     {
4669         j.m_value.destroy(j.m_type);
4670         j.m_type = value_t::string;
4671         j.m_value = s;
4672         j.assert_invariant();
4673     }
4674 
4675     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4676     static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4677     {
4678         j.m_value.destroy(j.m_type);
4679         j.m_type = value_t::string;
4680         j.m_value = std::move(s);
4681         j.assert_invariant();
4682     }
4683 
4684     template < typename BasicJsonType, typename CompatibleStringType,
4685                enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4686                              int > = 0 >
constructnlohmann::detail::external_constructor4687     static void construct(BasicJsonType& j, const CompatibleStringType& str)
4688     {
4689         j.m_value.destroy(j.m_type);
4690         j.m_type = value_t::string;
4691         j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4692         j.assert_invariant();
4693     }
4694 };
4695 
4696 template<>
4697 struct external_constructor<value_t::binary>
4698 {
4699     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4700     static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4701     {
4702         j.m_value.destroy(j.m_type);
4703         j.m_type = value_t::binary;
4704         j.m_value = typename BasicJsonType::binary_t(b);
4705         j.assert_invariant();
4706     }
4707 
4708     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4709     static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4710     {
4711         j.m_value.destroy(j.m_type);
4712         j.m_type = value_t::binary;
4713         j.m_value = typename BasicJsonType::binary_t(std::move(b));
4714         j.assert_invariant();
4715     }
4716 };
4717 
4718 template<>
4719 struct external_constructor<value_t::number_float>
4720 {
4721     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4722     static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4723     {
4724         j.m_value.destroy(j.m_type);
4725         j.m_type = value_t::number_float;
4726         j.m_value = val;
4727         j.assert_invariant();
4728     }
4729 };
4730 
4731 template<>
4732 struct external_constructor<value_t::number_unsigned>
4733 {
4734     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4735     static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4736     {
4737         j.m_value.destroy(j.m_type);
4738         j.m_type = value_t::number_unsigned;
4739         j.m_value = val;
4740         j.assert_invariant();
4741     }
4742 };
4743 
4744 template<>
4745 struct external_constructor<value_t::number_integer>
4746 {
4747     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4748     static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4749     {
4750         j.m_value.destroy(j.m_type);
4751         j.m_type = value_t::number_integer;
4752         j.m_value = val;
4753         j.assert_invariant();
4754     }
4755 };
4756 
4757 template<>
4758 struct external_constructor<value_t::array>
4759 {
4760     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4761     static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4762     {
4763         j.m_value.destroy(j.m_type);
4764         j.m_type = value_t::array;
4765         j.m_value = arr;
4766         j.set_parents();
4767         j.assert_invariant();
4768     }
4769 
4770     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4771     static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4772     {
4773         j.m_value.destroy(j.m_type);
4774         j.m_type = value_t::array;
4775         j.m_value = std::move(arr);
4776         j.set_parents();
4777         j.assert_invariant();
4778     }
4779 
4780     template < typename BasicJsonType, typename CompatibleArrayType,
4781                enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4782                              int > = 0 >
constructnlohmann::detail::external_constructor4783     static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4784     {
4785         using std::begin;
4786         using std::end;
4787 
4788         j.m_value.destroy(j.m_type);
4789         j.m_type = value_t::array;
4790         j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4791         j.set_parents();
4792         j.assert_invariant();
4793     }
4794 
4795     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4796     static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4797     {
4798         j.m_value.destroy(j.m_type);
4799         j.m_type = value_t::array;
4800         j.m_value = value_t::array;
4801         j.m_value.array->reserve(arr.size());
4802         for (const bool x : arr)
4803         {
4804             j.m_value.array->push_back(x);
4805             j.set_parent(j.m_value.array->back());
4806         }
4807         j.assert_invariant();
4808     }
4809 
4810     template<typename BasicJsonType, typename T,
4811              enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
constructnlohmann::detail::external_constructor4812     static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4813     {
4814         j.m_value.destroy(j.m_type);
4815         j.m_type = value_t::array;
4816         j.m_value = value_t::array;
4817         j.m_value.array->resize(arr.size());
4818         if (arr.size() > 0)
4819         {
4820             std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4821         }
4822         j.set_parents();
4823         j.assert_invariant();
4824     }
4825 };
4826 
4827 template<>
4828 struct external_constructor<value_t::object>
4829 {
4830     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4831     static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4832     {
4833         j.m_value.destroy(j.m_type);
4834         j.m_type = value_t::object;
4835         j.m_value = obj;
4836         j.set_parents();
4837         j.assert_invariant();
4838     }
4839 
4840     template<typename BasicJsonType>
constructnlohmann::detail::external_constructor4841     static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4842     {
4843         j.m_value.destroy(j.m_type);
4844         j.m_type = value_t::object;
4845         j.m_value = std::move(obj);
4846         j.set_parents();
4847         j.assert_invariant();
4848     }
4849 
4850     template < typename BasicJsonType, typename CompatibleObjectType,
4851                enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
constructnlohmann::detail::external_constructor4852     static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4853     {
4854         using std::begin;
4855         using std::end;
4856 
4857         j.m_value.destroy(j.m_type);
4858         j.m_type = value_t::object;
4859         j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4860         j.set_parents();
4861         j.assert_invariant();
4862     }
4863 };
4864 
4865 /////////////
4866 // to_json //
4867 /////////////
4868 
4869 template<typename BasicJsonType, typename T,
4870          enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
to_json(BasicJsonType & j,T b)4871 void to_json(BasicJsonType& j, T b) noexcept
4872 {
4873     external_constructor<value_t::boolean>::construct(j, b);
4874 }
4875 
4876 template<typename BasicJsonType, typename CompatibleString,
4877          enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
to_json(BasicJsonType & j,const CompatibleString & s)4878 void to_json(BasicJsonType& j, const CompatibleString& s)
4879 {
4880     external_constructor<value_t::string>::construct(j, s);
4881 }
4882 
4883 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::string_t && s)4884 void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4885 {
4886     external_constructor<value_t::string>::construct(j, std::move(s));
4887 }
4888 
4889 template<typename BasicJsonType, typename FloatType,
4890          enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
to_json(BasicJsonType & j,FloatType val)4891 void to_json(BasicJsonType& j, FloatType val) noexcept
4892 {
4893     external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4894 }
4895 
4896 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4897          enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberUnsignedType val)4898 void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4899 {
4900     external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4901 }
4902 
4903 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4904          enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
to_json(BasicJsonType & j,CompatibleNumberIntegerType val)4905 void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4906 {
4907     external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4908 }
4909 
4910 template<typename BasicJsonType, typename EnumType,
4911          enable_if_t<std::is_enum<EnumType>::value, int> = 0>
to_json(BasicJsonType & j,EnumType e)4912 void to_json(BasicJsonType& j, EnumType e) noexcept
4913 {
4914     using underlying_type = typename std::underlying_type<EnumType>::type;
4915     external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4916 }
4917 
4918 template<typename BasicJsonType>
to_json(BasicJsonType & j,const std::vector<bool> & e)4919 void to_json(BasicJsonType& j, const std::vector<bool>& e)
4920 {
4921     external_constructor<value_t::array>::construct(j, e);
4922 }
4923 
4924 template < typename BasicJsonType, typename CompatibleArrayType,
4925            enable_if_t < is_compatible_array_type<BasicJsonType,
4926                          CompatibleArrayType>::value&&
4927                          !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4928                          !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4929                          !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4930                          !is_basic_json<CompatibleArrayType>::value,
4931                          int > = 0 >
to_json(BasicJsonType & j,const CompatibleArrayType & arr)4932 void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4933 {
4934     external_constructor<value_t::array>::construct(j, arr);
4935 }
4936 
4937 template<typename BasicJsonType>
to_json(BasicJsonType & j,const typename BasicJsonType::binary_t & bin)4938 void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4939 {
4940     external_constructor<value_t::binary>::construct(j, bin);
4941 }
4942 
4943 template<typename BasicJsonType, typename T,
4944          enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
to_json(BasicJsonType & j,const std::valarray<T> & arr)4945 void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4946 {
4947     external_constructor<value_t::array>::construct(j, std::move(arr));
4948 }
4949 
4950 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::array_t && arr)4951 void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4952 {
4953     external_constructor<value_t::array>::construct(j, std::move(arr));
4954 }
4955 
4956 template < typename BasicJsonType, typename CompatibleObjectType,
4957            enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
to_json(BasicJsonType & j,const CompatibleObjectType & obj)4958 void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4959 {
4960     external_constructor<value_t::object>::construct(j, obj);
4961 }
4962 
4963 template<typename BasicJsonType>
to_json(BasicJsonType & j,typename BasicJsonType::object_t && obj)4964 void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4965 {
4966     external_constructor<value_t::object>::construct(j, std::move(obj));
4967 }
4968 
4969 template <
4970     typename BasicJsonType, typename T, std::size_t N,
4971     enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4972                   const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4973                   int > = 0 >
to_json(BasicJsonType & j,const T (& arr)[N])4974 void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4975 {
4976     external_constructor<value_t::array>::construct(j, arr);
4977 }
4978 
4979 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
to_json(BasicJsonType & j,const std::pair<T1,T2> & p)4980 void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4981 {
4982     j = { p.first, p.second };
4983 }
4984 
4985 // for https://github.com/nlohmann/json/pull/1134
4986 template<typename BasicJsonType, typename T,
4987          enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
to_json(BasicJsonType & j,const T & b)4988 void to_json(BasicJsonType& j, const T& b)
4989 {
4990     j = { {b.key(), b.value()} };
4991 }
4992 
4993 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
to_json_tuple_impl(BasicJsonType & j,const Tuple & t,index_sequence<Idx...>)4994 void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4995 {
4996     j = { std::get<Idx>(t)... };
4997 }
4998 
4999 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
to_json(BasicJsonType & j,const T & t)5000 void to_json(BasicJsonType& j, const T& t)
5001 {
5002     to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5003 }
5004 
5005 #ifdef JSON_HAS_CPP_17
5006 template<typename BasicJsonType>
to_json(BasicJsonType & j,const std::filesystem::path & p)5007 void to_json(BasicJsonType& j, const std::filesystem::path& p)
5008 {
5009     j = p.string();
5010 }
5011 #endif
5012 
5013 struct to_json_fn
5014 {
5015     template<typename BasicJsonType, typename T>
operator ()nlohmann::detail::to_json_fn5016     auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5017     -> decltype(to_json(j, std::forward<T>(val)), void())
5018     {
5019         return to_json(j, std::forward<T>(val));
5020     }
5021 };
5022 }  // namespace detail
5023 
5024 /// namespace to hold default `to_json` function
5025 /// to see why this is required:
5026 /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html
5027 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5028 {
5029 constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
5030 } // namespace
5031 } // namespace nlohmann
5032 
5033 // #include <nlohmann/detail/meta/identity_tag.hpp>
5034 
5035 // #include <nlohmann/detail/meta/type_traits.hpp>
5036 
5037 
5038 namespace nlohmann
5039 {
5040 
5041 template<typename ValueType, typename>
5042 struct adl_serializer
5043 {
5044     /*!
5045     @brief convert a JSON value to any value type
5046 
5047     This function is usually called by the `get()` function of the
5048     @ref basic_json class (either explicit or via conversion operators).
5049 
5050     @note This function is chosen for default-constructible value types.
5051 
5052     @param[in] j        JSON value to read from
5053     @param[in,out] val  value to write to
5054     */
5055     template<typename BasicJsonType, typename TargetType = ValueType>
from_jsonnlohmann::adl_serializer5056     static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
5057         noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5058     -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5059     {
5060         ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5061     }
5062 
5063     /*!
5064     @brief convert a JSON value to any value type
5065 
5066     This function is usually called by the `get()` function of the
5067     @ref basic_json class (either explicit or via conversion operators).
5068 
5069     @note This function is chosen for value types which are not default-constructible.
5070 
5071     @param[in] j  JSON value to read from
5072 
5073     @return copy of the JSON value, converted to @a ValueType
5074     */
5075     template<typename BasicJsonType, typename TargetType = ValueType>
from_jsonnlohmann::adl_serializer5076     static auto from_json(BasicJsonType && j) noexcept(
5077     noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5078     -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5079     {
5080         return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5081     }
5082 
5083     /*!
5084     @brief convert any value type to a JSON value
5085 
5086     This function is usually called by the constructors of the @ref basic_json
5087     class.
5088 
5089     @param[in,out] j  JSON value to write to
5090     @param[in] val    value to read from
5091     */
5092     template<typename BasicJsonType, typename TargetType = ValueType>
to_jsonnlohmann::adl_serializer5093     static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5094         noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5095     -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5096     {
5097         ::nlohmann::to_json(j, std::forward<TargetType>(val));
5098     }
5099 };
5100 }  // namespace nlohmann
5101 
5102 // #include <nlohmann/byte_container_with_subtype.hpp>
5103 
5104 
5105 #include <cstdint> // uint8_t, uint64_t
5106 #include <tuple> // tie
5107 #include <utility> // move
5108 
5109 namespace nlohmann
5110 {
5111 
5112 /*!
5113 @brief an internal type for a backed binary type
5114 
5115 This type extends the template parameter @a BinaryType provided to `basic_json`
5116 with a subtype used by BSON and MessagePack. This type exists so that the user
5117 does not have to specify a type themselves with a specific naming scheme in
5118 order to override the binary type.
5119 
5120 @tparam BinaryType container to store bytes (`std::vector<std::uint8_t>` by
5121                    default)
5122 
5123 @since version 3.8.0; changed type of subtypes to std::uint64_t in 3.10.0.
5124 */
5125 template<typename BinaryType>
5126 class byte_container_with_subtype : public BinaryType
5127 {
5128   public:
5129     /// the type of the underlying container
5130     using container_type = BinaryType;
5131     /// the type of the subtype
5132     using subtype_type = std::uint64_t;
5133 
byte_container_with_subtype()5134     byte_container_with_subtype() noexcept(noexcept(container_type()))
5135         : container_type()
5136     {}
5137 
byte_container_with_subtype(const container_type & b)5138     byte_container_with_subtype(const container_type& b) noexcept(noexcept(container_type(b)))
5139         : container_type(b)
5140     {}
5141 
byte_container_with_subtype(container_type && b)5142     byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5143         : container_type(std::move(b))
5144     {}
5145 
byte_container_with_subtype(const container_type & b,subtype_type subtype_)5146     byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
5147         : container_type(b)
5148         , m_subtype(subtype_)
5149         , m_has_subtype(true)
5150     {}
5151 
byte_container_with_subtype(container_type && b,subtype_type subtype_)5152     byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5153         : container_type(std::move(b))
5154         , m_subtype(subtype_)
5155         , m_has_subtype(true)
5156     {}
5157 
operator ==(const byte_container_with_subtype & rhs) const5158     bool operator==(const byte_container_with_subtype& rhs) const
5159     {
5160         return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5161                std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5162     }
5163 
operator !=(const byte_container_with_subtype & rhs) const5164     bool operator!=(const byte_container_with_subtype& rhs) const
5165     {
5166         return !(rhs == *this);
5167     }
5168 
5169     /*!
5170     @brief sets the binary subtype
5171 
5172     Sets the binary subtype of the value, also flags a binary JSON value as
5173     having a subtype, which has implications for serialization.
5174 
5175     @complexity Constant.
5176 
5177     @exceptionsafety No-throw guarantee: this member function never throws
5178     exceptions.
5179 
5180     @sa see @ref subtype() -- return the binary subtype
5181     @sa see @ref clear_subtype() -- clears the binary subtype
5182     @sa see @ref has_subtype() -- returns whether or not the binary value has a
5183     subtype
5184 
5185     @since version 3.8.0
5186     */
set_subtype(subtype_type subtype_)5187     void set_subtype(subtype_type subtype_) noexcept
5188     {
5189         m_subtype = subtype_;
5190         m_has_subtype = true;
5191     }
5192 
5193     /*!
5194     @brief return the binary subtype
5195 
5196     Returns the numerical subtype of the value if it has a subtype. If it does
5197     not have a subtype, this function will return subtype_type(-1) as a sentinel
5198     value.
5199 
5200     @return the numerical subtype of the binary value
5201 
5202     @complexity Constant.
5203 
5204     @exceptionsafety No-throw guarantee: this member function never throws
5205     exceptions.
5206 
5207     @sa see @ref set_subtype() -- sets the binary subtype
5208     @sa see @ref clear_subtype() -- clears the binary subtype
5209     @sa see @ref has_subtype() -- returns whether or not the binary value has a
5210     subtype
5211 
5212     @since version 3.8.0; fixed return value to properly return
5213            subtype_type(-1) as documented in version 3.10.0
5214     */
subtype() const5215     constexpr subtype_type subtype() const noexcept
5216     {
5217         return m_has_subtype ? m_subtype : subtype_type(-1);
5218     }
5219 
5220     /*!
5221     @brief return whether the value has a subtype
5222 
5223     @return whether the value has a subtype
5224 
5225     @complexity Constant.
5226 
5227     @exceptionsafety No-throw guarantee: this member function never throws
5228     exceptions.
5229 
5230     @sa see @ref subtype() -- return the binary subtype
5231     @sa see @ref set_subtype() -- sets the binary subtype
5232     @sa see @ref clear_subtype() -- clears the binary subtype
5233 
5234     @since version 3.8.0
5235     */
has_subtype() const5236     constexpr bool has_subtype() const noexcept
5237     {
5238         return m_has_subtype;
5239     }
5240 
5241     /*!
5242     @brief clears the binary subtype
5243 
5244     Clears the binary subtype and flags the value as not having a subtype, which
5245     has implications for serialization; for instance MessagePack will prefer the
5246     bin family over the ext family.
5247 
5248     @complexity Constant.
5249 
5250     @exceptionsafety No-throw guarantee: this member function never throws
5251     exceptions.
5252 
5253     @sa see @ref subtype() -- return the binary subtype
5254     @sa see @ref set_subtype() -- sets the binary subtype
5255     @sa see @ref has_subtype() -- returns whether or not the binary value has a
5256     subtype
5257 
5258     @since version 3.8.0
5259     */
clear_subtype()5260     void clear_subtype() noexcept
5261     {
5262         m_subtype = 0;
5263         m_has_subtype = false;
5264     }
5265 
5266   private:
5267     subtype_type m_subtype = 0;
5268     bool m_has_subtype = false;
5269 };
5270 
5271 }  // namespace nlohmann
5272 
5273 // #include <nlohmann/detail/conversions/from_json.hpp>
5274 
5275 // #include <nlohmann/detail/conversions/to_json.hpp>
5276 
5277 // #include <nlohmann/detail/exceptions.hpp>
5278 
5279 // #include <nlohmann/detail/hash.hpp>
5280 
5281 
5282 #include <cstdint> // uint8_t
5283 #include <cstddef> // size_t
5284 #include <functional> // hash
5285 
5286 // #include <nlohmann/detail/macro_scope.hpp>
5287 
5288 // #include <nlohmann/detail/value_t.hpp>
5289 
5290 
5291 namespace nlohmann
5292 {
5293 namespace detail
5294 {
5295 
5296 // boost::hash_combine
combine(std::size_t seed,std::size_t h)5297 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5298 {
5299     seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5300     return seed;
5301 }
5302 
5303 /*!
5304 @brief hash a JSON value
5305 
5306 The hash function tries to rely on std::hash where possible. Furthermore, the
5307 type of the JSON value is taken into account to have different hash values for
5308 null, 0, 0U, and false, etc.
5309 
5310 @tparam BasicJsonType basic_json specialization
5311 @param j JSON value to hash
5312 @return hash value of j
5313 */
5314 template<typename BasicJsonType>
hash(const BasicJsonType & j)5315 std::size_t hash(const BasicJsonType& j)
5316 {
5317     using string_t = typename BasicJsonType::string_t;
5318     using number_integer_t = typename BasicJsonType::number_integer_t;
5319     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5320     using number_float_t = typename BasicJsonType::number_float_t;
5321 
5322     const auto type = static_cast<std::size_t>(j.type());
5323     switch (j.type())
5324     {
5325         case BasicJsonType::value_t::null:
5326         case BasicJsonType::value_t::discarded:
5327         {
5328             return combine(type, 0);
5329         }
5330 
5331         case BasicJsonType::value_t::object:
5332         {
5333             auto seed = combine(type, j.size());
5334             for (const auto& element : j.items())
5335             {
5336                 const auto h = std::hash<string_t> {}(element.key());
5337                 seed = combine(seed, h);
5338                 seed = combine(seed, hash(element.value()));
5339             }
5340             return seed;
5341         }
5342 
5343         case BasicJsonType::value_t::array:
5344         {
5345             auto seed = combine(type, j.size());
5346             for (const auto& element : j)
5347             {
5348                 seed = combine(seed, hash(element));
5349             }
5350             return seed;
5351         }
5352 
5353         case BasicJsonType::value_t::string:
5354         {
5355             const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5356             return combine(type, h);
5357         }
5358 
5359         case BasicJsonType::value_t::boolean:
5360         {
5361             const auto h = std::hash<bool> {}(j.template get<bool>());
5362             return combine(type, h);
5363         }
5364 
5365         case BasicJsonType::value_t::number_integer:
5366         {
5367             const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5368             return combine(type, h);
5369         }
5370 
5371         case BasicJsonType::value_t::number_unsigned:
5372         {
5373             const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5374             return combine(type, h);
5375         }
5376 
5377         case BasicJsonType::value_t::number_float:
5378         {
5379             const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5380             return combine(type, h);
5381         }
5382 
5383         case BasicJsonType::value_t::binary:
5384         {
5385             auto seed = combine(type, j.get_binary().size());
5386             const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5387             seed = combine(seed, h);
5388             seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5389             for (const auto byte : j.get_binary())
5390             {
5391                 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5392             }
5393             return seed;
5394         }
5395 
5396         default:                   // LCOV_EXCL_LINE
5397             JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5398             return 0;              // LCOV_EXCL_LINE
5399     }
5400 }
5401 
5402 }  // namespace detail
5403 }  // namespace nlohmann
5404 
5405 // #include <nlohmann/detail/input/binary_reader.hpp>
5406 
5407 
5408 #include <algorithm> // generate_n
5409 #include <array> // array
5410 #include <cmath> // ldexp
5411 #include <cstddef> // size_t
5412 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5413 #include <cstdio> // snprintf
5414 #include <cstring> // memcpy
5415 #include <iterator> // back_inserter
5416 #include <limits> // numeric_limits
5417 #include <string> // char_traits, string
5418 #include <utility> // make_pair, move
5419 #include <vector> // vector
5420 
5421 // #include <nlohmann/detail/exceptions.hpp>
5422 
5423 // #include <nlohmann/detail/input/input_adapters.hpp>
5424 
5425 
5426 #include <array> // array
5427 #include <cstddef> // size_t
5428 #include <cstring> // strlen
5429 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5430 #include <memory> // shared_ptr, make_shared, addressof
5431 #include <numeric> // accumulate
5432 #include <string> // string, char_traits
5433 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5434 #include <utility> // pair, declval
5435 
5436 #ifndef JSON_NO_IO
5437     #include <cstdio>   // FILE *
5438     #include <istream>  // istream
5439 #endif                  // JSON_NO_IO
5440 
5441 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
5442 
5443 // #include <nlohmann/detail/macro_scope.hpp>
5444 
5445 
5446 namespace nlohmann
5447 {
5448 namespace detail
5449 {
5450 /// the supported input formats
5451 enum class input_format_t { json, cbor, msgpack, ubjson, bson };
5452 
5453 ////////////////////
5454 // input adapters //
5455 ////////////////////
5456 
5457 #ifndef JSON_NO_IO
5458 /*!
5459 Input adapter for stdio file access. This adapter read only 1 byte and do not use any
5460  buffer. This adapter is a very low level adapter.
5461 */
5462 class file_input_adapter
5463 {
5464   public:
5465     using char_type = char;
5466 
5467     JSON_HEDLEY_NON_NULL(2)
file_input_adapter(std::FILE * f)5468     explicit file_input_adapter(std::FILE* f) noexcept
5469         : m_file(f)
5470     {}
5471 
5472     // make class move-only
5473     file_input_adapter(const file_input_adapter&) = delete;
5474     file_input_adapter(file_input_adapter&&) noexcept = default;
5475     file_input_adapter& operator=(const file_input_adapter&) = delete;
5476     file_input_adapter& operator=(file_input_adapter&&) = delete;
5477     ~file_input_adapter() = default;
5478 
get_character()5479     std::char_traits<char>::int_type get_character() noexcept
5480     {
5481         return std::fgetc(m_file);
5482     }
5483 
5484   private:
5485     /// the file pointer to read from
5486     std::FILE* m_file;
5487 };
5488 
5489 
5490 /*!
5491 Input adapter for a (caching) istream. Ignores a UFT Byte Order Mark at
5492 beginning of input. Does not support changing the underlying std::streambuf
5493 in mid-input. Maintains underlying std::istream and std::streambuf to support
5494 subsequent use of standard std::istream operations to process any input
5495 characters following those used in parsing the JSON input.  Clears the
5496 std::istream flags; any input errors (e.g., EOF) will be detected by the first
5497 subsequent call for input from the std::istream.
5498 */
5499 class input_stream_adapter
5500 {
5501   public:
5502     using char_type = char;
5503 
~input_stream_adapter()5504     ~input_stream_adapter()
5505     {
5506         // clear stream flags; we use underlying streambuf I/O, do not
5507         // maintain ifstream flags, except eof
5508         if (is != nullptr)
5509         {
5510             is->clear(is->rdstate() & std::ios::eofbit);
5511         }
5512     }
5513 
input_stream_adapter(std::istream & i)5514     explicit input_stream_adapter(std::istream& i)
5515         : is(&i), sb(i.rdbuf())
5516     {}
5517 
5518     // delete because of pointer members
5519     input_stream_adapter(const input_stream_adapter&) = delete;
5520     input_stream_adapter& operator=(input_stream_adapter&) = delete;
5521     input_stream_adapter& operator=(input_stream_adapter&&) = delete;
5522 
input_stream_adapter(input_stream_adapter && rhs)5523     input_stream_adapter(input_stream_adapter&& rhs) noexcept
5524         : is(rhs.is), sb(rhs.sb)
5525     {
5526         rhs.is = nullptr;
5527         rhs.sb = nullptr;
5528     }
5529 
5530     // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5531     // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5532     // end up as the same value, eg. 0xFFFFFFFF.
get_character()5533     std::char_traits<char>::int_type get_character()
5534     {
5535         auto res = sb->sbumpc();
5536         // set eof manually, as we don't use the istream interface.
5537         if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5538         {
5539             is->clear(is->rdstate() | std::ios::eofbit);
5540         }
5541         return res;
5542     }
5543 
5544   private:
5545     /// the associated input stream
5546     std::istream* is = nullptr;
5547     std::streambuf* sb = nullptr;
5548 };
5549 #endif  // JSON_NO_IO
5550 
5551 // General-purpose iterator-based adapter. It might not be as fast as
5552 // theoretically possible for some containers, but it is extremely versatile.
5553 template<typename IteratorType>
5554 class iterator_input_adapter
5555 {
5556   public:
5557     using char_type = typename std::iterator_traits<IteratorType>::value_type;
5558 
iterator_input_adapter(IteratorType first,IteratorType last)5559     iterator_input_adapter(IteratorType first, IteratorType last)
5560         : current(std::move(first)), end(std::move(last))
5561     {}
5562 
get_character()5563     typename std::char_traits<char_type>::int_type get_character()
5564     {
5565         if (JSON_HEDLEY_LIKELY(current != end))
5566         {
5567             auto result = std::char_traits<char_type>::to_int_type(*current);
5568             std::advance(current, 1);
5569             return result;
5570         }
5571 
5572         return std::char_traits<char_type>::eof();
5573     }
5574 
5575   private:
5576     IteratorType current;
5577     IteratorType end;
5578 
5579     template<typename BaseInputAdapter, size_t T>
5580     friend struct wide_string_input_helper;
5581 
empty() const5582     bool empty() const
5583     {
5584         return current == end;
5585     }
5586 };
5587 
5588 
5589 template<typename BaseInputAdapter, size_t T>
5590 struct wide_string_input_helper;
5591 
5592 template<typename BaseInputAdapter>
5593 struct wide_string_input_helper<BaseInputAdapter, 4>
5594 {
5595     // UTF-32
fill_buffernlohmann::detail::wide_string_input_helper5596     static void fill_buffer(BaseInputAdapter& input,
5597                             std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5598                             size_t& utf8_bytes_index,
5599                             size_t& utf8_bytes_filled)
5600     {
5601         utf8_bytes_index = 0;
5602 
5603         if (JSON_HEDLEY_UNLIKELY(input.empty()))
5604         {
5605             utf8_bytes[0] = std::char_traits<char>::eof();
5606             utf8_bytes_filled = 1;
5607         }
5608         else
5609         {
5610             // get the current character
5611             const auto wc = input.get_character();
5612 
5613             // UTF-32 to UTF-8 encoding
5614             if (wc < 0x80)
5615             {
5616                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5617                 utf8_bytes_filled = 1;
5618             }
5619             else if (wc <= 0x7FF)
5620             {
5621                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5622                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5623                 utf8_bytes_filled = 2;
5624             }
5625             else if (wc <= 0xFFFF)
5626             {
5627                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5628                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5629                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5630                 utf8_bytes_filled = 3;
5631             }
5632             else if (wc <= 0x10FFFF)
5633             {
5634                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5635                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5636                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5637                 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5638                 utf8_bytes_filled = 4;
5639             }
5640             else
5641             {
5642                 // unknown character
5643                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5644                 utf8_bytes_filled = 1;
5645             }
5646         }
5647     }
5648 };
5649 
5650 template<typename BaseInputAdapter>
5651 struct wide_string_input_helper<BaseInputAdapter, 2>
5652 {
5653     // UTF-16
fill_buffernlohmann::detail::wide_string_input_helper5654     static void fill_buffer(BaseInputAdapter& input,
5655                             std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5656                             size_t& utf8_bytes_index,
5657                             size_t& utf8_bytes_filled)
5658     {
5659         utf8_bytes_index = 0;
5660 
5661         if (JSON_HEDLEY_UNLIKELY(input.empty()))
5662         {
5663             utf8_bytes[0] = std::char_traits<char>::eof();
5664             utf8_bytes_filled = 1;
5665         }
5666         else
5667         {
5668             // get the current character
5669             const auto wc = input.get_character();
5670 
5671             // UTF-16 to UTF-8 encoding
5672             if (wc < 0x80)
5673             {
5674                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5675                 utf8_bytes_filled = 1;
5676             }
5677             else if (wc <= 0x7FF)
5678             {
5679                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5680                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5681                 utf8_bytes_filled = 2;
5682             }
5683             else if (0xD800 > wc || wc >= 0xE000)
5684             {
5685                 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5686                 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5687                 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5688                 utf8_bytes_filled = 3;
5689             }
5690             else
5691             {
5692                 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5693                 {
5694                     const auto wc2 = static_cast<unsigned int>(input.get_character());
5695                     const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5696                     utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5697                     utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5698                     utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5699                     utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5700                     utf8_bytes_filled = 4;
5701                 }
5702                 else
5703                 {
5704                     utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5705                     utf8_bytes_filled = 1;
5706                 }
5707             }
5708         }
5709     }
5710 };
5711 
5712 // Wraps another input apdater to convert wide character types into individual bytes.
5713 template<typename BaseInputAdapter, typename WideCharType>
5714 class wide_string_input_adapter
5715 {
5716   public:
5717     using char_type = char;
5718 
wide_string_input_adapter(BaseInputAdapter base)5719     wide_string_input_adapter(BaseInputAdapter base)
5720         : base_adapter(base) {}
5721 
get_character()5722     typename std::char_traits<char>::int_type get_character() noexcept
5723     {
5724         // check if buffer needs to be filled
5725         if (utf8_bytes_index == utf8_bytes_filled)
5726         {
5727             fill_buffer<sizeof(WideCharType)>();
5728 
5729             JSON_ASSERT(utf8_bytes_filled > 0);
5730             JSON_ASSERT(utf8_bytes_index == 0);
5731         }
5732 
5733         // use buffer
5734         JSON_ASSERT(utf8_bytes_filled > 0);
5735         JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5736         return utf8_bytes[utf8_bytes_index++];
5737     }
5738 
5739   private:
5740     BaseInputAdapter base_adapter;
5741 
5742     template<size_t T>
fill_buffer()5743     void fill_buffer()
5744     {
5745         wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5746     }
5747 
5748     /// a buffer for UTF-8 bytes
5749     std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5750 
5751     /// index to the utf8_codes array for the next valid byte
5752     std::size_t utf8_bytes_index = 0;
5753     /// number of valid bytes in the utf8_codes array
5754     std::size_t utf8_bytes_filled = 0;
5755 };
5756 
5757 
5758 template<typename IteratorType, typename Enable = void>
5759 struct iterator_input_adapter_factory
5760 {
5761     using iterator_type = IteratorType;
5762     using char_type = typename std::iterator_traits<iterator_type>::value_type;
5763     using adapter_type = iterator_input_adapter<iterator_type>;
5764 
createnlohmann::detail::iterator_input_adapter_factory5765     static adapter_type create(IteratorType first, IteratorType last)
5766     {
5767         return adapter_type(std::move(first), std::move(last));
5768     }
5769 };
5770 
5771 template<typename T>
5772 struct is_iterator_of_multibyte
5773 {
5774     using value_type = typename std::iterator_traits<T>::value_type;
5775     enum
5776     {
5777         value = sizeof(value_type) > 1
5778     };
5779 };
5780 
5781 template<typename IteratorType>
5782 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5783 {
5784     using iterator_type = IteratorType;
5785     using char_type = typename std::iterator_traits<iterator_type>::value_type;
5786     using base_adapter_type = iterator_input_adapter<iterator_type>;
5787     using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5788 
createnlohmann::detail::iterator_input_adapter_factory5789     static adapter_type create(IteratorType first, IteratorType last)
5790     {
5791         return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5792     }
5793 };
5794 
5795 // General purpose iterator-based input
5796 template<typename IteratorType>
input_adapter(IteratorType first,IteratorType last)5797 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5798 {
5799     using factory_type = iterator_input_adapter_factory<IteratorType>;
5800     return factory_type::create(first, last);
5801 }
5802 
5803 // Convenience shorthand from container to iterator
5804 // Enables ADL on begin(container) and end(container)
5805 // Encloses the using declarations in namespace for not to leak them to outside scope
5806 
5807 namespace container_input_adapter_factory_impl
5808 {
5809 
5810 using std::begin;
5811 using std::end;
5812 
5813 template<typename ContainerType, typename Enable = void>
5814 struct container_input_adapter_factory {};
5815 
5816 template<typename ContainerType>
5817 struct container_input_adapter_factory< ContainerType,
5818        void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5819        {
5820            using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5821 
createnlohmann::detail::container_input_adapter_factory_impl::container_input_adapter_factory5822            static adapter_type create(const ContainerType& container)
5823 {
5824     return input_adapter(begin(container), end(container));
5825 }
5826        };
5827 
5828 } // namespace container_input_adapter_factory_impl
5829 
5830 template<typename ContainerType>
input_adapter(const ContainerType & container)5831 typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
5832 {
5833     return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
5834 }
5835 
5836 #ifndef JSON_NO_IO
5837 // Special cases with fast paths
input_adapter(std::FILE * file)5838 inline file_input_adapter input_adapter(std::FILE* file)
5839 {
5840     return file_input_adapter(file);
5841 }
5842 
input_adapter(std::istream & stream)5843 inline input_stream_adapter input_adapter(std::istream& stream)
5844 {
5845     return input_stream_adapter(stream);
5846 }
5847 
input_adapter(std::istream && stream)5848 inline input_stream_adapter input_adapter(std::istream&& stream)
5849 {
5850     return input_stream_adapter(stream);
5851 }
5852 #endif  // JSON_NO_IO
5853 
5854 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5855 
5856 // Null-delimited strings, and the like.
5857 template < typename CharT,
5858            typename std::enable_if <
5859                std::is_pointer<CharT>::value&&
5860                !std::is_array<CharT>::value&&
5861                std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5862                sizeof(typename std::remove_pointer<CharT>::type) == 1,
5863                int >::type = 0 >
input_adapter(CharT b)5864 contiguous_bytes_input_adapter input_adapter(CharT b)
5865 {
5866     auto length = std::strlen(reinterpret_cast<const char*>(b));
5867     const auto* ptr = reinterpret_cast<const char*>(b);
5868     return input_adapter(ptr, ptr + length);
5869 }
5870 
5871 template<typename T, std::size_t N>
input_adapter(T (& array)[N])5872 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5873 {
5874     return input_adapter(array, array + N);
5875 }
5876 
5877 // This class only handles inputs of input_buffer_adapter type.
5878 // It's required so that expressions like {ptr, len} can be implicitely casted
5879 // to the correct adapter.
5880 class span_input_adapter
5881 {
5882   public:
5883     template < typename CharT,
5884                typename std::enable_if <
5885                    std::is_pointer<CharT>::value&&
5886                    std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5887                    sizeof(typename std::remove_pointer<CharT>::type) == 1,
5888                    int >::type = 0 >
span_input_adapter(CharT b,std::size_t l)5889     span_input_adapter(CharT b, std::size_t l)
5890         : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5891 
5892     template<class IteratorType,
5893              typename std::enable_if<
5894                  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5895                  int>::type = 0>
span_input_adapter(IteratorType first,IteratorType last)5896     span_input_adapter(IteratorType first, IteratorType last)
5897         : ia(input_adapter(first, last)) {}
5898 
get()5899     contiguous_bytes_input_adapter&& get()
5900     {
5901         return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5902     }
5903 
5904   private:
5905     contiguous_bytes_input_adapter ia;
5906 };
5907 }  // namespace detail
5908 }  // namespace nlohmann
5909 
5910 // #include <nlohmann/detail/input/json_sax.hpp>
5911 
5912 
5913 #include <cstddef>
5914 #include <string> // string
5915 #include <utility> // move
5916 #include <vector> // vector
5917 
5918 // #include <nlohmann/detail/exceptions.hpp>
5919 
5920 // #include <nlohmann/detail/macro_scope.hpp>
5921 
5922 
5923 namespace nlohmann
5924 {
5925 
5926 /*!
5927 @brief SAX interface
5928 
5929 This class describes the SAX interface used by @ref nlohmann::json::sax_parse.
5930 Each function is called in different situations while the input is parsed. The
5931 boolean return value informs the parser whether to continue processing the
5932 input.
5933 */
5934 template<typename BasicJsonType>
5935 struct json_sax
5936 {
5937     using number_integer_t = typename BasicJsonType::number_integer_t;
5938     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5939     using number_float_t = typename BasicJsonType::number_float_t;
5940     using string_t = typename BasicJsonType::string_t;
5941     using binary_t = typename BasicJsonType::binary_t;
5942 
5943     /*!
5944     @brief a null value was read
5945     @return whether parsing should proceed
5946     */
5947     virtual bool null() = 0;
5948 
5949     /*!
5950     @brief a boolean value was read
5951     @param[in] val  boolean value
5952     @return whether parsing should proceed
5953     */
5954     virtual bool boolean(bool val) = 0;
5955 
5956     /*!
5957     @brief an integer number was read
5958     @param[in] val  integer value
5959     @return whether parsing should proceed
5960     */
5961     virtual bool number_integer(number_integer_t val) = 0;
5962 
5963     /*!
5964     @brief an unsigned integer number was read
5965     @param[in] val  unsigned integer value
5966     @return whether parsing should proceed
5967     */
5968     virtual bool number_unsigned(number_unsigned_t val) = 0;
5969 
5970     /*!
5971     @brief an floating-point number was read
5972     @param[in] val  floating-point value
5973     @param[in] s    raw token value
5974     @return whether parsing should proceed
5975     */
5976     virtual bool number_float(number_float_t val, const string_t& s) = 0;
5977 
5978     /*!
5979     @brief a string was read
5980     @param[in] val  string value
5981     @return whether parsing should proceed
5982     @note It is safe to move the passed string.
5983     */
5984     virtual bool string(string_t& val) = 0;
5985 
5986     /*!
5987     @brief a binary string was read
5988     @param[in] val  binary value
5989     @return whether parsing should proceed
5990     @note It is safe to move the passed binary.
5991     */
5992     virtual bool binary(binary_t& val) = 0;
5993 
5994     /*!
5995     @brief the beginning of an object was read
5996     @param[in] elements  number of object elements or -1 if unknown
5997     @return whether parsing should proceed
5998     @note binary formats may report the number of elements
5999     */
6000     virtual bool start_object(std::size_t elements) = 0;
6001 
6002     /*!
6003     @brief an object key was read
6004     @param[in] val  object key
6005     @return whether parsing should proceed
6006     @note It is safe to move the passed string.
6007     */
6008     virtual bool key(string_t& val) = 0;
6009 
6010     /*!
6011     @brief the end of an object was read
6012     @return whether parsing should proceed
6013     */
6014     virtual bool end_object() = 0;
6015 
6016     /*!
6017     @brief the beginning of an array was read
6018     @param[in] elements  number of array elements or -1 if unknown
6019     @return whether parsing should proceed
6020     @note binary formats may report the number of elements
6021     */
6022     virtual bool start_array(std::size_t elements) = 0;
6023 
6024     /*!
6025     @brief the end of an array was read
6026     @return whether parsing should proceed
6027     */
6028     virtual bool end_array() = 0;
6029 
6030     /*!
6031     @brief a parse error occurred
6032     @param[in] position    the position in the input where the error occurs
6033     @param[in] last_token  the last read token
6034     @param[in] ex          an exception object describing the error
6035     @return whether parsing should proceed (must return false)
6036     */
6037     virtual bool parse_error(std::size_t position,
6038                              const std::string& last_token,
6039                              const detail::exception& ex) = 0;
6040 
6041     json_sax() = default;
6042     json_sax(const json_sax&) = default;
6043     json_sax(json_sax&&) noexcept = default;
6044     json_sax& operator=(const json_sax&) = default;
6045     json_sax& operator=(json_sax&&) noexcept = default;
6046     virtual ~json_sax() = default;
6047 };
6048 
6049 
6050 namespace detail
6051 {
6052 /*!
6053 @brief SAX implementation to create a JSON value from SAX events
6054 
6055 This class implements the @ref json_sax interface and processes the SAX events
6056 to create a JSON value which makes it basically a DOM parser. The structure or
6057 hierarchy of the JSON value is managed by the stack `ref_stack` which contains
6058 a pointer to the respective array or object for each recursion depth.
6059 
6060 After successful parsing, the value that is passed by reference to the
6061 constructor contains the parsed value.
6062 
6063 @tparam BasicJsonType  the JSON type
6064 */
6065 template<typename BasicJsonType>
6066 class json_sax_dom_parser
6067 {
6068   public:
6069     using number_integer_t = typename BasicJsonType::number_integer_t;
6070     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6071     using number_float_t = typename BasicJsonType::number_float_t;
6072     using string_t = typename BasicJsonType::string_t;
6073     using binary_t = typename BasicJsonType::binary_t;
6074 
6075     /*!
6076     @param[in,out] r  reference to a JSON value that is manipulated while
6077                        parsing
6078     @param[in] allow_exceptions_  whether parse errors yield exceptions
6079     */
json_sax_dom_parser(BasicJsonType & r,const bool allow_exceptions_=true)6080     explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6081         : root(r), allow_exceptions(allow_exceptions_)
6082     {}
6083 
6084     // make class move-only
6085     json_sax_dom_parser(const json_sax_dom_parser&) = delete;
6086     json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6087     json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
6088     json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6089     ~json_sax_dom_parser() = default;
6090 
null()6091     bool null()
6092     {
6093         handle_value(nullptr);
6094         return true;
6095     }
6096 
boolean(bool val)6097     bool boolean(bool val)
6098     {
6099         handle_value(val);
6100         return true;
6101     }
6102 
number_integer(number_integer_t val)6103     bool number_integer(number_integer_t val)
6104     {
6105         handle_value(val);
6106         return true;
6107     }
6108 
number_unsigned(number_unsigned_t val)6109     bool number_unsigned(number_unsigned_t val)
6110     {
6111         handle_value(val);
6112         return true;
6113     }
6114 
number_float(number_float_t val,const string_t &)6115     bool number_float(number_float_t val, const string_t& /*unused*/)
6116     {
6117         handle_value(val);
6118         return true;
6119     }
6120 
string(string_t & val)6121     bool string(string_t& val)
6122     {
6123         handle_value(val);
6124         return true;
6125     }
6126 
binary(binary_t & val)6127     bool binary(binary_t& val)
6128     {
6129         handle_value(std::move(val));
6130         return true;
6131     }
6132 
start_object(std::size_t len)6133     bool start_object(std::size_t len)
6134     {
6135         ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6136 
6137         if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6138         {
6139             JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6140         }
6141 
6142         return true;
6143     }
6144 
key(string_t & val)6145     bool key(string_t& val)
6146     {
6147         // add null at given key and store the reference for later
6148         object_element = &(ref_stack.back()->m_value.object->operator[](val));
6149         return true;
6150     }
6151 
end_object()6152     bool end_object()
6153     {
6154         ref_stack.back()->set_parents();
6155         ref_stack.pop_back();
6156         return true;
6157     }
6158 
start_array(std::size_t len)6159     bool start_array(std::size_t len)
6160     {
6161         ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6162 
6163         if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6164         {
6165             JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6166         }
6167 
6168         return true;
6169     }
6170 
end_array()6171     bool end_array()
6172     {
6173         ref_stack.back()->set_parents();
6174         ref_stack.pop_back();
6175         return true;
6176     }
6177 
6178     template<class Exception>
parse_error(std::size_t,const std::string &,const Exception & ex)6179     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6180                      const Exception& ex)
6181     {
6182         errored = true;
6183         static_cast<void>(ex);
6184         if (allow_exceptions)
6185         {
6186             JSON_THROW(ex);
6187         }
6188         return false;
6189     }
6190 
is_errored() const6191     constexpr bool is_errored() const
6192     {
6193         return errored;
6194     }
6195 
6196   private:
6197     /*!
6198     @invariant If the ref stack is empty, then the passed value will be the new
6199                root.
6200     @invariant If the ref stack contains a value, then it is an array or an
6201                object to which we can add elements
6202     */
6203     template<typename Value>
6204     JSON_HEDLEY_RETURNS_NON_NULL
handle_value(Value && v)6205     BasicJsonType* handle_value(Value&& v)
6206     {
6207         if (ref_stack.empty())
6208         {
6209             root = BasicJsonType(std::forward<Value>(v));
6210             return &root;
6211         }
6212 
6213         JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6214 
6215         if (ref_stack.back()->is_array())
6216         {
6217             ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6218             return &(ref_stack.back()->m_value.array->back());
6219         }
6220 
6221         JSON_ASSERT(ref_stack.back()->is_object());
6222         JSON_ASSERT(object_element);
6223         *object_element = BasicJsonType(std::forward<Value>(v));
6224         return object_element;
6225     }
6226 
6227     /// the parsed JSON value
6228     BasicJsonType& root;
6229     /// stack to model hierarchy of values
6230     std::vector<BasicJsonType*> ref_stack {};
6231     /// helper to hold the reference for the next object element
6232     BasicJsonType* object_element = nullptr;
6233     /// whether a syntax error occurred
6234     bool errored = false;
6235     /// whether to throw exceptions in case of errors
6236     const bool allow_exceptions = true;
6237 };
6238 
6239 template<typename BasicJsonType>
6240 class json_sax_dom_callback_parser
6241 {
6242   public:
6243     using number_integer_t = typename BasicJsonType::number_integer_t;
6244     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6245     using number_float_t = typename BasicJsonType::number_float_t;
6246     using string_t = typename BasicJsonType::string_t;
6247     using binary_t = typename BasicJsonType::binary_t;
6248     using parser_callback_t = typename BasicJsonType::parser_callback_t;
6249     using parse_event_t = typename BasicJsonType::parse_event_t;
6250 
json_sax_dom_callback_parser(BasicJsonType & r,const parser_callback_t cb,const bool allow_exceptions_=true)6251     json_sax_dom_callback_parser(BasicJsonType& r,
6252                                  const parser_callback_t cb,
6253                                  const bool allow_exceptions_ = true)
6254         : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6255     {
6256         keep_stack.push_back(true);
6257     }
6258 
6259     // make class move-only
6260     json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
6261     json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6262     json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
6263     json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6264     ~json_sax_dom_callback_parser() = default;
6265 
null()6266     bool null()
6267     {
6268         handle_value(nullptr);
6269         return true;
6270     }
6271 
boolean(bool val)6272     bool boolean(bool val)
6273     {
6274         handle_value(val);
6275         return true;
6276     }
6277 
number_integer(number_integer_t val)6278     bool number_integer(number_integer_t val)
6279     {
6280         handle_value(val);
6281         return true;
6282     }
6283 
number_unsigned(number_unsigned_t val)6284     bool number_unsigned(number_unsigned_t val)
6285     {
6286         handle_value(val);
6287         return true;
6288     }
6289 
number_float(number_float_t val,const string_t &)6290     bool number_float(number_float_t val, const string_t& /*unused*/)
6291     {
6292         handle_value(val);
6293         return true;
6294     }
6295 
string(string_t & val)6296     bool string(string_t& val)
6297     {
6298         handle_value(val);
6299         return true;
6300     }
6301 
binary(binary_t & val)6302     bool binary(binary_t& val)
6303     {
6304         handle_value(std::move(val));
6305         return true;
6306     }
6307 
start_object(std::size_t len)6308     bool start_object(std::size_t len)
6309     {
6310         // check callback for object start
6311         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6312         keep_stack.push_back(keep);
6313 
6314         auto val = handle_value(BasicJsonType::value_t::object, true);
6315         ref_stack.push_back(val.second);
6316 
6317         // check object limit
6318         if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6319         {
6320             JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6321         }
6322 
6323         return true;
6324     }
6325 
key(string_t & val)6326     bool key(string_t& val)
6327     {
6328         BasicJsonType k = BasicJsonType(val);
6329 
6330         // check callback for key
6331         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6332         key_keep_stack.push_back(keep);
6333 
6334         // add discarded value at given key and store the reference for later
6335         if (keep && ref_stack.back())
6336         {
6337             object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6338         }
6339 
6340         return true;
6341     }
6342 
end_object()6343     bool end_object()
6344     {
6345         if (ref_stack.back())
6346         {
6347             if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6348             {
6349                 // discard object
6350                 *ref_stack.back() = discarded;
6351             }
6352             else
6353             {
6354                 ref_stack.back()->set_parents();
6355             }
6356         }
6357 
6358         JSON_ASSERT(!ref_stack.empty());
6359         JSON_ASSERT(!keep_stack.empty());
6360         ref_stack.pop_back();
6361         keep_stack.pop_back();
6362 
6363         if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6364         {
6365             // remove discarded value
6366             for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6367             {
6368                 if (it->is_discarded())
6369                 {
6370                     ref_stack.back()->erase(it);
6371                     break;
6372                 }
6373             }
6374         }
6375 
6376         return true;
6377     }
6378 
start_array(std::size_t len)6379     bool start_array(std::size_t len)
6380     {
6381         const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6382         keep_stack.push_back(keep);
6383 
6384         auto val = handle_value(BasicJsonType::value_t::array, true);
6385         ref_stack.push_back(val.second);
6386 
6387         // check array limit
6388         if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6389         {
6390             JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6391         }
6392 
6393         return true;
6394     }
6395 
end_array()6396     bool end_array()
6397     {
6398         bool keep = true;
6399 
6400         if (ref_stack.back())
6401         {
6402             keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6403             if (keep)
6404             {
6405                 ref_stack.back()->set_parents();
6406             }
6407             else
6408             {
6409                 // discard array
6410                 *ref_stack.back() = discarded;
6411             }
6412         }
6413 
6414         JSON_ASSERT(!ref_stack.empty());
6415         JSON_ASSERT(!keep_stack.empty());
6416         ref_stack.pop_back();
6417         keep_stack.pop_back();
6418 
6419         // remove discarded value
6420         if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6421         {
6422             ref_stack.back()->m_value.array->pop_back();
6423         }
6424 
6425         return true;
6426     }
6427 
6428     template<class Exception>
parse_error(std::size_t,const std::string &,const Exception & ex)6429     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6430                      const Exception& ex)
6431     {
6432         errored = true;
6433         static_cast<void>(ex);
6434         if (allow_exceptions)
6435         {
6436             JSON_THROW(ex);
6437         }
6438         return false;
6439     }
6440 
is_errored() const6441     constexpr bool is_errored() const
6442     {
6443         return errored;
6444     }
6445 
6446   private:
6447     /*!
6448     @param[in] v  value to add to the JSON value we build during parsing
6449     @param[in] skip_callback  whether we should skip calling the callback
6450                function; this is required after start_array() and
6451                start_object() SAX events, because otherwise we would call the
6452                callback function with an empty array or object, respectively.
6453 
6454     @invariant If the ref stack is empty, then the passed value will be the new
6455                root.
6456     @invariant If the ref stack contains a value, then it is an array or an
6457                object to which we can add elements
6458 
6459     @return pair of boolean (whether value should be kept) and pointer (to the
6460             passed value in the ref_stack hierarchy; nullptr if not kept)
6461     */
6462     template<typename Value>
handle_value(Value && v,const bool skip_callback=false)6463     std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6464     {
6465         JSON_ASSERT(!keep_stack.empty());
6466 
6467         // do not handle this value if we know it would be added to a discarded
6468         // container
6469         if (!keep_stack.back())
6470         {
6471             return {false, nullptr};
6472         }
6473 
6474         // create value
6475         auto value = BasicJsonType(std::forward<Value>(v));
6476 
6477         // check callback
6478         const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6479 
6480         // do not handle this value if we just learnt it shall be discarded
6481         if (!keep)
6482         {
6483             return {false, nullptr};
6484         }
6485 
6486         if (ref_stack.empty())
6487         {
6488             root = std::move(value);
6489             return {true, &root};
6490         }
6491 
6492         // skip this value if we already decided to skip the parent
6493         // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6494         if (!ref_stack.back())
6495         {
6496             return {false, nullptr};
6497         }
6498 
6499         // we now only expect arrays and objects
6500         JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6501 
6502         // array
6503         if (ref_stack.back()->is_array())
6504         {
6505             ref_stack.back()->m_value.array->emplace_back(std::move(value));
6506             return {true, &(ref_stack.back()->m_value.array->back())};
6507         }
6508 
6509         // object
6510         JSON_ASSERT(ref_stack.back()->is_object());
6511         // check if we should store an element for the current key
6512         JSON_ASSERT(!key_keep_stack.empty());
6513         const bool store_element = key_keep_stack.back();
6514         key_keep_stack.pop_back();
6515 
6516         if (!store_element)
6517         {
6518             return {false, nullptr};
6519         }
6520 
6521         JSON_ASSERT(object_element);
6522         *object_element = std::move(value);
6523         return {true, object_element};
6524     }
6525 
6526     /// the parsed JSON value
6527     BasicJsonType& root;
6528     /// stack to model hierarchy of values
6529     std::vector<BasicJsonType*> ref_stack {};
6530     /// stack to manage which values to keep
6531     std::vector<bool> keep_stack {};
6532     /// stack to manage which object keys to keep
6533     std::vector<bool> key_keep_stack {};
6534     /// helper to hold the reference for the next object element
6535     BasicJsonType* object_element = nullptr;
6536     /// whether a syntax error occurred
6537     bool errored = false;
6538     /// callback function
6539     const parser_callback_t callback = nullptr;
6540     /// whether to throw exceptions in case of errors
6541     const bool allow_exceptions = true;
6542     /// a discarded value for the callback
6543     BasicJsonType discarded = BasicJsonType::value_t::discarded;
6544 };
6545 
6546 template<typename BasicJsonType>
6547 class json_sax_acceptor
6548 {
6549   public:
6550     using number_integer_t = typename BasicJsonType::number_integer_t;
6551     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6552     using number_float_t = typename BasicJsonType::number_float_t;
6553     using string_t = typename BasicJsonType::string_t;
6554     using binary_t = typename BasicJsonType::binary_t;
6555 
null()6556     bool null()
6557     {
6558         return true;
6559     }
6560 
boolean(bool)6561     bool boolean(bool /*unused*/)
6562     {
6563         return true;
6564     }
6565 
number_integer(number_integer_t)6566     bool number_integer(number_integer_t /*unused*/)
6567     {
6568         return true;
6569     }
6570 
number_unsigned(number_unsigned_t)6571     bool number_unsigned(number_unsigned_t /*unused*/)
6572     {
6573         return true;
6574     }
6575 
number_float(number_float_t,const string_t &)6576     bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6577     {
6578         return true;
6579     }
6580 
string(string_t &)6581     bool string(string_t& /*unused*/)
6582     {
6583         return true;
6584     }
6585 
binary(binary_t &)6586     bool binary(binary_t& /*unused*/)
6587     {
6588         return true;
6589     }
6590 
start_object(std::size_t=std::size_t (-1))6591     bool start_object(std::size_t /*unused*/ = std::size_t(-1))
6592     {
6593         return true;
6594     }
6595 
key(string_t &)6596     bool key(string_t& /*unused*/)
6597     {
6598         return true;
6599     }
6600 
end_object()6601     bool end_object()
6602     {
6603         return true;
6604     }
6605 
start_array(std::size_t=std::size_t (-1))6606     bool start_array(std::size_t /*unused*/ = std::size_t(-1))
6607     {
6608         return true;
6609     }
6610 
end_array()6611     bool end_array()
6612     {
6613         return true;
6614     }
6615 
parse_error(std::size_t,const std::string &,const detail::exception &)6616     bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6617     {
6618         return false;
6619     }
6620 };
6621 }  // namespace detail
6622 
6623 }  // namespace nlohmann
6624 
6625 // #include <nlohmann/detail/input/lexer.hpp>
6626 
6627 
6628 #include <array> // array
6629 #include <clocale> // localeconv
6630 #include <cstddef> // size_t
6631 #include <cstdio> // snprintf
6632 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6633 #include <initializer_list> // initializer_list
6634 #include <string> // char_traits, string
6635 #include <utility> // move
6636 #include <vector> // vector
6637 
6638 // #include <nlohmann/detail/input/input_adapters.hpp>
6639 
6640 // #include <nlohmann/detail/input/position_t.hpp>
6641 
6642 // #include <nlohmann/detail/macro_scope.hpp>
6643 
6644 
6645 namespace nlohmann
6646 {
6647 namespace detail
6648 {
6649 ///////////
6650 // lexer //
6651 ///////////
6652 
6653 template<typename BasicJsonType>
6654 class lexer_base
6655 {
6656   public:
6657     /// token types for the parser
6658     enum class token_type
6659     {
6660         uninitialized,    ///< indicating the scanner is uninitialized
6661         literal_true,     ///< the `true` literal
6662         literal_false,    ///< the `false` literal
6663         literal_null,     ///< the `null` literal
6664         value_string,     ///< a string -- use get_string() for actual value
6665         value_unsigned,   ///< an unsigned integer -- use get_number_unsigned() for actual value
6666         value_integer,    ///< a signed integer -- use get_number_integer() for actual value
6667         value_float,      ///< an floating point number -- use get_number_float() for actual value
6668         begin_array,      ///< the character for array begin `[`
6669         begin_object,     ///< the character for object begin `{`
6670         end_array,        ///< the character for array end `]`
6671         end_object,       ///< the character for object end `}`
6672         name_separator,   ///< the name separator `:`
6673         value_separator,  ///< the value separator `,`
6674         parse_error,      ///< indicating a parse error
6675         end_of_input,     ///< indicating the end of the input buffer
6676         literal_or_value  ///< a literal or the begin of a value (only for diagnostics)
6677     };
6678 
6679     /// return name of values of type token_type (only used for errors)
6680     JSON_HEDLEY_RETURNS_NON_NULL
6681     JSON_HEDLEY_CONST
token_type_name(const token_type t)6682     static const char* token_type_name(const token_type t) noexcept
6683     {
6684         switch (t)
6685         {
6686             case token_type::uninitialized:
6687                 return "<uninitialized>";
6688             case token_type::literal_true:
6689                 return "true literal";
6690             case token_type::literal_false:
6691                 return "false literal";
6692             case token_type::literal_null:
6693                 return "null literal";
6694             case token_type::value_string:
6695                 return "string literal";
6696             case token_type::value_unsigned:
6697             case token_type::value_integer:
6698             case token_type::value_float:
6699                 return "number literal";
6700             case token_type::begin_array:
6701                 return "'['";
6702             case token_type::begin_object:
6703                 return "'{'";
6704             case token_type::end_array:
6705                 return "']'";
6706             case token_type::end_object:
6707                 return "'}'";
6708             case token_type::name_separator:
6709                 return "':'";
6710             case token_type::value_separator:
6711                 return "','";
6712             case token_type::parse_error:
6713                 return "<parse error>";
6714             case token_type::end_of_input:
6715                 return "end of input";
6716             case token_type::literal_or_value:
6717                 return "'[', '{', or a literal";
6718             // LCOV_EXCL_START
6719             default: // catch non-enum values
6720                 return "unknown token";
6721                 // LCOV_EXCL_STOP
6722         }
6723     }
6724 };
6725 /*!
6726 @brief lexical analysis
6727 
6728 This class organizes the lexical analysis during JSON deserialization.
6729 */
6730 template<typename BasicJsonType, typename InputAdapterType>
6731 class lexer : public lexer_base<BasicJsonType>
6732 {
6733     using number_integer_t = typename BasicJsonType::number_integer_t;
6734     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6735     using number_float_t = typename BasicJsonType::number_float_t;
6736     using string_t = typename BasicJsonType::string_t;
6737     using char_type = typename InputAdapterType::char_type;
6738     using char_int_type = typename std::char_traits<char_type>::int_type;
6739 
6740   public:
6741     using token_type = typename lexer_base<BasicJsonType>::token_type;
6742 
lexer(InputAdapterType && adapter,bool ignore_comments_=false)6743     explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6744         : ia(std::move(adapter))
6745         , ignore_comments(ignore_comments_)
6746         , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6747     {}
6748 
6749     // delete because of pointer members
6750     lexer(const lexer&) = delete;
6751     lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6752     lexer& operator=(lexer&) = delete;
6753     lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6754     ~lexer() = default;
6755 
6756   private:
6757     /////////////////////
6758     // locales
6759     /////////////////////
6760 
6761     /// return the locale-dependent decimal point
6762     JSON_HEDLEY_PURE
get_decimal_point()6763     static char get_decimal_point() noexcept
6764     {
6765         const auto* loc = localeconv();
6766         JSON_ASSERT(loc != nullptr);
6767         return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6768     }
6769 
6770     /////////////////////
6771     // scan functions
6772     /////////////////////
6773 
6774     /*!
6775     @brief get codepoint from 4 hex characters following `\u`
6776 
6777     For input "\u c1 c2 c3 c4" the codepoint is:
6778       (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
6779     = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
6780 
6781     Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f'
6782     must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The
6783     conversion is done by subtracting the offset (0x30, 0x37, and 0x57)
6784     between the ASCII value of the character and the desired integer value.
6785 
6786     @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or
6787             non-hex character)
6788     */
get_codepoint()6789     int get_codepoint()
6790     {
6791         // this function only makes sense after reading `\u`
6792         JSON_ASSERT(current == 'u');
6793         int codepoint = 0;
6794 
6795         const auto factors = { 12u, 8u, 4u, 0u };
6796         for (const auto factor : factors)
6797         {
6798             get();
6799 
6800             if (current >= '0' && current <= '9')
6801             {
6802                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6803             }
6804             else if (current >= 'A' && current <= 'F')
6805             {
6806                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6807             }
6808             else if (current >= 'a' && current <= 'f')
6809             {
6810                 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6811             }
6812             else
6813             {
6814                 return -1;
6815             }
6816         }
6817 
6818         JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6819         return codepoint;
6820     }
6821 
6822     /*!
6823     @brief check if the next byte(s) are inside a given range
6824 
6825     Adds the current byte and, for each passed range, reads a new byte and
6826     checks if it is inside the range. If a violation was detected, set up an
6827     error message and return false. Otherwise, return true.
6828 
6829     @param[in] ranges  list of integers; interpreted as list of pairs of
6830                        inclusive lower and upper bound, respectively
6831 
6832     @pre The passed list @a ranges must have 2, 4, or 6 elements; that is,
6833          1, 2, or 3 pairs. This precondition is enforced by an assertion.
6834 
6835     @return true if and only if no range violation was detected
6836     */
next_byte_in_range(std::initializer_list<char_int_type> ranges)6837     bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6838     {
6839         JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6840         add(current);
6841 
6842         for (auto range = ranges.begin(); range != ranges.end(); ++range)
6843         {
6844             get();
6845             if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6846             {
6847                 add(current);
6848             }
6849             else
6850             {
6851                 error_message = "invalid string: ill-formed UTF-8 byte";
6852                 return false;
6853             }
6854         }
6855 
6856         return true;
6857     }
6858 
6859     /*!
6860     @brief scan a string literal
6861 
6862     This function scans a string according to Sect. 7 of RFC 8259. While
6863     scanning, bytes are escaped and copied into buffer token_buffer. Then the
6864     function returns successfully, token_buffer is *not* null-terminated (as it
6865     may contain \0 bytes), and token_buffer.size() is the number of bytes in the
6866     string.
6867 
6868     @return token_type::value_string if string could be successfully scanned,
6869             token_type::parse_error otherwise
6870 
6871     @note In case of errors, variable error_message contains a textual
6872           description.
6873     */
scan_string()6874     token_type scan_string()
6875     {
6876         // reset token_buffer (ignore opening quote)
6877         reset();
6878 
6879         // we entered the function by reading an open quote
6880         JSON_ASSERT(current == '\"');
6881 
6882         while (true)
6883         {
6884             // get next character
6885             switch (get())
6886             {
6887                 // end of file while parsing string
6888                 case std::char_traits<char_type>::eof():
6889                 {
6890                     error_message = "invalid string: missing closing quote";
6891                     return token_type::parse_error;
6892                 }
6893 
6894                 // closing quote
6895                 case '\"':
6896                 {
6897                     return token_type::value_string;
6898                 }
6899 
6900                 // escapes
6901                 case '\\':
6902                 {
6903                     switch (get())
6904                     {
6905                         // quotation mark
6906                         case '\"':
6907                             add('\"');
6908                             break;
6909                         // reverse solidus
6910                         case '\\':
6911                             add('\\');
6912                             break;
6913                         // solidus
6914                         case '/':
6915                             add('/');
6916                             break;
6917                         // backspace
6918                         case 'b':
6919                             add('\b');
6920                             break;
6921                         // form feed
6922                         case 'f':
6923                             add('\f');
6924                             break;
6925                         // line feed
6926                         case 'n':
6927                             add('\n');
6928                             break;
6929                         // carriage return
6930                         case 'r':
6931                             add('\r');
6932                             break;
6933                         // tab
6934                         case 't':
6935                             add('\t');
6936                             break;
6937 
6938                         // unicode escapes
6939                         case 'u':
6940                         {
6941                             const int codepoint1 = get_codepoint();
6942                             int codepoint = codepoint1; // start with codepoint1
6943 
6944                             if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6945                             {
6946                                 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6947                                 return token_type::parse_error;
6948                             }
6949 
6950                             // check if code point is a high surrogate
6951                             if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6952                             {
6953                                 // expect next \uxxxx entry
6954                                 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6955                                 {
6956                                     const int codepoint2 = get_codepoint();
6957 
6958                                     if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6959                                     {
6960                                         error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6961                                         return token_type::parse_error;
6962                                     }
6963 
6964                                     // check if codepoint2 is a low surrogate
6965                                     if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6966                                     {
6967                                         // overwrite codepoint
6968                                         codepoint = static_cast<int>(
6969                                                         // high surrogate occupies the most significant 22 bits
6970                                                         (static_cast<unsigned int>(codepoint1) << 10u)
6971                                                         // low surrogate occupies the least significant 15 bits
6972                                                         + static_cast<unsigned int>(codepoint2)
6973                                                         // there is still the 0xD800, 0xDC00 and 0x10000 noise
6974                                                         // in the result so we have to subtract with:
6975                                                         // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6976                                                         - 0x35FDC00u);
6977                                     }
6978                                     else
6979                                     {
6980                                         error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6981                                         return token_type::parse_error;
6982                                     }
6983                                 }
6984                                 else
6985                                 {
6986                                     error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6987                                     return token_type::parse_error;
6988                                 }
6989                             }
6990                             else
6991                             {
6992                                 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6993                                 {
6994                                     error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6995                                     return token_type::parse_error;
6996                                 }
6997                             }
6998 
6999                             // result of the above calculation yields a proper codepoint
7000                             JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7001 
7002                             // translate codepoint into bytes
7003                             if (codepoint < 0x80)
7004                             {
7005                                 // 1-byte characters: 0xxxxxxx (ASCII)
7006                                 add(static_cast<char_int_type>(codepoint));
7007                             }
7008                             else if (codepoint <= 0x7FF)
7009                             {
7010                                 // 2-byte characters: 110xxxxx 10xxxxxx
7011                                 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7012                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7013                             }
7014                             else if (codepoint <= 0xFFFF)
7015                             {
7016                                 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7017                                 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7018                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7019                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7020                             }
7021                             else
7022                             {
7023                                 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7024                                 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7025                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7026                                 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7027                                 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7028                             }
7029 
7030                             break;
7031                         }
7032 
7033                         // other characters after escape
7034                         default:
7035                             error_message = "invalid string: forbidden character after backslash";
7036                             return token_type::parse_error;
7037                     }
7038 
7039                     break;
7040                 }
7041 
7042                 // invalid control characters
7043                 case 0x00:
7044                 {
7045                     error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7046                     return token_type::parse_error;
7047                 }
7048 
7049                 case 0x01:
7050                 {
7051                     error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7052                     return token_type::parse_error;
7053                 }
7054 
7055                 case 0x02:
7056                 {
7057                     error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7058                     return token_type::parse_error;
7059                 }
7060 
7061                 case 0x03:
7062                 {
7063                     error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7064                     return token_type::parse_error;
7065                 }
7066 
7067                 case 0x04:
7068                 {
7069                     error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7070                     return token_type::parse_error;
7071                 }
7072 
7073                 case 0x05:
7074                 {
7075                     error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7076                     return token_type::parse_error;
7077                 }
7078 
7079                 case 0x06:
7080                 {
7081                     error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7082                     return token_type::parse_error;
7083                 }
7084 
7085                 case 0x07:
7086                 {
7087                     error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7088                     return token_type::parse_error;
7089                 }
7090 
7091                 case 0x08:
7092                 {
7093                     error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7094                     return token_type::parse_error;
7095                 }
7096 
7097                 case 0x09:
7098                 {
7099                     error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7100                     return token_type::parse_error;
7101                 }
7102 
7103                 case 0x0A:
7104                 {
7105                     error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7106                     return token_type::parse_error;
7107                 }
7108 
7109                 case 0x0B:
7110                 {
7111                     error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7112                     return token_type::parse_error;
7113                 }
7114 
7115                 case 0x0C:
7116                 {
7117                     error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7118                     return token_type::parse_error;
7119                 }
7120 
7121                 case 0x0D:
7122                 {
7123                     error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7124                     return token_type::parse_error;
7125                 }
7126 
7127                 case 0x0E:
7128                 {
7129                     error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7130                     return token_type::parse_error;
7131                 }
7132 
7133                 case 0x0F:
7134                 {
7135                     error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7136                     return token_type::parse_error;
7137                 }
7138 
7139                 case 0x10:
7140                 {
7141                     error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7142                     return token_type::parse_error;
7143                 }
7144 
7145                 case 0x11:
7146                 {
7147                     error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7148                     return token_type::parse_error;
7149                 }
7150 
7151                 case 0x12:
7152                 {
7153                     error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7154                     return token_type::parse_error;
7155                 }
7156 
7157                 case 0x13:
7158                 {
7159                     error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7160                     return token_type::parse_error;
7161                 }
7162 
7163                 case 0x14:
7164                 {
7165                     error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7166                     return token_type::parse_error;
7167                 }
7168 
7169                 case 0x15:
7170                 {
7171                     error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7172                     return token_type::parse_error;
7173                 }
7174 
7175                 case 0x16:
7176                 {
7177                     error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7178                     return token_type::parse_error;
7179                 }
7180 
7181                 case 0x17:
7182                 {
7183                     error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7184                     return token_type::parse_error;
7185                 }
7186 
7187                 case 0x18:
7188                 {
7189                     error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7190                     return token_type::parse_error;
7191                 }
7192 
7193                 case 0x19:
7194                 {
7195                     error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7196                     return token_type::parse_error;
7197                 }
7198 
7199                 case 0x1A:
7200                 {
7201                     error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7202                     return token_type::parse_error;
7203                 }
7204 
7205                 case 0x1B:
7206                 {
7207                     error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7208                     return token_type::parse_error;
7209                 }
7210 
7211                 case 0x1C:
7212                 {
7213                     error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7214                     return token_type::parse_error;
7215                 }
7216 
7217                 case 0x1D:
7218                 {
7219                     error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7220                     return token_type::parse_error;
7221                 }
7222 
7223                 case 0x1E:
7224                 {
7225                     error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7226                     return token_type::parse_error;
7227                 }
7228 
7229                 case 0x1F:
7230                 {
7231                     error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7232                     return token_type::parse_error;
7233                 }
7234 
7235                 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7236                 case 0x20:
7237                 case 0x21:
7238                 case 0x23:
7239                 case 0x24:
7240                 case 0x25:
7241                 case 0x26:
7242                 case 0x27:
7243                 case 0x28:
7244                 case 0x29:
7245                 case 0x2A:
7246                 case 0x2B:
7247                 case 0x2C:
7248                 case 0x2D:
7249                 case 0x2E:
7250                 case 0x2F:
7251                 case 0x30:
7252                 case 0x31:
7253                 case 0x32:
7254                 case 0x33:
7255                 case 0x34:
7256                 case 0x35:
7257                 case 0x36:
7258                 case 0x37:
7259                 case 0x38:
7260                 case 0x39:
7261                 case 0x3A:
7262                 case 0x3B:
7263                 case 0x3C:
7264                 case 0x3D:
7265                 case 0x3E:
7266                 case 0x3F:
7267                 case 0x40:
7268                 case 0x41:
7269                 case 0x42:
7270                 case 0x43:
7271                 case 0x44:
7272                 case 0x45:
7273                 case 0x46:
7274                 case 0x47:
7275                 case 0x48:
7276                 case 0x49:
7277                 case 0x4A:
7278                 case 0x4B:
7279                 case 0x4C:
7280                 case 0x4D:
7281                 case 0x4E:
7282                 case 0x4F:
7283                 case 0x50:
7284                 case 0x51:
7285                 case 0x52:
7286                 case 0x53:
7287                 case 0x54:
7288                 case 0x55:
7289                 case 0x56:
7290                 case 0x57:
7291                 case 0x58:
7292                 case 0x59:
7293                 case 0x5A:
7294                 case 0x5B:
7295                 case 0x5D:
7296                 case 0x5E:
7297                 case 0x5F:
7298                 case 0x60:
7299                 case 0x61:
7300                 case 0x62:
7301                 case 0x63:
7302                 case 0x64:
7303                 case 0x65:
7304                 case 0x66:
7305                 case 0x67:
7306                 case 0x68:
7307                 case 0x69:
7308                 case 0x6A:
7309                 case 0x6B:
7310                 case 0x6C:
7311                 case 0x6D:
7312                 case 0x6E:
7313                 case 0x6F:
7314                 case 0x70:
7315                 case 0x71:
7316                 case 0x72:
7317                 case 0x73:
7318                 case 0x74:
7319                 case 0x75:
7320                 case 0x76:
7321                 case 0x77:
7322                 case 0x78:
7323                 case 0x79:
7324                 case 0x7A:
7325                 case 0x7B:
7326                 case 0x7C:
7327                 case 0x7D:
7328                 case 0x7E:
7329                 case 0x7F:
7330                 {
7331                     add(current);
7332                     break;
7333                 }
7334 
7335                 // U+0080..U+07FF: bytes C2..DF 80..BF
7336                 case 0xC2:
7337                 case 0xC3:
7338                 case 0xC4:
7339                 case 0xC5:
7340                 case 0xC6:
7341                 case 0xC7:
7342                 case 0xC8:
7343                 case 0xC9:
7344                 case 0xCA:
7345                 case 0xCB:
7346                 case 0xCC:
7347                 case 0xCD:
7348                 case 0xCE:
7349                 case 0xCF:
7350                 case 0xD0:
7351                 case 0xD1:
7352                 case 0xD2:
7353                 case 0xD3:
7354                 case 0xD4:
7355                 case 0xD5:
7356                 case 0xD6:
7357                 case 0xD7:
7358                 case 0xD8:
7359                 case 0xD9:
7360                 case 0xDA:
7361                 case 0xDB:
7362                 case 0xDC:
7363                 case 0xDD:
7364                 case 0xDE:
7365                 case 0xDF:
7366                 {
7367                     if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7368                     {
7369                         return token_type::parse_error;
7370                     }
7371                     break;
7372                 }
7373 
7374                 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7375                 case 0xE0:
7376                 {
7377                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7378                     {
7379                         return token_type::parse_error;
7380                     }
7381                     break;
7382                 }
7383 
7384                 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7385                 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7386                 case 0xE1:
7387                 case 0xE2:
7388                 case 0xE3:
7389                 case 0xE4:
7390                 case 0xE5:
7391                 case 0xE6:
7392                 case 0xE7:
7393                 case 0xE8:
7394                 case 0xE9:
7395                 case 0xEA:
7396                 case 0xEB:
7397                 case 0xEC:
7398                 case 0xEE:
7399                 case 0xEF:
7400                 {
7401                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7402                     {
7403                         return token_type::parse_error;
7404                     }
7405                     break;
7406                 }
7407 
7408                 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7409                 case 0xED:
7410                 {
7411                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7412                     {
7413                         return token_type::parse_error;
7414                     }
7415                     break;
7416                 }
7417 
7418                 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7419                 case 0xF0:
7420                 {
7421                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7422                     {
7423                         return token_type::parse_error;
7424                     }
7425                     break;
7426                 }
7427 
7428                 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7429                 case 0xF1:
7430                 case 0xF2:
7431                 case 0xF3:
7432                 {
7433                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7434                     {
7435                         return token_type::parse_error;
7436                     }
7437                     break;
7438                 }
7439 
7440                 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7441                 case 0xF4:
7442                 {
7443                     if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7444                     {
7445                         return token_type::parse_error;
7446                     }
7447                     break;
7448                 }
7449 
7450                 // remaining bytes (80..C1 and F5..FF) are ill-formed
7451                 default:
7452                 {
7453                     error_message = "invalid string: ill-formed UTF-8 byte";
7454                     return token_type::parse_error;
7455                 }
7456             }
7457         }
7458     }
7459 
7460     /*!
7461      * @brief scan a comment
7462      * @return whether comment could be scanned successfully
7463      */
scan_comment()7464     bool scan_comment()
7465     {
7466         switch (get())
7467         {
7468             // single-line comments skip input until a newline or EOF is read
7469             case '/':
7470             {
7471                 while (true)
7472                 {
7473                     switch (get())
7474                     {
7475                         case '\n':
7476                         case '\r':
7477                         case std::char_traits<char_type>::eof():
7478                         case '\0':
7479                             return true;
7480 
7481                         default:
7482                             break;
7483                     }
7484                 }
7485             }
7486 
7487             // multi-line comments skip input until */ is read
7488             case '*':
7489             {
7490                 while (true)
7491                 {
7492                     switch (get())
7493                     {
7494                         case std::char_traits<char_type>::eof():
7495                         case '\0':
7496                         {
7497                             error_message = "invalid comment; missing closing '*/'";
7498                             return false;
7499                         }
7500 
7501                         case '*':
7502                         {
7503                             switch (get())
7504                             {
7505                                 case '/':
7506                                     return true;
7507 
7508                                 default:
7509                                 {
7510                                     unget();
7511                                     continue;
7512                                 }
7513                             }
7514                         }
7515 
7516                         default:
7517                             continue;
7518                     }
7519                 }
7520             }
7521 
7522             // unexpected character after reading '/'
7523             default:
7524             {
7525                 error_message = "invalid comment; expecting '/' or '*' after '/'";
7526                 return false;
7527             }
7528         }
7529     }
7530 
7531     JSON_HEDLEY_NON_NULL(2)
strtof(float & f,const char * str,char ** endptr)7532     static void strtof(float& f, const char* str, char** endptr) noexcept
7533     {
7534         f = std::strtof(str, endptr);
7535     }
7536 
7537     JSON_HEDLEY_NON_NULL(2)
strtof(double & f,const char * str,char ** endptr)7538     static void strtof(double& f, const char* str, char** endptr) noexcept
7539     {
7540         f = std::strtod(str, endptr);
7541     }
7542 
7543     JSON_HEDLEY_NON_NULL(2)
strtof(long double & f,const char * str,char ** endptr)7544     static void strtof(long double& f, const char* str, char** endptr) noexcept
7545     {
7546         f = std::strtold(str, endptr);
7547     }
7548 
7549     /*!
7550     @brief scan a number literal
7551 
7552     This function scans a string according to Sect. 6 of RFC 8259.
7553 
7554     The function is realized with a deterministic finite state machine derived
7555     from the grammar described in RFC 8259. Starting in state "init", the
7556     input is read and used to determined the next state. Only state "done"
7557     accepts the number. State "error" is a trap state to model errors. In the
7558     table below, "anything" means any character but the ones listed before.
7559 
7560     state    | 0        | 1-9      | e E      | +       | -       | .        | anything
7561     ---------|----------|----------|----------|---------|---------|----------|-----------
7562     init     | zero     | any1     | [error]  | [error] | minus   | [error]  | [error]
7563     minus    | zero     | any1     | [error]  | [error] | [error] | [error]  | [error]
7564     zero     | done     | done     | exponent | done    | done    | decimal1 | done
7565     any1     | any1     | any1     | exponent | done    | done    | decimal1 | done
7566     decimal1 | decimal2 | decimal2 | [error]  | [error] | [error] | [error]  | [error]
7567     decimal2 | decimal2 | decimal2 | exponent | done    | done    | done     | done
7568     exponent | any2     | any2     | [error]  | sign    | sign    | [error]  | [error]
7569     sign     | any2     | any2     | [error]  | [error] | [error] | [error]  | [error]
7570     any2     | any2     | any2     | done     | done    | done    | done     | done
7571 
7572     The state machine is realized with one label per state (prefixed with
7573     "scan_number_") and `goto` statements between them. The state machine
7574     contains cycles, but any cycle can be left when EOF is read. Therefore,
7575     the function is guaranteed to terminate.
7576 
7577     During scanning, the read bytes are stored in token_buffer. This string is
7578     then converted to a signed integer, an unsigned integer, or a
7579     floating-point number.
7580 
7581     @return token_type::value_unsigned, token_type::value_integer, or
7582             token_type::value_float if number could be successfully scanned,
7583             token_type::parse_error otherwise
7584 
7585     @note The scanner is independent of the current locale. Internally, the
7586           locale's decimal point is used instead of `.` to work with the
7587           locale-dependent converters.
7588     */
scan_number()7589     token_type scan_number()  // lgtm [cpp/use-of-goto]
7590     {
7591         // reset token_buffer to store the number's bytes
7592         reset();
7593 
7594         // the type of the parsed number; initially set to unsigned; will be
7595         // changed if minus sign, decimal point or exponent is read
7596         token_type number_type = token_type::value_unsigned;
7597 
7598         // state (init): we just found out we need to scan a number
7599         switch (current)
7600         {
7601             case '-':
7602             {
7603                 add(current);
7604                 goto scan_number_minus;
7605             }
7606 
7607             case '0':
7608             {
7609                 add(current);
7610                 goto scan_number_zero;
7611             }
7612 
7613             case '1':
7614             case '2':
7615             case '3':
7616             case '4':
7617             case '5':
7618             case '6':
7619             case '7':
7620             case '8':
7621             case '9':
7622             {
7623                 add(current);
7624                 goto scan_number_any1;
7625             }
7626 
7627             // all other characters are rejected outside scan_number()
7628             default:            // LCOV_EXCL_LINE
7629                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7630         }
7631 
7632 scan_number_minus:
7633         // state: we just parsed a leading minus sign
7634         number_type = token_type::value_integer;
7635         switch (get())
7636         {
7637             case '0':
7638             {
7639                 add(current);
7640                 goto scan_number_zero;
7641             }
7642 
7643             case '1':
7644             case '2':
7645             case '3':
7646             case '4':
7647             case '5':
7648             case '6':
7649             case '7':
7650             case '8':
7651             case '9':
7652             {
7653                 add(current);
7654                 goto scan_number_any1;
7655             }
7656 
7657             default:
7658             {
7659                 error_message = "invalid number; expected digit after '-'";
7660                 return token_type::parse_error;
7661             }
7662         }
7663 
7664 scan_number_zero:
7665         // state: we just parse a zero (maybe with a leading minus sign)
7666         switch (get())
7667         {
7668             case '.':
7669             {
7670                 add(decimal_point_char);
7671                 goto scan_number_decimal1;
7672             }
7673 
7674             case 'e':
7675             case 'E':
7676             {
7677                 add(current);
7678                 goto scan_number_exponent;
7679             }
7680 
7681             default:
7682                 goto scan_number_done;
7683         }
7684 
7685 scan_number_any1:
7686         // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7687         switch (get())
7688         {
7689             case '0':
7690             case '1':
7691             case '2':
7692             case '3':
7693             case '4':
7694             case '5':
7695             case '6':
7696             case '7':
7697             case '8':
7698             case '9':
7699             {
7700                 add(current);
7701                 goto scan_number_any1;
7702             }
7703 
7704             case '.':
7705             {
7706                 add(decimal_point_char);
7707                 goto scan_number_decimal1;
7708             }
7709 
7710             case 'e':
7711             case 'E':
7712             {
7713                 add(current);
7714                 goto scan_number_exponent;
7715             }
7716 
7717             default:
7718                 goto scan_number_done;
7719         }
7720 
7721 scan_number_decimal1:
7722         // state: we just parsed a decimal point
7723         number_type = token_type::value_float;
7724         switch (get())
7725         {
7726             case '0':
7727             case '1':
7728             case '2':
7729             case '3':
7730             case '4':
7731             case '5':
7732             case '6':
7733             case '7':
7734             case '8':
7735             case '9':
7736             {
7737                 add(current);
7738                 goto scan_number_decimal2;
7739             }
7740 
7741             default:
7742             {
7743                 error_message = "invalid number; expected digit after '.'";
7744                 return token_type::parse_error;
7745             }
7746         }
7747 
7748 scan_number_decimal2:
7749         // we just parsed at least one number after a decimal point
7750         switch (get())
7751         {
7752             case '0':
7753             case '1':
7754             case '2':
7755             case '3':
7756             case '4':
7757             case '5':
7758             case '6':
7759             case '7':
7760             case '8':
7761             case '9':
7762             {
7763                 add(current);
7764                 goto scan_number_decimal2;
7765             }
7766 
7767             case 'e':
7768             case 'E':
7769             {
7770                 add(current);
7771                 goto scan_number_exponent;
7772             }
7773 
7774             default:
7775                 goto scan_number_done;
7776         }
7777 
7778 scan_number_exponent:
7779         // we just parsed an exponent
7780         number_type = token_type::value_float;
7781         switch (get())
7782         {
7783             case '+':
7784             case '-':
7785             {
7786                 add(current);
7787                 goto scan_number_sign;
7788             }
7789 
7790             case '0':
7791             case '1':
7792             case '2':
7793             case '3':
7794             case '4':
7795             case '5':
7796             case '6':
7797             case '7':
7798             case '8':
7799             case '9':
7800             {
7801                 add(current);
7802                 goto scan_number_any2;
7803             }
7804 
7805             default:
7806             {
7807                 error_message =
7808                     "invalid number; expected '+', '-', or digit after exponent";
7809                 return token_type::parse_error;
7810             }
7811         }
7812 
7813 scan_number_sign:
7814         // we just parsed an exponent sign
7815         switch (get())
7816         {
7817             case '0':
7818             case '1':
7819             case '2':
7820             case '3':
7821             case '4':
7822             case '5':
7823             case '6':
7824             case '7':
7825             case '8':
7826             case '9':
7827             {
7828                 add(current);
7829                 goto scan_number_any2;
7830             }
7831 
7832             default:
7833             {
7834                 error_message = "invalid number; expected digit after exponent sign";
7835                 return token_type::parse_error;
7836             }
7837         }
7838 
7839 scan_number_any2:
7840         // we just parsed a number after the exponent or exponent sign
7841         switch (get())
7842         {
7843             case '0':
7844             case '1':
7845             case '2':
7846             case '3':
7847             case '4':
7848             case '5':
7849             case '6':
7850             case '7':
7851             case '8':
7852             case '9':
7853             {
7854                 add(current);
7855                 goto scan_number_any2;
7856             }
7857 
7858             default:
7859                 goto scan_number_done;
7860         }
7861 
7862 scan_number_done:
7863         // unget the character after the number (we only read it to know that
7864         // we are done scanning a number)
7865         unget();
7866 
7867         char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7868         errno = 0;
7869 
7870         // try to parse integers first and fall back to floats
7871         if (number_type == token_type::value_unsigned)
7872         {
7873             const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7874 
7875             // we checked the number format before
7876             JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7877 
7878             if (errno == 0)
7879             {
7880                 value_unsigned = static_cast<number_unsigned_t>(x);
7881                 if (value_unsigned == x)
7882                 {
7883                     return token_type::value_unsigned;
7884                 }
7885             }
7886         }
7887         else if (number_type == token_type::value_integer)
7888         {
7889             const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7890 
7891             // we checked the number format before
7892             JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7893 
7894             if (errno == 0)
7895             {
7896                 value_integer = static_cast<number_integer_t>(x);
7897                 if (value_integer == x)
7898                 {
7899                     return token_type::value_integer;
7900                 }
7901             }
7902         }
7903 
7904         // this code is reached if we parse a floating-point number or if an
7905         // integer conversion above failed
7906         strtof(value_float, token_buffer.data(), &endptr);
7907 
7908         // we checked the number format before
7909         JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7910 
7911         return token_type::value_float;
7912     }
7913 
7914     /*!
7915     @param[in] literal_text  the literal text to expect
7916     @param[in] length        the length of the passed literal text
7917     @param[in] return_type   the token type to return on success
7918     */
7919     JSON_HEDLEY_NON_NULL(2)
scan_literal(const char_type * literal_text,const std::size_t length,token_type return_type)7920     token_type scan_literal(const char_type* literal_text, const std::size_t length,
7921                             token_type return_type)
7922     {
7923         JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7924         for (std::size_t i = 1; i < length; ++i)
7925         {
7926             if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7927             {
7928                 error_message = "invalid literal";
7929                 return token_type::parse_error;
7930             }
7931         }
7932         return return_type;
7933     }
7934 
7935     /////////////////////
7936     // input management
7937     /////////////////////
7938 
7939     /// reset token_buffer; current character is beginning of token
reset()7940     void reset() noexcept
7941     {
7942         token_buffer.clear();
7943         token_string.clear();
7944         token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7945     }
7946 
7947     /*
7948     @brief get next character from the input
7949 
7950     This function provides the interface to the used input adapter. It does
7951     not throw in case the input reached EOF, but returns a
7952     `std::char_traits<char>::eof()` in that case.  Stores the scanned characters
7953     for use in error messages.
7954 
7955     @return character read from the input
7956     */
get()7957     char_int_type get()
7958     {
7959         ++position.chars_read_total;
7960         ++position.chars_read_current_line;
7961 
7962         if (next_unget)
7963         {
7964             // just reset the next_unget variable and work with current
7965             next_unget = false;
7966         }
7967         else
7968         {
7969             current = ia.get_character();
7970         }
7971 
7972         if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7973         {
7974             token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7975         }
7976 
7977         if (current == '\n')
7978         {
7979             ++position.lines_read;
7980             position.chars_read_current_line = 0;
7981         }
7982 
7983         return current;
7984     }
7985 
7986     /*!
7987     @brief unget current character (read it again on next get)
7988 
7989     We implement unget by setting variable next_unget to true. The input is not
7990     changed - we just simulate ungetting by modifying chars_read_total,
7991     chars_read_current_line, and token_string. The next call to get() will
7992     behave as if the unget character is read again.
7993     */
unget()7994     void unget()
7995     {
7996         next_unget = true;
7997 
7998         --position.chars_read_total;
7999 
8000         // in case we "unget" a newline, we have to also decrement the lines_read
8001         if (position.chars_read_current_line == 0)
8002         {
8003             if (position.lines_read > 0)
8004             {
8005                 --position.lines_read;
8006             }
8007         }
8008         else
8009         {
8010             --position.chars_read_current_line;
8011         }
8012 
8013         if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8014         {
8015             JSON_ASSERT(!token_string.empty());
8016             token_string.pop_back();
8017         }
8018     }
8019 
8020     /// add a character to token_buffer
add(char_int_type c)8021     void add(char_int_type c)
8022     {
8023         token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8024     }
8025 
8026   public:
8027     /////////////////////
8028     // value getters
8029     /////////////////////
8030 
8031     /// return integer value
get_number_integer() const8032     constexpr number_integer_t get_number_integer() const noexcept
8033     {
8034         return value_integer;
8035     }
8036 
8037     /// return unsigned integer value
get_number_unsigned() const8038     constexpr number_unsigned_t get_number_unsigned() const noexcept
8039     {
8040         return value_unsigned;
8041     }
8042 
8043     /// return floating-point value
get_number_float() const8044     constexpr number_float_t get_number_float() const noexcept
8045     {
8046         return value_float;
8047     }
8048 
8049     /// return current string value (implicitly resets the token; useful only once)
get_string()8050     string_t& get_string()
8051     {
8052         return token_buffer;
8053     }
8054 
8055     /////////////////////
8056     // diagnostics
8057     /////////////////////
8058 
8059     /// return position of last read token
get_position() const8060     constexpr position_t get_position() const noexcept
8061     {
8062         return position;
8063     }
8064 
8065     /// return the last read token (for errors only).  Will never contain EOF
8066     /// (an arbitrary value that is not a valid char value, often -1), because
8067     /// 255 may legitimately occur.  May contain NUL, which should be escaped.
get_token_string() const8068     std::string get_token_string() const
8069     {
8070         // escape control characters
8071         std::string result;
8072         for (const auto c : token_string)
8073         {
8074             if (static_cast<unsigned char>(c) <= '\x1F')
8075             {
8076                 // escape control characters
8077                 std::array<char, 9> cs{{}};
8078                 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8079                 result += cs.data();
8080             }
8081             else
8082             {
8083                 // add character as is
8084                 result.push_back(static_cast<std::string::value_type>(c));
8085             }
8086         }
8087 
8088         return result;
8089     }
8090 
8091     /// return syntax error message
8092     JSON_HEDLEY_RETURNS_NON_NULL
get_error_message() const8093     constexpr const char* get_error_message() const noexcept
8094     {
8095         return error_message;
8096     }
8097 
8098     /////////////////////
8099     // actual scanner
8100     /////////////////////
8101 
8102     /*!
8103     @brief skip the UTF-8 byte order mark
8104     @return true iff there is no BOM or the correct BOM has been skipped
8105     */
skip_bom()8106     bool skip_bom()
8107     {
8108         if (get() == 0xEF)
8109         {
8110             // check if we completely parse the BOM
8111             return get() == 0xBB && get() == 0xBF;
8112         }
8113 
8114         // the first character is not the beginning of the BOM; unget it to
8115         // process is later
8116         unget();
8117         return true;
8118     }
8119 
skip_whitespace()8120     void skip_whitespace()
8121     {
8122         do
8123         {
8124             get();
8125         }
8126         while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8127     }
8128 
scan()8129     token_type scan()
8130     {
8131         // initially, skip the BOM
8132         if (position.chars_read_total == 0 && !skip_bom())
8133         {
8134             error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8135             return token_type::parse_error;
8136         }
8137 
8138         // read next character and ignore whitespace
8139         skip_whitespace();
8140 
8141         // ignore comments
8142         while (ignore_comments && current == '/')
8143         {
8144             if (!scan_comment())
8145             {
8146                 return token_type::parse_error;
8147             }
8148 
8149             // skip following whitespace
8150             skip_whitespace();
8151         }
8152 
8153         switch (current)
8154         {
8155             // structural characters
8156             case '[':
8157                 return token_type::begin_array;
8158             case ']':
8159                 return token_type::end_array;
8160             case '{':
8161                 return token_type::begin_object;
8162             case '}':
8163                 return token_type::end_object;
8164             case ':':
8165                 return token_type::name_separator;
8166             case ',':
8167                 return token_type::value_separator;
8168 
8169             // literals
8170             case 't':
8171             {
8172                 std::array<char_type, 4> true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}};
8173                 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8174             }
8175             case 'f':
8176             {
8177                 std::array<char_type, 5> false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}};
8178                 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8179             }
8180             case 'n':
8181             {
8182                 std::array<char_type, 4> null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}};
8183                 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8184             }
8185 
8186             // string
8187             case '\"':
8188                 return scan_string();
8189 
8190             // number
8191             case '-':
8192             case '0':
8193             case '1':
8194             case '2':
8195             case '3':
8196             case '4':
8197             case '5':
8198             case '6':
8199             case '7':
8200             case '8':
8201             case '9':
8202                 return scan_number();
8203 
8204             // end of input (the null byte is needed when parsing from
8205             // string literals)
8206             case '\0':
8207             case std::char_traits<char_type>::eof():
8208                 return token_type::end_of_input;
8209 
8210             // error
8211             default:
8212                 error_message = "invalid literal";
8213                 return token_type::parse_error;
8214         }
8215     }
8216 
8217   private:
8218     /// input adapter
8219     InputAdapterType ia;
8220 
8221     /// whether comments should be ignored (true) or signaled as errors (false)
8222     const bool ignore_comments = false;
8223 
8224     /// the current character
8225     char_int_type current = std::char_traits<char_type>::eof();
8226 
8227     /// whether the next get() call should just return current
8228     bool next_unget = false;
8229 
8230     /// the start position of the current token
8231     position_t position {};
8232 
8233     /// raw input token string (for error messages)
8234     std::vector<char_type> token_string {};
8235 
8236     /// buffer for variable-length tokens (numbers, strings)
8237     string_t token_buffer {};
8238 
8239     /// a description of occurred lexer errors
8240     const char* error_message = "";
8241 
8242     // number values
8243     number_integer_t value_integer = 0;
8244     number_unsigned_t value_unsigned = 0;
8245     number_float_t value_float = 0;
8246 
8247     /// the decimal point
8248     const char_int_type decimal_point_char = '.';
8249 };
8250 }  // namespace detail
8251 }  // namespace nlohmann
8252 
8253 // #include <nlohmann/detail/macro_scope.hpp>
8254 
8255 // #include <nlohmann/detail/meta/is_sax.hpp>
8256 
8257 
8258 #include <cstdint> // size_t
8259 #include <utility> // declval
8260 #include <string> // string
8261 
8262 // #include <nlohmann/detail/meta/detected.hpp>
8263 
8264 // #include <nlohmann/detail/meta/type_traits.hpp>
8265 
8266 
8267 namespace nlohmann
8268 {
8269 namespace detail
8270 {
8271 template<typename T>
8272 using null_function_t = decltype(std::declval<T&>().null());
8273 
8274 template<typename T>
8275 using boolean_function_t =
8276     decltype(std::declval<T&>().boolean(std::declval<bool>()));
8277 
8278 template<typename T, typename Integer>
8279 using number_integer_function_t =
8280     decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8281 
8282 template<typename T, typename Unsigned>
8283 using number_unsigned_function_t =
8284     decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8285 
8286 template<typename T, typename Float, typename String>
8287 using number_float_function_t = decltype(std::declval<T&>().number_float(
8288                                     std::declval<Float>(), std::declval<const String&>()));
8289 
8290 template<typename T, typename String>
8291 using string_function_t =
8292     decltype(std::declval<T&>().string(std::declval<String&>()));
8293 
8294 template<typename T, typename Binary>
8295 using binary_function_t =
8296     decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8297 
8298 template<typename T>
8299 using start_object_function_t =
8300     decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8301 
8302 template<typename T, typename String>
8303 using key_function_t =
8304     decltype(std::declval<T&>().key(std::declval<String&>()));
8305 
8306 template<typename T>
8307 using end_object_function_t = decltype(std::declval<T&>().end_object());
8308 
8309 template<typename T>
8310 using start_array_function_t =
8311     decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8312 
8313 template<typename T>
8314 using end_array_function_t = decltype(std::declval<T&>().end_array());
8315 
8316 template<typename T, typename Exception>
8317 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8318         std::declval<std::size_t>(), std::declval<const std::string&>(),
8319         std::declval<const Exception&>()));
8320 
8321 template<typename SAX, typename BasicJsonType>
8322 struct is_sax
8323 {
8324   private:
8325     static_assert(is_basic_json<BasicJsonType>::value,
8326                   "BasicJsonType must be of type basic_json<...>");
8327 
8328     using number_integer_t = typename BasicJsonType::number_integer_t;
8329     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8330     using number_float_t = typename BasicJsonType::number_float_t;
8331     using string_t = typename BasicJsonType::string_t;
8332     using binary_t = typename BasicJsonType::binary_t;
8333     using exception_t = typename BasicJsonType::exception;
8334 
8335   public:
8336     static constexpr bool value =
8337         is_detected_exact<bool, null_function_t, SAX>::value &&
8338         is_detected_exact<bool, boolean_function_t, SAX>::value &&
8339         is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
8340         is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
8341         is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
8342         is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
8343         is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
8344         is_detected_exact<bool, start_object_function_t, SAX>::value &&
8345         is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
8346         is_detected_exact<bool, end_object_function_t, SAX>::value &&
8347         is_detected_exact<bool, start_array_function_t, SAX>::value &&
8348         is_detected_exact<bool, end_array_function_t, SAX>::value &&
8349         is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
8350 };
8351 
8352 template<typename SAX, typename BasicJsonType>
8353 struct is_sax_static_asserts
8354 {
8355   private:
8356     static_assert(is_basic_json<BasicJsonType>::value,
8357                   "BasicJsonType must be of type basic_json<...>");
8358 
8359     using number_integer_t = typename BasicJsonType::number_integer_t;
8360     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8361     using number_float_t = typename BasicJsonType::number_float_t;
8362     using string_t = typename BasicJsonType::string_t;
8363     using binary_t = typename BasicJsonType::binary_t;
8364     using exception_t = typename BasicJsonType::exception;
8365 
8366   public:
8367     static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
8368                   "Missing/invalid function: bool null()");
8369     static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8370                   "Missing/invalid function: bool boolean(bool)");
8371     static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8372                   "Missing/invalid function: bool boolean(bool)");
8373     static_assert(
8374         is_detected_exact<bool, number_integer_function_t, SAX,
8375         number_integer_t>::value,
8376         "Missing/invalid function: bool number_integer(number_integer_t)");
8377     static_assert(
8378         is_detected_exact<bool, number_unsigned_function_t, SAX,
8379         number_unsigned_t>::value,
8380         "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8381     static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8382                   number_float_t, string_t>::value,
8383                   "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8384     static_assert(
8385         is_detected_exact<bool, string_function_t, SAX, string_t>::value,
8386         "Missing/invalid function: bool string(string_t&)");
8387     static_assert(
8388         is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
8389         "Missing/invalid function: bool binary(binary_t&)");
8390     static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
8391                   "Missing/invalid function: bool start_object(std::size_t)");
8392     static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
8393                   "Missing/invalid function: bool key(string_t&)");
8394     static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
8395                   "Missing/invalid function: bool end_object()");
8396     static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
8397                   "Missing/invalid function: bool start_array(std::size_t)");
8398     static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
8399                   "Missing/invalid function: bool end_array()");
8400     static_assert(
8401         is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
8402         "Missing/invalid function: bool parse_error(std::size_t, const "
8403         "std::string&, const exception&)");
8404 };
8405 }  // namespace detail
8406 }  // namespace nlohmann
8407 
8408 // #include <nlohmann/detail/meta/type_traits.hpp>
8409 
8410 // #include <nlohmann/detail/value_t.hpp>
8411 
8412 
8413 namespace nlohmann
8414 {
8415 namespace detail
8416 {
8417 
8418 /// how to treat CBOR tags
8419 enum class cbor_tag_handler_t
8420 {
8421     error,   ///< throw a parse_error exception in case of a tag
8422     ignore,  ///< ignore tags
8423     store    ///< store tags as binary type
8424 };
8425 
8426 /*!
8427 @brief determine system byte order
8428 
8429 @return true if and only if system's byte order is little endian
8430 
8431 @note from https://stackoverflow.com/a/1001328/266378
8432 */
little_endianess(int num=1)8433 static inline bool little_endianess(int num = 1) noexcept
8434 {
8435     return *reinterpret_cast<char*>(&num) == 1;
8436 }
8437 
8438 
8439 ///////////////////
8440 // binary reader //
8441 ///////////////////
8442 
8443 /*!
8444 @brief deserialization of CBOR, MessagePack, and UBJSON values
8445 */
8446 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8447 class binary_reader
8448 {
8449     using number_integer_t = typename BasicJsonType::number_integer_t;
8450     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8451     using number_float_t = typename BasicJsonType::number_float_t;
8452     using string_t = typename BasicJsonType::string_t;
8453     using binary_t = typename BasicJsonType::binary_t;
8454     using json_sax_t = SAX;
8455     using char_type = typename InputAdapterType::char_type;
8456     using char_int_type = typename std::char_traits<char_type>::int_type;
8457 
8458   public:
8459     /*!
8460     @brief create a binary reader
8461 
8462     @param[in] adapter  input adapter to read from
8463     */
binary_reader(InputAdapterType && adapter)8464     explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
8465     {
8466         (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
8467     }
8468 
8469     // make class move-only
8470     binary_reader(const binary_reader&) = delete;
8471     binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8472     binary_reader& operator=(const binary_reader&) = delete;
8473     binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8474     ~binary_reader() = default;
8475 
8476     /*!
8477     @param[in] format  the binary format to parse
8478     @param[in] sax_    a SAX event processor
8479     @param[in] strict  whether to expect the input to be consumed completed
8480     @param[in] tag_handler  how to treat CBOR tags
8481 
8482     @return whether parsing was successful
8483     */
8484     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)8485     bool sax_parse(const input_format_t format,
8486                    json_sax_t* sax_,
8487                    const bool strict = true,
8488                    const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8489     {
8490         sax = sax_;
8491         bool result = false;
8492 
8493         switch (format)
8494         {
8495             case input_format_t::bson:
8496                 result = parse_bson_internal();
8497                 break;
8498 
8499             case input_format_t::cbor:
8500                 result = parse_cbor_internal(true, tag_handler);
8501                 break;
8502 
8503             case input_format_t::msgpack:
8504                 result = parse_msgpack_internal();
8505                 break;
8506 
8507             case input_format_t::ubjson:
8508                 result = parse_ubjson_internal();
8509                 break;
8510 
8511             case input_format_t::json: // LCOV_EXCL_LINE
8512             default:            // LCOV_EXCL_LINE
8513                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8514         }
8515 
8516         // strict mode: next byte must be EOF
8517         if (result && strict)
8518         {
8519             if (format == input_format_t::ubjson)
8520             {
8521                 get_ignore_noop();
8522             }
8523             else
8524             {
8525                 get();
8526             }
8527 
8528             if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8529             {
8530                 return sax->parse_error(chars_read, get_token_string(),
8531                                         parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
8532             }
8533         }
8534 
8535         return result;
8536     }
8537 
8538   private:
8539     //////////
8540     // BSON //
8541     //////////
8542 
8543     /*!
8544     @brief Reads in a BSON-object and passes it to the SAX-parser.
8545     @return whether a valid BSON-value was passed to the SAX parser
8546     */
parse_bson_internal()8547     bool parse_bson_internal()
8548     {
8549         std::int32_t document_size{};
8550         get_number<std::int32_t, true>(input_format_t::bson, document_size);
8551 
8552         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
8553         {
8554             return false;
8555         }
8556 
8557         if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8558         {
8559             return false;
8560         }
8561 
8562         return sax->end_object();
8563     }
8564 
8565     /*!
8566     @brief Parses a C-style string from the BSON input.
8567     @param[in,out] result  A reference to the string variable where the read
8568                             string is to be stored.
8569     @return `true` if the \x00-byte indicating the end of the string was
8570              encountered before the EOF; false` indicates an unexpected EOF.
8571     */
get_bson_cstr(string_t & result)8572     bool get_bson_cstr(string_t& result)
8573     {
8574         auto out = std::back_inserter(result);
8575         while (true)
8576         {
8577             get();
8578             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
8579             {
8580                 return false;
8581             }
8582             if (current == 0x00)
8583             {
8584                 return true;
8585             }
8586             *out++ = static_cast<typename string_t::value_type>(current);
8587         }
8588     }
8589 
8590     /*!
8591     @brief Parses a zero-terminated string of length @a len from the BSON
8592            input.
8593     @param[in] len  The length (including the zero-byte at the end) of the
8594                     string to be read.
8595     @param[in,out] result  A reference to the string variable where the read
8596                             string is to be stored.
8597     @tparam NumberType The type of the length @a len
8598     @pre len >= 1
8599     @return `true` if the string was successfully parsed
8600     */
8601     template<typename NumberType>
get_bson_string(const NumberType len,string_t & result)8602     bool get_bson_string(const NumberType len, string_t& result)
8603     {
8604         if (JSON_HEDLEY_UNLIKELY(len < 1))
8605         {
8606             auto last_token = get_token_string();
8607             return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string"), BasicJsonType()));
8608         }
8609 
8610         return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8611     }
8612 
8613     /*!
8614     @brief Parses a byte array input of length @a len from the BSON input.
8615     @param[in] len  The length of the byte array to be read.
8616     @param[in,out] result  A reference to the binary variable where the read
8617                             array is to be stored.
8618     @tparam NumberType The type of the length @a len
8619     @pre len >= 0
8620     @return `true` if the byte array was successfully parsed
8621     */
8622     template<typename NumberType>
get_bson_binary(const NumberType len,binary_t & result)8623     bool get_bson_binary(const NumberType len, binary_t& result)
8624     {
8625         if (JSON_HEDLEY_UNLIKELY(len < 0))
8626         {
8627             auto last_token = get_token_string();
8628             return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary"), BasicJsonType()));
8629         }
8630 
8631         // All BSON binary values have a subtype
8632         std::uint8_t subtype{};
8633         get_number<std::uint8_t>(input_format_t::bson, subtype);
8634         result.set_subtype(subtype);
8635 
8636         return get_binary(input_format_t::bson, len, result);
8637     }
8638 
8639     /*!
8640     @brief Read a BSON document element of the given @a element_type.
8641     @param[in] element_type The BSON element type, c.f. http://bsonspec.org/spec.html
8642     @param[in] element_type_parse_position The position in the input stream,
8643                where the `element_type` was read.
8644     @warning Not all BSON element types are supported yet. An unsupported
8645              @a element_type will give rise to a parse_error.114:
8646              Unsupported BSON record type 0x...
8647     @return whether a valid BSON-object/array was passed to the SAX parser
8648     */
parse_bson_element_internal(const char_int_type element_type,const std::size_t element_type_parse_position)8649     bool parse_bson_element_internal(const char_int_type element_type,
8650                                      const std::size_t element_type_parse_position)
8651     {
8652         switch (element_type)
8653         {
8654             case 0x01: // double
8655             {
8656                 double number{};
8657                 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8658             }
8659 
8660             case 0x02: // string
8661             {
8662                 std::int32_t len{};
8663                 string_t value;
8664                 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8665             }
8666 
8667             case 0x03: // object
8668             {
8669                 return parse_bson_internal();
8670             }
8671 
8672             case 0x04: // array
8673             {
8674                 return parse_bson_array();
8675             }
8676 
8677             case 0x05: // binary
8678             {
8679                 std::int32_t len{};
8680                 binary_t value;
8681                 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8682             }
8683 
8684             case 0x08: // boolean
8685             {
8686                 return sax->boolean(get() != 0);
8687             }
8688 
8689             case 0x0A: // null
8690             {
8691                 return sax->null();
8692             }
8693 
8694             case 0x10: // int32
8695             {
8696                 std::int32_t value{};
8697                 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8698             }
8699 
8700             case 0x12: // int64
8701             {
8702                 std::int64_t value{};
8703                 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8704             }
8705 
8706             default: // anything else not supported (yet)
8707             {
8708                 std::array<char, 3> cr{{}};
8709                 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8710                 return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data()), BasicJsonType()));
8711             }
8712         }
8713     }
8714 
8715     /*!
8716     @brief Read a BSON element list (as specified in the BSON-spec)
8717 
8718     The same binary layout is used for objects and arrays, hence it must be
8719     indicated with the argument @a is_array which one is expected
8720     (true --> array, false --> object).
8721 
8722     @param[in] is_array Determines if the element list being read is to be
8723                         treated as an object (@a is_array == false), or as an
8724                         array (@a is_array == true).
8725     @return whether a valid BSON-object/array was passed to the SAX parser
8726     */
parse_bson_element_list(const bool is_array)8727     bool parse_bson_element_list(const bool is_array)
8728     {
8729         string_t key;
8730 
8731         while (auto element_type = get())
8732         {
8733             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8734             {
8735                 return false;
8736             }
8737 
8738             const std::size_t element_type_parse_position = chars_read;
8739             if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8740             {
8741                 return false;
8742             }
8743 
8744             if (!is_array && !sax->key(key))
8745             {
8746                 return false;
8747             }
8748 
8749             if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8750             {
8751                 return false;
8752             }
8753 
8754             // get_bson_cstr only appends
8755             key.clear();
8756         }
8757 
8758         return true;
8759     }
8760 
8761     /*!
8762     @brief Reads an array from the BSON input and passes it to the SAX-parser.
8763     @return whether a valid BSON-array was passed to the SAX parser
8764     */
parse_bson_array()8765     bool parse_bson_array()
8766     {
8767         std::int32_t document_size{};
8768         get_number<std::int32_t, true>(input_format_t::bson, document_size);
8769 
8770         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8771         {
8772             return false;
8773         }
8774 
8775         if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8776         {
8777             return false;
8778         }
8779 
8780         return sax->end_array();
8781     }
8782 
8783     //////////
8784     // CBOR //
8785     //////////
8786 
8787     /*!
8788     @param[in] get_char  whether a new character should be retrieved from the
8789                          input (true) or whether the last read character should
8790                          be considered instead (false)
8791     @param[in] tag_handler how CBOR tags should be treated
8792 
8793     @return whether a valid CBOR value was passed to the SAX parser
8794     */
parse_cbor_internal(const bool get_char,const cbor_tag_handler_t tag_handler)8795     bool parse_cbor_internal(const bool get_char,
8796                              const cbor_tag_handler_t tag_handler)
8797     {
8798         switch (get_char ? get() : current)
8799         {
8800             // EOF
8801             case std::char_traits<char_type>::eof():
8802                 return unexpect_eof(input_format_t::cbor, "value");
8803 
8804             // Integer 0x00..0x17 (0..23)
8805             case 0x00:
8806             case 0x01:
8807             case 0x02:
8808             case 0x03:
8809             case 0x04:
8810             case 0x05:
8811             case 0x06:
8812             case 0x07:
8813             case 0x08:
8814             case 0x09:
8815             case 0x0A:
8816             case 0x0B:
8817             case 0x0C:
8818             case 0x0D:
8819             case 0x0E:
8820             case 0x0F:
8821             case 0x10:
8822             case 0x11:
8823             case 0x12:
8824             case 0x13:
8825             case 0x14:
8826             case 0x15:
8827             case 0x16:
8828             case 0x17:
8829                 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8830 
8831             case 0x18: // Unsigned integer (one-byte uint8_t follows)
8832             {
8833                 std::uint8_t number{};
8834                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8835             }
8836 
8837             case 0x19: // Unsigned integer (two-byte uint16_t follows)
8838             {
8839                 std::uint16_t number{};
8840                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8841             }
8842 
8843             case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8844             {
8845                 std::uint32_t number{};
8846                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8847             }
8848 
8849             case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8850             {
8851                 std::uint64_t number{};
8852                 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8853             }
8854 
8855             // Negative integer -1-0x00..-1-0x17 (-1..-24)
8856             case 0x20:
8857             case 0x21:
8858             case 0x22:
8859             case 0x23:
8860             case 0x24:
8861             case 0x25:
8862             case 0x26:
8863             case 0x27:
8864             case 0x28:
8865             case 0x29:
8866             case 0x2A:
8867             case 0x2B:
8868             case 0x2C:
8869             case 0x2D:
8870             case 0x2E:
8871             case 0x2F:
8872             case 0x30:
8873             case 0x31:
8874             case 0x32:
8875             case 0x33:
8876             case 0x34:
8877             case 0x35:
8878             case 0x36:
8879             case 0x37:
8880                 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8881 
8882             case 0x38: // Negative integer (one-byte uint8_t follows)
8883             {
8884                 std::uint8_t number{};
8885                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8886             }
8887 
8888             case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8889             {
8890                 std::uint16_t number{};
8891                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8892             }
8893 
8894             case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8895             {
8896                 std::uint32_t number{};
8897                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8898             }
8899 
8900             case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8901             {
8902                 std::uint64_t number{};
8903                 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8904                         - static_cast<number_integer_t>(number));
8905             }
8906 
8907             // Binary data (0x00..0x17 bytes follow)
8908             case 0x40:
8909             case 0x41:
8910             case 0x42:
8911             case 0x43:
8912             case 0x44:
8913             case 0x45:
8914             case 0x46:
8915             case 0x47:
8916             case 0x48:
8917             case 0x49:
8918             case 0x4A:
8919             case 0x4B:
8920             case 0x4C:
8921             case 0x4D:
8922             case 0x4E:
8923             case 0x4F:
8924             case 0x50:
8925             case 0x51:
8926             case 0x52:
8927             case 0x53:
8928             case 0x54:
8929             case 0x55:
8930             case 0x56:
8931             case 0x57:
8932             case 0x58: // Binary data (one-byte uint8_t for n follows)
8933             case 0x59: // Binary data (two-byte uint16_t for n follow)
8934             case 0x5A: // Binary data (four-byte uint32_t for n follow)
8935             case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8936             case 0x5F: // Binary data (indefinite length)
8937             {
8938                 binary_t b;
8939                 return get_cbor_binary(b) && sax->binary(b);
8940             }
8941 
8942             // UTF-8 string (0x00..0x17 bytes follow)
8943             case 0x60:
8944             case 0x61:
8945             case 0x62:
8946             case 0x63:
8947             case 0x64:
8948             case 0x65:
8949             case 0x66:
8950             case 0x67:
8951             case 0x68:
8952             case 0x69:
8953             case 0x6A:
8954             case 0x6B:
8955             case 0x6C:
8956             case 0x6D:
8957             case 0x6E:
8958             case 0x6F:
8959             case 0x70:
8960             case 0x71:
8961             case 0x72:
8962             case 0x73:
8963             case 0x74:
8964             case 0x75:
8965             case 0x76:
8966             case 0x77:
8967             case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8968             case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8969             case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8970             case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8971             case 0x7F: // UTF-8 string (indefinite length)
8972             {
8973                 string_t s;
8974                 return get_cbor_string(s) && sax->string(s);
8975             }
8976 
8977             // array (0x00..0x17 data items follow)
8978             case 0x80:
8979             case 0x81:
8980             case 0x82:
8981             case 0x83:
8982             case 0x84:
8983             case 0x85:
8984             case 0x86:
8985             case 0x87:
8986             case 0x88:
8987             case 0x89:
8988             case 0x8A:
8989             case 0x8B:
8990             case 0x8C:
8991             case 0x8D:
8992             case 0x8E:
8993             case 0x8F:
8994             case 0x90:
8995             case 0x91:
8996             case 0x92:
8997             case 0x93:
8998             case 0x94:
8999             case 0x95:
9000             case 0x96:
9001             case 0x97:
9002                 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9003 
9004             case 0x98: // array (one-byte uint8_t for n follows)
9005             {
9006                 std::uint8_t len{};
9007                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9008             }
9009 
9010             case 0x99: // array (two-byte uint16_t for n follow)
9011             {
9012                 std::uint16_t len{};
9013                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9014             }
9015 
9016             case 0x9A: // array (four-byte uint32_t for n follow)
9017             {
9018                 std::uint32_t len{};
9019                 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9020             }
9021 
9022             case 0x9B: // array (eight-byte uint64_t for n follow)
9023             {
9024                 std::uint64_t len{};
9025                 return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9026             }
9027 
9028             case 0x9F: // array (indefinite length)
9029                 return get_cbor_array(std::size_t(-1), tag_handler);
9030 
9031             // map (0x00..0x17 pairs of data items follow)
9032             case 0xA0:
9033             case 0xA1:
9034             case 0xA2:
9035             case 0xA3:
9036             case 0xA4:
9037             case 0xA5:
9038             case 0xA6:
9039             case 0xA7:
9040             case 0xA8:
9041             case 0xA9:
9042             case 0xAA:
9043             case 0xAB:
9044             case 0xAC:
9045             case 0xAD:
9046             case 0xAE:
9047             case 0xAF:
9048             case 0xB0:
9049             case 0xB1:
9050             case 0xB2:
9051             case 0xB3:
9052             case 0xB4:
9053             case 0xB5:
9054             case 0xB6:
9055             case 0xB7:
9056                 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9057 
9058             case 0xB8: // map (one-byte uint8_t for n follows)
9059             {
9060                 std::uint8_t len{};
9061                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9062             }
9063 
9064             case 0xB9: // map (two-byte uint16_t for n follow)
9065             {
9066                 std::uint16_t len{};
9067                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9068             }
9069 
9070             case 0xBA: // map (four-byte uint32_t for n follow)
9071             {
9072                 std::uint32_t len{};
9073                 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9074             }
9075 
9076             case 0xBB: // map (eight-byte uint64_t for n follow)
9077             {
9078                 std::uint64_t len{};
9079                 return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9080             }
9081 
9082             case 0xBF: // map (indefinite length)
9083                 return get_cbor_object(std::size_t(-1), tag_handler);
9084 
9085             case 0xC6: // tagged item
9086             case 0xC7:
9087             case 0xC8:
9088             case 0xC9:
9089             case 0xCA:
9090             case 0xCB:
9091             case 0xCC:
9092             case 0xCD:
9093             case 0xCE:
9094             case 0xCF:
9095             case 0xD0:
9096             case 0xD1:
9097             case 0xD2:
9098             case 0xD3:
9099             case 0xD4:
9100             case 0xD8: // tagged item (1 bytes follow)
9101             case 0xD9: // tagged item (2 bytes follow)
9102             case 0xDA: // tagged item (4 bytes follow)
9103             case 0xDB: // tagged item (8 bytes follow)
9104             {
9105                 switch (tag_handler)
9106                 {
9107                     case cbor_tag_handler_t::error:
9108                     {
9109                         auto last_token = get_token_string();
9110                         return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9111                     }
9112 
9113                     case cbor_tag_handler_t::ignore:
9114                     {
9115                         // ignore binary subtype
9116                         switch (current)
9117                         {
9118                             case 0xD8:
9119                             {
9120                                 std::uint8_t subtype_to_ignore{};
9121                                 get_number(input_format_t::cbor, subtype_to_ignore);
9122                                 break;
9123                             }
9124                             case 0xD9:
9125                             {
9126                                 std::uint16_t subtype_to_ignore{};
9127                                 get_number(input_format_t::cbor, subtype_to_ignore);
9128                                 break;
9129                             }
9130                             case 0xDA:
9131                             {
9132                                 std::uint32_t subtype_to_ignore{};
9133                                 get_number(input_format_t::cbor, subtype_to_ignore);
9134                                 break;
9135                             }
9136                             case 0xDB:
9137                             {
9138                                 std::uint64_t subtype_to_ignore{};
9139                                 get_number(input_format_t::cbor, subtype_to_ignore);
9140                                 break;
9141                             }
9142                             default:
9143                                 break;
9144                         }
9145                         return parse_cbor_internal(true, tag_handler);
9146                     }
9147 
9148                     case cbor_tag_handler_t::store:
9149                     {
9150                         binary_t b;
9151                         // use binary subtype and store in binary container
9152                         switch (current)
9153                         {
9154                             case 0xD8:
9155                             {
9156                                 std::uint8_t subtype{};
9157                                 get_number(input_format_t::cbor, subtype);
9158                                 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9159                                 break;
9160                             }
9161                             case 0xD9:
9162                             {
9163                                 std::uint16_t subtype{};
9164                                 get_number(input_format_t::cbor, subtype);
9165                                 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9166                                 break;
9167                             }
9168                             case 0xDA:
9169                             {
9170                                 std::uint32_t subtype{};
9171                                 get_number(input_format_t::cbor, subtype);
9172                                 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9173                                 break;
9174                             }
9175                             case 0xDB:
9176                             {
9177                                 std::uint64_t subtype{};
9178                                 get_number(input_format_t::cbor, subtype);
9179                                 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9180                                 break;
9181                             }
9182                             default:
9183                                 return parse_cbor_internal(true, tag_handler);
9184                         }
9185                         get();
9186                         return get_cbor_binary(b) && sax->binary(b);
9187                     }
9188 
9189                     default:                 // LCOV_EXCL_LINE
9190                         JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9191                         return false;        // LCOV_EXCL_LINE
9192                 }
9193             }
9194 
9195             case 0xF4: // false
9196                 return sax->boolean(false);
9197 
9198             case 0xF5: // true
9199                 return sax->boolean(true);
9200 
9201             case 0xF6: // null
9202                 return sax->null();
9203 
9204             case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9205             {
9206                 const auto byte1_raw = get();
9207                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9208                 {
9209                     return false;
9210                 }
9211                 const auto byte2_raw = get();
9212                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9213                 {
9214                     return false;
9215                 }
9216 
9217                 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9218                 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9219 
9220                 // code from RFC 7049, Appendix D, Figure 3:
9221                 // As half-precision floating-point numbers were only added
9222                 // to IEEE 754 in 2008, today's programming platforms often
9223                 // still only have limited support for them. It is very
9224                 // easy to include at least decoding support for them even
9225                 // without such support. An example of a small decoder for
9226                 // half-precision floating-point numbers in the C language
9227                 // is shown in Fig. 3.
9228                 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9229                 const double val = [&half]
9230                 {
9231                     const int exp = (half >> 10u) & 0x1Fu;
9232                     const unsigned int mant = half & 0x3FFu;
9233                     JSON_ASSERT(0 <= exp&& exp <= 32);
9234                     JSON_ASSERT(mant <= 1024);
9235                     switch (exp)
9236                     {
9237                         case 0:
9238                             return std::ldexp(mant, -24);
9239                         case 31:
9240                             return (mant == 0)
9241                             ? std::numeric_limits<double>::infinity()
9242                             : std::numeric_limits<double>::quiet_NaN();
9243                         default:
9244                             return std::ldexp(mant + 1024, exp - 25);
9245                     }
9246                 }();
9247                 return sax->number_float((half & 0x8000u) != 0
9248                                          ? static_cast<number_float_t>(-val)
9249                                          : static_cast<number_float_t>(val), "");
9250             }
9251 
9252             case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9253             {
9254                 float number{};
9255                 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9256             }
9257 
9258             case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9259             {
9260                 double number{};
9261                 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9262             }
9263 
9264             default: // anything else (0xFF is handled inside the other types)
9265             {
9266                 auto last_token = get_token_string();
9267                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9268             }
9269         }
9270     }
9271 
9272     /*!
9273     @brief reads a CBOR string
9274 
9275     This function first reads starting bytes to determine the expected
9276     string length and then copies this number of bytes into a string.
9277     Additionally, CBOR's strings with indefinite lengths are supported.
9278 
9279     @param[out] result  created string
9280 
9281     @return whether string creation completed
9282     */
get_cbor_string(string_t & result)9283     bool get_cbor_string(string_t& result)
9284     {
9285         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9286         {
9287             return false;
9288         }
9289 
9290         switch (current)
9291         {
9292             // UTF-8 string (0x00..0x17 bytes follow)
9293             case 0x60:
9294             case 0x61:
9295             case 0x62:
9296             case 0x63:
9297             case 0x64:
9298             case 0x65:
9299             case 0x66:
9300             case 0x67:
9301             case 0x68:
9302             case 0x69:
9303             case 0x6A:
9304             case 0x6B:
9305             case 0x6C:
9306             case 0x6D:
9307             case 0x6E:
9308             case 0x6F:
9309             case 0x70:
9310             case 0x71:
9311             case 0x72:
9312             case 0x73:
9313             case 0x74:
9314             case 0x75:
9315             case 0x76:
9316             case 0x77:
9317             {
9318                 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9319             }
9320 
9321             case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9322             {
9323                 std::uint8_t len{};
9324                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9325             }
9326 
9327             case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9328             {
9329                 std::uint16_t len{};
9330                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9331             }
9332 
9333             case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9334             {
9335                 std::uint32_t len{};
9336                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9337             }
9338 
9339             case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9340             {
9341                 std::uint64_t len{};
9342                 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9343             }
9344 
9345             case 0x7F: // UTF-8 string (indefinite length)
9346             {
9347                 while (get() != 0xFF)
9348                 {
9349                     string_t chunk;
9350                     if (!get_cbor_string(chunk))
9351                     {
9352                         return false;
9353                     }
9354                     result.append(chunk);
9355                 }
9356                 return true;
9357             }
9358 
9359             default:
9360             {
9361                 auto last_token = get_token_string();
9362                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string"), BasicJsonType()));
9363             }
9364         }
9365     }
9366 
9367     /*!
9368     @brief reads a CBOR byte array
9369 
9370     This function first reads starting bytes to determine the expected
9371     byte array length and then copies this number of bytes into the byte array.
9372     Additionally, CBOR's byte arrays with indefinite lengths are supported.
9373 
9374     @param[out] result  created byte array
9375 
9376     @return whether byte array creation completed
9377     */
get_cbor_binary(binary_t & result)9378     bool get_cbor_binary(binary_t& result)
9379     {
9380         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
9381         {
9382             return false;
9383         }
9384 
9385         switch (current)
9386         {
9387             // Binary data (0x00..0x17 bytes follow)
9388             case 0x40:
9389             case 0x41:
9390             case 0x42:
9391             case 0x43:
9392             case 0x44:
9393             case 0x45:
9394             case 0x46:
9395             case 0x47:
9396             case 0x48:
9397             case 0x49:
9398             case 0x4A:
9399             case 0x4B:
9400             case 0x4C:
9401             case 0x4D:
9402             case 0x4E:
9403             case 0x4F:
9404             case 0x50:
9405             case 0x51:
9406             case 0x52:
9407             case 0x53:
9408             case 0x54:
9409             case 0x55:
9410             case 0x56:
9411             case 0x57:
9412             {
9413                 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9414             }
9415 
9416             case 0x58: // Binary data (one-byte uint8_t for n follows)
9417             {
9418                 std::uint8_t len{};
9419                 return get_number(input_format_t::cbor, len) &&
9420                        get_binary(input_format_t::cbor, len, result);
9421             }
9422 
9423             case 0x59: // Binary data (two-byte uint16_t for n follow)
9424             {
9425                 std::uint16_t len{};
9426                 return get_number(input_format_t::cbor, len) &&
9427                        get_binary(input_format_t::cbor, len, result);
9428             }
9429 
9430             case 0x5A: // Binary data (four-byte uint32_t for n follow)
9431             {
9432                 std::uint32_t len{};
9433                 return get_number(input_format_t::cbor, len) &&
9434                        get_binary(input_format_t::cbor, len, result);
9435             }
9436 
9437             case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9438             {
9439                 std::uint64_t len{};
9440                 return get_number(input_format_t::cbor, len) &&
9441                        get_binary(input_format_t::cbor, len, result);
9442             }
9443 
9444             case 0x5F: // Binary data (indefinite length)
9445             {
9446                 while (get() != 0xFF)
9447                 {
9448                     binary_t chunk;
9449                     if (!get_cbor_binary(chunk))
9450                     {
9451                         return false;
9452                     }
9453                     result.insert(result.end(), chunk.begin(), chunk.end());
9454                 }
9455                 return true;
9456             }
9457 
9458             default:
9459             {
9460                 auto last_token = get_token_string();
9461                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary"), BasicJsonType()));
9462             }
9463         }
9464     }
9465 
9466     /*!
9467     @param[in] len  the length of the array or std::size_t(-1) for an
9468                     array of indefinite size
9469     @param[in] tag_handler how CBOR tags should be treated
9470     @return whether array creation completed
9471     */
get_cbor_array(const std::size_t len,const cbor_tag_handler_t tag_handler)9472     bool get_cbor_array(const std::size_t len,
9473                         const cbor_tag_handler_t tag_handler)
9474     {
9475         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9476         {
9477             return false;
9478         }
9479 
9480         if (len != std::size_t(-1))
9481         {
9482             for (std::size_t i = 0; i < len; ++i)
9483             {
9484                 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9485                 {
9486                     return false;
9487                 }
9488             }
9489         }
9490         else
9491         {
9492             while (get() != 0xFF)
9493             {
9494                 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9495                 {
9496                     return false;
9497                 }
9498             }
9499         }
9500 
9501         return sax->end_array();
9502     }
9503 
9504     /*!
9505     @param[in] len  the length of the object or std::size_t(-1) for an
9506                     object of indefinite size
9507     @param[in] tag_handler how CBOR tags should be treated
9508     @return whether object creation completed
9509     */
get_cbor_object(const std::size_t len,const cbor_tag_handler_t tag_handler)9510     bool get_cbor_object(const std::size_t len,
9511                          const cbor_tag_handler_t tag_handler)
9512     {
9513         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9514         {
9515             return false;
9516         }
9517 
9518         if (len != 0)
9519         {
9520             string_t key;
9521             if (len != std::size_t(-1))
9522             {
9523                 for (std::size_t i = 0; i < len; ++i)
9524                 {
9525                     get();
9526                     if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9527                     {
9528                         return false;
9529                     }
9530 
9531                     if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9532                     {
9533                         return false;
9534                     }
9535                     key.clear();
9536                 }
9537             }
9538             else
9539             {
9540                 while (get() != 0xFF)
9541                 {
9542                     if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9543                     {
9544                         return false;
9545                     }
9546 
9547                     if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9548                     {
9549                         return false;
9550                     }
9551                     key.clear();
9552                 }
9553             }
9554         }
9555 
9556         return sax->end_object();
9557     }
9558 
9559     /////////////
9560     // MsgPack //
9561     /////////////
9562 
9563     /*!
9564     @return whether a valid MessagePack value was passed to the SAX parser
9565     */
parse_msgpack_internal()9566     bool parse_msgpack_internal()
9567     {
9568         switch (get())
9569         {
9570             // EOF
9571             case std::char_traits<char_type>::eof():
9572                 return unexpect_eof(input_format_t::msgpack, "value");
9573 
9574             // positive fixint
9575             case 0x00:
9576             case 0x01:
9577             case 0x02:
9578             case 0x03:
9579             case 0x04:
9580             case 0x05:
9581             case 0x06:
9582             case 0x07:
9583             case 0x08:
9584             case 0x09:
9585             case 0x0A:
9586             case 0x0B:
9587             case 0x0C:
9588             case 0x0D:
9589             case 0x0E:
9590             case 0x0F:
9591             case 0x10:
9592             case 0x11:
9593             case 0x12:
9594             case 0x13:
9595             case 0x14:
9596             case 0x15:
9597             case 0x16:
9598             case 0x17:
9599             case 0x18:
9600             case 0x19:
9601             case 0x1A:
9602             case 0x1B:
9603             case 0x1C:
9604             case 0x1D:
9605             case 0x1E:
9606             case 0x1F:
9607             case 0x20:
9608             case 0x21:
9609             case 0x22:
9610             case 0x23:
9611             case 0x24:
9612             case 0x25:
9613             case 0x26:
9614             case 0x27:
9615             case 0x28:
9616             case 0x29:
9617             case 0x2A:
9618             case 0x2B:
9619             case 0x2C:
9620             case 0x2D:
9621             case 0x2E:
9622             case 0x2F:
9623             case 0x30:
9624             case 0x31:
9625             case 0x32:
9626             case 0x33:
9627             case 0x34:
9628             case 0x35:
9629             case 0x36:
9630             case 0x37:
9631             case 0x38:
9632             case 0x39:
9633             case 0x3A:
9634             case 0x3B:
9635             case 0x3C:
9636             case 0x3D:
9637             case 0x3E:
9638             case 0x3F:
9639             case 0x40:
9640             case 0x41:
9641             case 0x42:
9642             case 0x43:
9643             case 0x44:
9644             case 0x45:
9645             case 0x46:
9646             case 0x47:
9647             case 0x48:
9648             case 0x49:
9649             case 0x4A:
9650             case 0x4B:
9651             case 0x4C:
9652             case 0x4D:
9653             case 0x4E:
9654             case 0x4F:
9655             case 0x50:
9656             case 0x51:
9657             case 0x52:
9658             case 0x53:
9659             case 0x54:
9660             case 0x55:
9661             case 0x56:
9662             case 0x57:
9663             case 0x58:
9664             case 0x59:
9665             case 0x5A:
9666             case 0x5B:
9667             case 0x5C:
9668             case 0x5D:
9669             case 0x5E:
9670             case 0x5F:
9671             case 0x60:
9672             case 0x61:
9673             case 0x62:
9674             case 0x63:
9675             case 0x64:
9676             case 0x65:
9677             case 0x66:
9678             case 0x67:
9679             case 0x68:
9680             case 0x69:
9681             case 0x6A:
9682             case 0x6B:
9683             case 0x6C:
9684             case 0x6D:
9685             case 0x6E:
9686             case 0x6F:
9687             case 0x70:
9688             case 0x71:
9689             case 0x72:
9690             case 0x73:
9691             case 0x74:
9692             case 0x75:
9693             case 0x76:
9694             case 0x77:
9695             case 0x78:
9696             case 0x79:
9697             case 0x7A:
9698             case 0x7B:
9699             case 0x7C:
9700             case 0x7D:
9701             case 0x7E:
9702             case 0x7F:
9703                 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9704 
9705             // fixmap
9706             case 0x80:
9707             case 0x81:
9708             case 0x82:
9709             case 0x83:
9710             case 0x84:
9711             case 0x85:
9712             case 0x86:
9713             case 0x87:
9714             case 0x88:
9715             case 0x89:
9716             case 0x8A:
9717             case 0x8B:
9718             case 0x8C:
9719             case 0x8D:
9720             case 0x8E:
9721             case 0x8F:
9722                 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9723 
9724             // fixarray
9725             case 0x90:
9726             case 0x91:
9727             case 0x92:
9728             case 0x93:
9729             case 0x94:
9730             case 0x95:
9731             case 0x96:
9732             case 0x97:
9733             case 0x98:
9734             case 0x99:
9735             case 0x9A:
9736             case 0x9B:
9737             case 0x9C:
9738             case 0x9D:
9739             case 0x9E:
9740             case 0x9F:
9741                 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9742 
9743             // fixstr
9744             case 0xA0:
9745             case 0xA1:
9746             case 0xA2:
9747             case 0xA3:
9748             case 0xA4:
9749             case 0xA5:
9750             case 0xA6:
9751             case 0xA7:
9752             case 0xA8:
9753             case 0xA9:
9754             case 0xAA:
9755             case 0xAB:
9756             case 0xAC:
9757             case 0xAD:
9758             case 0xAE:
9759             case 0xAF:
9760             case 0xB0:
9761             case 0xB1:
9762             case 0xB2:
9763             case 0xB3:
9764             case 0xB4:
9765             case 0xB5:
9766             case 0xB6:
9767             case 0xB7:
9768             case 0xB8:
9769             case 0xB9:
9770             case 0xBA:
9771             case 0xBB:
9772             case 0xBC:
9773             case 0xBD:
9774             case 0xBE:
9775             case 0xBF:
9776             case 0xD9: // str 8
9777             case 0xDA: // str 16
9778             case 0xDB: // str 32
9779             {
9780                 string_t s;
9781                 return get_msgpack_string(s) && sax->string(s);
9782             }
9783 
9784             case 0xC0: // nil
9785                 return sax->null();
9786 
9787             case 0xC2: // false
9788                 return sax->boolean(false);
9789 
9790             case 0xC3: // true
9791                 return sax->boolean(true);
9792 
9793             case 0xC4: // bin 8
9794             case 0xC5: // bin 16
9795             case 0xC6: // bin 32
9796             case 0xC7: // ext 8
9797             case 0xC8: // ext 16
9798             case 0xC9: // ext 32
9799             case 0xD4: // fixext 1
9800             case 0xD5: // fixext 2
9801             case 0xD6: // fixext 4
9802             case 0xD7: // fixext 8
9803             case 0xD8: // fixext 16
9804             {
9805                 binary_t b;
9806                 return get_msgpack_binary(b) && sax->binary(b);
9807             }
9808 
9809             case 0xCA: // float 32
9810             {
9811                 float number{};
9812                 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9813             }
9814 
9815             case 0xCB: // float 64
9816             {
9817                 double number{};
9818                 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9819             }
9820 
9821             case 0xCC: // uint 8
9822             {
9823                 std::uint8_t number{};
9824                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9825             }
9826 
9827             case 0xCD: // uint 16
9828             {
9829                 std::uint16_t number{};
9830                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9831             }
9832 
9833             case 0xCE: // uint 32
9834             {
9835                 std::uint32_t number{};
9836                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9837             }
9838 
9839             case 0xCF: // uint 64
9840             {
9841                 std::uint64_t number{};
9842                 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9843             }
9844 
9845             case 0xD0: // int 8
9846             {
9847                 std::int8_t number{};
9848                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9849             }
9850 
9851             case 0xD1: // int 16
9852             {
9853                 std::int16_t number{};
9854                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9855             }
9856 
9857             case 0xD2: // int 32
9858             {
9859                 std::int32_t number{};
9860                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9861             }
9862 
9863             case 0xD3: // int 64
9864             {
9865                 std::int64_t number{};
9866                 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9867             }
9868 
9869             case 0xDC: // array 16
9870             {
9871                 std::uint16_t len{};
9872                 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9873             }
9874 
9875             case 0xDD: // array 32
9876             {
9877                 std::uint32_t len{};
9878                 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9879             }
9880 
9881             case 0xDE: // map 16
9882             {
9883                 std::uint16_t len{};
9884                 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9885             }
9886 
9887             case 0xDF: // map 32
9888             {
9889                 std::uint32_t len{};
9890                 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9891             }
9892 
9893             // negative fixint
9894             case 0xE0:
9895             case 0xE1:
9896             case 0xE2:
9897             case 0xE3:
9898             case 0xE4:
9899             case 0xE5:
9900             case 0xE6:
9901             case 0xE7:
9902             case 0xE8:
9903             case 0xE9:
9904             case 0xEA:
9905             case 0xEB:
9906             case 0xEC:
9907             case 0xED:
9908             case 0xEE:
9909             case 0xEF:
9910             case 0xF0:
9911             case 0xF1:
9912             case 0xF2:
9913             case 0xF3:
9914             case 0xF4:
9915             case 0xF5:
9916             case 0xF6:
9917             case 0xF7:
9918             case 0xF8:
9919             case 0xF9:
9920             case 0xFA:
9921             case 0xFB:
9922             case 0xFC:
9923             case 0xFD:
9924             case 0xFE:
9925             case 0xFF:
9926                 return sax->number_integer(static_cast<std::int8_t>(current));
9927 
9928             default: // anything else
9929             {
9930                 auto last_token = get_token_string();
9931                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9932             }
9933         }
9934     }
9935 
9936     /*!
9937     @brief reads a MessagePack string
9938 
9939     This function first reads starting bytes to determine the expected
9940     string length and then copies this number of bytes into a string.
9941 
9942     @param[out] result  created string
9943 
9944     @return whether string creation completed
9945     */
get_msgpack_string(string_t & result)9946     bool get_msgpack_string(string_t& result)
9947     {
9948         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9949         {
9950             return false;
9951         }
9952 
9953         switch (current)
9954         {
9955             // fixstr
9956             case 0xA0:
9957             case 0xA1:
9958             case 0xA2:
9959             case 0xA3:
9960             case 0xA4:
9961             case 0xA5:
9962             case 0xA6:
9963             case 0xA7:
9964             case 0xA8:
9965             case 0xA9:
9966             case 0xAA:
9967             case 0xAB:
9968             case 0xAC:
9969             case 0xAD:
9970             case 0xAE:
9971             case 0xAF:
9972             case 0xB0:
9973             case 0xB1:
9974             case 0xB2:
9975             case 0xB3:
9976             case 0xB4:
9977             case 0xB5:
9978             case 0xB6:
9979             case 0xB7:
9980             case 0xB8:
9981             case 0xB9:
9982             case 0xBA:
9983             case 0xBB:
9984             case 0xBC:
9985             case 0xBD:
9986             case 0xBE:
9987             case 0xBF:
9988             {
9989                 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9990             }
9991 
9992             case 0xD9: // str 8
9993             {
9994                 std::uint8_t len{};
9995                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9996             }
9997 
9998             case 0xDA: // str 16
9999             {
10000                 std::uint16_t len{};
10001                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10002             }
10003 
10004             case 0xDB: // str 32
10005             {
10006                 std::uint32_t len{};
10007                 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10008             }
10009 
10010             default:
10011             {
10012                 auto last_token = get_token_string();
10013                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string"), BasicJsonType()));
10014             }
10015         }
10016     }
10017 
10018     /*!
10019     @brief reads a MessagePack byte array
10020 
10021     This function first reads starting bytes to determine the expected
10022     byte array length and then copies this number of bytes into a byte array.
10023 
10024     @param[out] result  created byte array
10025 
10026     @return whether byte array creation completed
10027     */
get_msgpack_binary(binary_t & result)10028     bool get_msgpack_binary(binary_t& result)
10029     {
10030         // helper function to set the subtype
10031         auto assign_and_return_true = [&result](std::int8_t subtype)
10032         {
10033             result.set_subtype(static_cast<std::uint8_t>(subtype));
10034             return true;
10035         };
10036 
10037         switch (current)
10038         {
10039             case 0xC4: // bin 8
10040             {
10041                 std::uint8_t len{};
10042                 return get_number(input_format_t::msgpack, len) &&
10043                        get_binary(input_format_t::msgpack, len, result);
10044             }
10045 
10046             case 0xC5: // bin 16
10047             {
10048                 std::uint16_t len{};
10049                 return get_number(input_format_t::msgpack, len) &&
10050                        get_binary(input_format_t::msgpack, len, result);
10051             }
10052 
10053             case 0xC6: // bin 32
10054             {
10055                 std::uint32_t len{};
10056                 return get_number(input_format_t::msgpack, len) &&
10057                        get_binary(input_format_t::msgpack, len, result);
10058             }
10059 
10060             case 0xC7: // ext 8
10061             {
10062                 std::uint8_t len{};
10063                 std::int8_t subtype{};
10064                 return get_number(input_format_t::msgpack, len) &&
10065                        get_number(input_format_t::msgpack, subtype) &&
10066                        get_binary(input_format_t::msgpack, len, result) &&
10067                        assign_and_return_true(subtype);
10068             }
10069 
10070             case 0xC8: // ext 16
10071             {
10072                 std::uint16_t len{};
10073                 std::int8_t subtype{};
10074                 return get_number(input_format_t::msgpack, len) &&
10075                        get_number(input_format_t::msgpack, subtype) &&
10076                        get_binary(input_format_t::msgpack, len, result) &&
10077                        assign_and_return_true(subtype);
10078             }
10079 
10080             case 0xC9: // ext 32
10081             {
10082                 std::uint32_t len{};
10083                 std::int8_t subtype{};
10084                 return get_number(input_format_t::msgpack, len) &&
10085                        get_number(input_format_t::msgpack, subtype) &&
10086                        get_binary(input_format_t::msgpack, len, result) &&
10087                        assign_and_return_true(subtype);
10088             }
10089 
10090             case 0xD4: // fixext 1
10091             {
10092                 std::int8_t subtype{};
10093                 return get_number(input_format_t::msgpack, subtype) &&
10094                        get_binary(input_format_t::msgpack, 1, result) &&
10095                        assign_and_return_true(subtype);
10096             }
10097 
10098             case 0xD5: // fixext 2
10099             {
10100                 std::int8_t subtype{};
10101                 return get_number(input_format_t::msgpack, subtype) &&
10102                        get_binary(input_format_t::msgpack, 2, result) &&
10103                        assign_and_return_true(subtype);
10104             }
10105 
10106             case 0xD6: // fixext 4
10107             {
10108                 std::int8_t subtype{};
10109                 return get_number(input_format_t::msgpack, subtype) &&
10110                        get_binary(input_format_t::msgpack, 4, result) &&
10111                        assign_and_return_true(subtype);
10112             }
10113 
10114             case 0xD7: // fixext 8
10115             {
10116                 std::int8_t subtype{};
10117                 return get_number(input_format_t::msgpack, subtype) &&
10118                        get_binary(input_format_t::msgpack, 8, result) &&
10119                        assign_and_return_true(subtype);
10120             }
10121 
10122             case 0xD8: // fixext 16
10123             {
10124                 std::int8_t subtype{};
10125                 return get_number(input_format_t::msgpack, subtype) &&
10126                        get_binary(input_format_t::msgpack, 16, result) &&
10127                        assign_and_return_true(subtype);
10128             }
10129 
10130             default:           // LCOV_EXCL_LINE
10131                 return false;  // LCOV_EXCL_LINE
10132         }
10133     }
10134 
10135     /*!
10136     @param[in] len  the length of the array
10137     @return whether array creation completed
10138     */
get_msgpack_array(const std::size_t len)10139     bool get_msgpack_array(const std::size_t len)
10140     {
10141         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10142         {
10143             return false;
10144         }
10145 
10146         for (std::size_t i = 0; i < len; ++i)
10147         {
10148             if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10149             {
10150                 return false;
10151             }
10152         }
10153 
10154         return sax->end_array();
10155     }
10156 
10157     /*!
10158     @param[in] len  the length of the object
10159     @return whether object creation completed
10160     */
get_msgpack_object(const std::size_t len)10161     bool get_msgpack_object(const std::size_t len)
10162     {
10163         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10164         {
10165             return false;
10166         }
10167 
10168         string_t key;
10169         for (std::size_t i = 0; i < len; ++i)
10170         {
10171             get();
10172             if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10173             {
10174                 return false;
10175             }
10176 
10177             if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10178             {
10179                 return false;
10180             }
10181             key.clear();
10182         }
10183 
10184         return sax->end_object();
10185     }
10186 
10187     ////////////
10188     // UBJSON //
10189     ////////////
10190 
10191     /*!
10192     @param[in] get_char  whether a new character should be retrieved from the
10193                          input (true, default) or whether the last read
10194                          character should be considered instead
10195 
10196     @return whether a valid UBJSON value was passed to the SAX parser
10197     */
parse_ubjson_internal(const bool get_char=true)10198     bool parse_ubjson_internal(const bool get_char = true)
10199     {
10200         return get_ubjson_value(get_char ? get_ignore_noop() : current);
10201     }
10202 
10203     /*!
10204     @brief reads a UBJSON string
10205 
10206     This function is either called after reading the 'S' byte explicitly
10207     indicating a string, or in case of an object key where the 'S' byte can be
10208     left out.
10209 
10210     @param[out] result   created string
10211     @param[in] get_char  whether a new character should be retrieved from the
10212                          input (true, default) or whether the last read
10213                          character should be considered instead
10214 
10215     @return whether string creation completed
10216     */
get_ubjson_string(string_t & result,const bool get_char=true)10217     bool get_ubjson_string(string_t& result, const bool get_char = true)
10218     {
10219         if (get_char)
10220         {
10221             get();  // TODO(niels): may we ignore N here?
10222         }
10223 
10224         if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10225         {
10226             return false;
10227         }
10228 
10229         switch (current)
10230         {
10231             case 'U':
10232             {
10233                 std::uint8_t len{};
10234                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10235             }
10236 
10237             case 'i':
10238             {
10239                 std::int8_t len{};
10240                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10241             }
10242 
10243             case 'I':
10244             {
10245                 std::int16_t len{};
10246                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10247             }
10248 
10249             case 'l':
10250             {
10251                 std::int32_t len{};
10252                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10253             }
10254 
10255             case 'L':
10256             {
10257                 std::int64_t len{};
10258                 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10259             }
10260 
10261             default:
10262                 auto last_token = get_token_string();
10263                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"), BasicJsonType()));
10264         }
10265     }
10266 
10267     /*!
10268     @param[out] result  determined size
10269     @return whether size determination completed
10270     */
get_ubjson_size_value(std::size_t & result)10271     bool get_ubjson_size_value(std::size_t& result)
10272     {
10273         switch (get_ignore_noop())
10274         {
10275             case 'U':
10276             {
10277                 std::uint8_t number{};
10278                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10279                 {
10280                     return false;
10281                 }
10282                 result = static_cast<std::size_t>(number);
10283                 return true;
10284             }
10285 
10286             case 'i':
10287             {
10288                 std::int8_t number{};
10289                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10290                 {
10291                     return false;
10292                 }
10293                 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10294                 return true;
10295             }
10296 
10297             case 'I':
10298             {
10299                 std::int16_t number{};
10300                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10301                 {
10302                     return false;
10303                 }
10304                 result = static_cast<std::size_t>(number);
10305                 return true;
10306             }
10307 
10308             case 'l':
10309             {
10310                 std::int32_t number{};
10311                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10312                 {
10313                     return false;
10314                 }
10315                 result = static_cast<std::size_t>(number);
10316                 return true;
10317             }
10318 
10319             case 'L':
10320             {
10321                 std::int64_t number{};
10322                 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10323                 {
10324                     return false;
10325                 }
10326                 result = static_cast<std::size_t>(number);
10327                 return true;
10328             }
10329 
10330             default:
10331             {
10332                 auto last_token = get_token_string();
10333                 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"), BasicJsonType()));
10334             }
10335         }
10336     }
10337 
10338     /*!
10339     @brief determine the type and size for a container
10340 
10341     In the optimized UBJSON format, a type and a size can be provided to allow
10342     for a more compact representation.
10343 
10344     @param[out] result  pair of the size and the type
10345 
10346     @return whether pair creation completed
10347     */
get_ubjson_size_type(std::pair<std::size_t,char_int_type> & result)10348     bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
10349     {
10350         result.first = string_t::npos; // size
10351         result.second = 0; // type
10352 
10353         get_ignore_noop();
10354 
10355         if (current == '$')
10356         {
10357             result.second = get();  // must not ignore 'N', because 'N' maybe the type
10358             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
10359             {
10360                 return false;
10361             }
10362 
10363             get_ignore_noop();
10364             if (JSON_HEDLEY_UNLIKELY(current != '#'))
10365             {
10366                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10367                 {
10368                     return false;
10369                 }
10370                 auto last_token = get_token_string();
10371                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size"), BasicJsonType()));
10372             }
10373 
10374             return get_ubjson_size_value(result.first);
10375         }
10376 
10377         if (current == '#')
10378         {
10379             return get_ubjson_size_value(result.first);
10380         }
10381 
10382         return true;
10383     }
10384 
10385     /*!
10386     @param prefix  the previously read or set type prefix
10387     @return whether value creation completed
10388     */
get_ubjson_value(const char_int_type prefix)10389     bool get_ubjson_value(const char_int_type prefix)
10390     {
10391         switch (prefix)
10392         {
10393             case std::char_traits<char_type>::eof():  // EOF
10394                 return unexpect_eof(input_format_t::ubjson, "value");
10395 
10396             case 'T':  // true
10397                 return sax->boolean(true);
10398             case 'F':  // false
10399                 return sax->boolean(false);
10400 
10401             case 'Z':  // null
10402                 return sax->null();
10403 
10404             case 'U':
10405             {
10406                 std::uint8_t number{};
10407                 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
10408             }
10409 
10410             case 'i':
10411             {
10412                 std::int8_t number{};
10413                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10414             }
10415 
10416             case 'I':
10417             {
10418                 std::int16_t number{};
10419                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10420             }
10421 
10422             case 'l':
10423             {
10424                 std::int32_t number{};
10425                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10426             }
10427 
10428             case 'L':
10429             {
10430                 std::int64_t number{};
10431                 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10432             }
10433 
10434             case 'd':
10435             {
10436                 float number{};
10437                 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10438             }
10439 
10440             case 'D':
10441             {
10442                 double number{};
10443                 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10444             }
10445 
10446             case 'H':
10447             {
10448                 return get_ubjson_high_precision_number();
10449             }
10450 
10451             case 'C':  // char
10452             {
10453                 get();
10454                 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
10455                 {
10456                     return false;
10457                 }
10458                 if (JSON_HEDLEY_UNLIKELY(current > 127))
10459                 {
10460                     auto last_token = get_token_string();
10461                     return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char"), BasicJsonType()));
10462                 }
10463                 string_t s(1, static_cast<typename string_t::value_type>(current));
10464                 return sax->string(s);
10465             }
10466 
10467             case 'S':  // string
10468             {
10469                 string_t s;
10470                 return get_ubjson_string(s) && sax->string(s);
10471             }
10472 
10473             case '[':  // array
10474                 return get_ubjson_array();
10475 
10476             case '{':  // object
10477                 return get_ubjson_object();
10478 
10479             default: // anything else
10480             {
10481                 auto last_token = get_token_string();
10482                 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
10483             }
10484         }
10485     }
10486 
10487     /*!
10488     @return whether array creation completed
10489     */
get_ubjson_array()10490     bool get_ubjson_array()
10491     {
10492         std::pair<std::size_t, char_int_type> size_and_type;
10493         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10494         {
10495             return false;
10496         }
10497 
10498         if (size_and_type.first != string_t::npos)
10499         {
10500             if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
10501             {
10502                 return false;
10503             }
10504 
10505             if (size_and_type.second != 0)
10506             {
10507                 if (size_and_type.second != 'N')
10508                 {
10509                     for (std::size_t i = 0; i < size_and_type.first; ++i)
10510                     {
10511                         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10512                         {
10513                             return false;
10514                         }
10515                     }
10516                 }
10517             }
10518             else
10519             {
10520                 for (std::size_t i = 0; i < size_and_type.first; ++i)
10521                 {
10522                     if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10523                     {
10524                         return false;
10525                     }
10526                 }
10527             }
10528         }
10529         else
10530         {
10531             if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10532             {
10533                 return false;
10534             }
10535 
10536             while (current != ']')
10537             {
10538                 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
10539                 {
10540                     return false;
10541                 }
10542                 get_ignore_noop();
10543             }
10544         }
10545 
10546         return sax->end_array();
10547     }
10548 
10549     /*!
10550     @return whether object creation completed
10551     */
get_ubjson_object()10552     bool get_ubjson_object()
10553     {
10554         std::pair<std::size_t, char_int_type> size_and_type;
10555         if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10556         {
10557             return false;
10558         }
10559 
10560         string_t key;
10561         if (size_and_type.first != string_t::npos)
10562         {
10563             if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
10564             {
10565                 return false;
10566             }
10567 
10568             if (size_and_type.second != 0)
10569             {
10570                 for (std::size_t i = 0; i < size_and_type.first; ++i)
10571                 {
10572                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10573                     {
10574                         return false;
10575                     }
10576                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10577                     {
10578                         return false;
10579                     }
10580                     key.clear();
10581                 }
10582             }
10583             else
10584             {
10585                 for (std::size_t i = 0; i < size_and_type.first; ++i)
10586                 {
10587                     if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10588                     {
10589                         return false;
10590                     }
10591                     if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10592                     {
10593                         return false;
10594                     }
10595                     key.clear();
10596                 }
10597             }
10598         }
10599         else
10600         {
10601             if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10602             {
10603                 return false;
10604             }
10605 
10606             while (current != '}')
10607             {
10608                 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
10609                 {
10610                     return false;
10611                 }
10612                 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10613                 {
10614                     return false;
10615                 }
10616                 get_ignore_noop();
10617                 key.clear();
10618             }
10619         }
10620 
10621         return sax->end_object();
10622     }
10623 
10624     // Note, no reader for UBJSON binary types is implemented because they do
10625     // not exist
10626 
get_ubjson_high_precision_number()10627     bool get_ubjson_high_precision_number()
10628     {
10629         // get size of following number string
10630         std::size_t size{};
10631         auto res = get_ubjson_size_value(size);
10632         if (JSON_HEDLEY_UNLIKELY(!res))
10633         {
10634             return res;
10635         }
10636 
10637         // get number string
10638         std::vector<char> number_vector;
10639         for (std::size_t i = 0; i < size; ++i)
10640         {
10641             get();
10642             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
10643             {
10644                 return false;
10645             }
10646             number_vector.push_back(static_cast<char>(current));
10647         }
10648 
10649         // parse number string
10650         using ia_type = decltype(detail::input_adapter(number_vector));
10651         auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
10652         const auto result_number = number_lexer.scan();
10653         const auto number_string = number_lexer.get_token_string();
10654         const auto result_remainder = number_lexer.scan();
10655 
10656         using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
10657 
10658         if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
10659         {
10660             return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
10661         }
10662 
10663         switch (result_number)
10664         {
10665             case token_type::value_integer:
10666                 return sax->number_integer(number_lexer.get_number_integer());
10667             case token_type::value_unsigned:
10668                 return sax->number_unsigned(number_lexer.get_number_unsigned());
10669             case token_type::value_float:
10670                 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
10671             case token_type::uninitialized:
10672             case token_type::literal_true:
10673             case token_type::literal_false:
10674             case token_type::literal_null:
10675             case token_type::value_string:
10676             case token_type::begin_array:
10677             case token_type::begin_object:
10678             case token_type::end_array:
10679             case token_type::end_object:
10680             case token_type::name_separator:
10681             case token_type::value_separator:
10682             case token_type::parse_error:
10683             case token_type::end_of_input:
10684             case token_type::literal_or_value:
10685             default:
10686                 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
10687         }
10688     }
10689 
10690     ///////////////////////
10691     // Utility functions //
10692     ///////////////////////
10693 
10694     /*!
10695     @brief get next character from the input
10696 
10697     This function provides the interface to the used input adapter. It does
10698     not throw in case the input reached EOF, but returns a -'ve valued
10699     `std::char_traits<char_type>::eof()` in that case.
10700 
10701     @return character read from the input
10702     */
get()10703     char_int_type get()
10704     {
10705         ++chars_read;
10706         return current = ia.get_character();
10707     }
10708 
10709     /*!
10710     @return character read from the input after ignoring all 'N' entries
10711     */
get_ignore_noop()10712     char_int_type get_ignore_noop()
10713     {
10714         do
10715         {
10716             get();
10717         }
10718         while (current == 'N');
10719 
10720         return current;
10721     }
10722 
10723     /*
10724     @brief read a number from the input
10725 
10726     @tparam NumberType the type of the number
10727     @param[in] format   the current format (for diagnostics)
10728     @param[out] result  number of type @a NumberType
10729 
10730     @return whether conversion completed
10731 
10732     @note This function needs to respect the system's endianess, because
10733           bytes in CBOR, MessagePack, and UBJSON are stored in network order
10734           (big endian) and therefore need reordering on little endian systems.
10735     */
10736     template<typename NumberType, bool InputIsLittleEndian = false>
get_number(const input_format_t format,NumberType & result)10737     bool get_number(const input_format_t format, NumberType& result)
10738     {
10739         // step 1: read input into array with system's byte order
10740         std::array<std::uint8_t, sizeof(NumberType)> vec{};
10741         for (std::size_t i = 0; i < sizeof(NumberType); ++i)
10742         {
10743             get();
10744             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10745             {
10746                 return false;
10747             }
10748 
10749             // reverse byte order prior to conversion if necessary
10750             if (is_little_endian != InputIsLittleEndian)
10751             {
10752                 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10753             }
10754             else
10755             {
10756                 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10757             }
10758         }
10759 
10760         // step 2: convert array into number of type T and return
10761         std::memcpy(&result, vec.data(), sizeof(NumberType));
10762         return true;
10763     }
10764 
10765     /*!
10766     @brief create a string by reading characters from the input
10767 
10768     @tparam NumberType the type of the number
10769     @param[in] format the current format (for diagnostics)
10770     @param[in] len number of characters to read
10771     @param[out] result string created by reading @a len bytes
10772 
10773     @return whether string creation completed
10774 
10775     @note We can not reserve @a len bytes for the result, because @a len
10776           may be too large. Usually, @ref unexpect_eof() detects the end of
10777           the input before we run out of string memory.
10778     */
10779     template<typename NumberType>
get_string(const input_format_t format,const NumberType len,string_t & result)10780     bool get_string(const input_format_t format,
10781                     const NumberType len,
10782                     string_t& result)
10783     {
10784         bool success = true;
10785         for (NumberType i = 0; i < len; i++)
10786         {
10787             get();
10788             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10789             {
10790                 success = false;
10791                 break;
10792             }
10793             result.push_back(static_cast<typename string_t::value_type>(current));
10794         }
10795         return success;
10796     }
10797 
10798     /*!
10799     @brief create a byte array by reading bytes from the input
10800 
10801     @tparam NumberType the type of the number
10802     @param[in] format the current format (for diagnostics)
10803     @param[in] len number of bytes to read
10804     @param[out] result byte array created by reading @a len bytes
10805 
10806     @return whether byte array creation completed
10807 
10808     @note We can not reserve @a len bytes for the result, because @a len
10809           may be too large. Usually, @ref unexpect_eof() detects the end of
10810           the input before we run out of memory.
10811     */
10812     template<typename NumberType>
get_binary(const input_format_t format,const NumberType len,binary_t & result)10813     bool get_binary(const input_format_t format,
10814                     const NumberType len,
10815                     binary_t& result)
10816     {
10817         bool success = true;
10818         for (NumberType i = 0; i < len; i++)
10819         {
10820             get();
10821             if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10822             {
10823                 success = false;
10824                 break;
10825             }
10826             result.push_back(static_cast<std::uint8_t>(current));
10827         }
10828         return success;
10829     }
10830 
10831     /*!
10832     @param[in] format   the current format (for diagnostics)
10833     @param[in] context  further context information (for diagnostics)
10834     @return whether the last read character is not EOF
10835     */
10836     JSON_HEDLEY_NON_NULL(3)
unexpect_eof(const input_format_t format,const char * context) const10837     bool unexpect_eof(const input_format_t format, const char* context) const
10838     {
10839         if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10840         {
10841             return sax->parse_error(chars_read, "<end of file>",
10842                                     parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
10843         }
10844         return true;
10845     }
10846 
10847     /*!
10848     @return a string representation of the last read byte
10849     */
get_token_string() const10850     std::string get_token_string() const
10851     {
10852         std::array<char, 3> cr{{}};
10853         (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10854         return std::string{cr.data()};
10855     }
10856 
10857     /*!
10858     @param[in] format   the current format
10859     @param[in] detail   a detailed error message
10860     @param[in] context  further context information
10861     @return a message string to use in the parse_error exceptions
10862     */
exception_message(const input_format_t format,const std::string & detail,const std::string & context) const10863     std::string exception_message(const input_format_t format,
10864                                   const std::string& detail,
10865                                   const std::string& context) const
10866     {
10867         std::string error_msg = "syntax error while parsing ";
10868 
10869         switch (format)
10870         {
10871             case input_format_t::cbor:
10872                 error_msg += "CBOR";
10873                 break;
10874 
10875             case input_format_t::msgpack:
10876                 error_msg += "MessagePack";
10877                 break;
10878 
10879             case input_format_t::ubjson:
10880                 error_msg += "UBJSON";
10881                 break;
10882 
10883             case input_format_t::bson:
10884                 error_msg += "BSON";
10885                 break;
10886 
10887             case input_format_t::json: // LCOV_EXCL_LINE
10888             default:            // LCOV_EXCL_LINE
10889                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10890         }
10891 
10892         return error_msg + " " + context + ": " + detail;
10893     }
10894 
10895   private:
10896     /// input adapter
10897     InputAdapterType ia;
10898 
10899     /// the current character
10900     char_int_type current = std::char_traits<char_type>::eof();
10901 
10902     /// the number of characters read
10903     std::size_t chars_read = 0;
10904 
10905     /// whether we can assume little endianess
10906     const bool is_little_endian = little_endianess();
10907 
10908     /// the SAX parser
10909     json_sax_t* sax = nullptr;
10910 };
10911 }  // namespace detail
10912 }  // namespace nlohmann
10913 
10914 // #include <nlohmann/detail/input/input_adapters.hpp>
10915 
10916 // #include <nlohmann/detail/input/lexer.hpp>
10917 
10918 // #include <nlohmann/detail/input/parser.hpp>
10919 
10920 
10921 #include <cmath> // isfinite
10922 #include <cstdint> // uint8_t
10923 #include <functional> // function
10924 #include <string> // string
10925 #include <utility> // move
10926 #include <vector> // vector
10927 
10928 // #include <nlohmann/detail/exceptions.hpp>
10929 
10930 // #include <nlohmann/detail/input/input_adapters.hpp>
10931 
10932 // #include <nlohmann/detail/input/json_sax.hpp>
10933 
10934 // #include <nlohmann/detail/input/lexer.hpp>
10935 
10936 // #include <nlohmann/detail/macro_scope.hpp>
10937 
10938 // #include <nlohmann/detail/meta/is_sax.hpp>
10939 
10940 // #include <nlohmann/detail/value_t.hpp>
10941 
10942 
10943 namespace nlohmann
10944 {
10945 namespace detail
10946 {
10947 ////////////
10948 // parser //
10949 ////////////
10950 
10951 enum class parse_event_t : std::uint8_t
10952 {
10953     /// the parser read `{` and started to process a JSON object
10954     object_start,
10955     /// the parser read `}` and finished processing a JSON object
10956     object_end,
10957     /// the parser read `[` and started to process a JSON array
10958     array_start,
10959     /// the parser read `]` and finished processing a JSON array
10960     array_end,
10961     /// the parser read a key of a value in an object
10962     key,
10963     /// the parser finished reading a JSON value
10964     value
10965 };
10966 
10967 template<typename BasicJsonType>
10968 using parser_callback_t =
10969     std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
10970 
10971 /*!
10972 @brief syntax analysis
10973 
10974 This class implements a recursive descent parser.
10975 */
10976 template<typename BasicJsonType, typename InputAdapterType>
10977 class parser
10978 {
10979     using number_integer_t = typename BasicJsonType::number_integer_t;
10980     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10981     using number_float_t = typename BasicJsonType::number_float_t;
10982     using string_t = typename BasicJsonType::string_t;
10983     using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10984     using token_type = typename lexer_t::token_type;
10985 
10986   public:
10987     /// 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)10988     explicit parser(InputAdapterType&& adapter,
10989                     const parser_callback_t<BasicJsonType> cb = nullptr,
10990                     const bool allow_exceptions_ = true,
10991                     const bool skip_comments = false)
10992         : callback(cb)
10993         , m_lexer(std::move(adapter), skip_comments)
10994         , allow_exceptions(allow_exceptions_)
10995     {
10996         // read first token
10997         get_token();
10998     }
10999 
11000     /*!
11001     @brief public parser interface
11002 
11003     @param[in] strict      whether to expect the last token to be EOF
11004     @param[in,out] result  parsed JSON value
11005 
11006     @throw parse_error.101 in case of an unexpected token
11007     @throw parse_error.102 if to_unicode fails or surrogate error
11008     @throw parse_error.103 if to_unicode fails
11009     */
parse(const bool strict,BasicJsonType & result)11010     void parse(const bool strict, BasicJsonType& result)
11011     {
11012         if (callback)
11013         {
11014             json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
11015             sax_parse_internal(&sdp);
11016 
11017             // in strict mode, input must be completely read
11018             if (strict && (get_token() != token_type::end_of_input))
11019             {
11020                 sdp.parse_error(m_lexer.get_position(),
11021                                 m_lexer.get_token_string(),
11022                                 parse_error::create(101, m_lexer.get_position(),
11023                                                     exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11024             }
11025 
11026             // in case of an error, return discarded value
11027             if (sdp.is_errored())
11028             {
11029                 result = value_t::discarded;
11030                 return;
11031             }
11032 
11033             // set top-level value to null if it was discarded by the callback
11034             // function
11035             if (result.is_discarded())
11036             {
11037                 result = nullptr;
11038             }
11039         }
11040         else
11041         {
11042             json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
11043             sax_parse_internal(&sdp);
11044 
11045             // in strict mode, input must be completely read
11046             if (strict && (get_token() != token_type::end_of_input))
11047             {
11048                 sdp.parse_error(m_lexer.get_position(),
11049                                 m_lexer.get_token_string(),
11050                                 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11051             }
11052 
11053             // in case of an error, return discarded value
11054             if (sdp.is_errored())
11055             {
11056                 result = value_t::discarded;
11057                 return;
11058             }
11059         }
11060 
11061         result.assert_invariant();
11062     }
11063 
11064     /*!
11065     @brief public accept interface
11066 
11067     @param[in] strict  whether to expect the last token to be EOF
11068     @return whether the input is a proper JSON text
11069     */
accept(const bool strict=true)11070     bool accept(const bool strict = true)
11071     {
11072         json_sax_acceptor<BasicJsonType> sax_acceptor;
11073         return sax_parse(&sax_acceptor, strict);
11074     }
11075 
11076     template<typename SAX>
11077     JSON_HEDLEY_NON_NULL(2)
sax_parse(SAX * sax,const bool strict=true)11078     bool sax_parse(SAX* sax, const bool strict = true)
11079     {
11080         (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
11081         const bool result = sax_parse_internal(sax);
11082 
11083         // strict mode: next byte must be EOF
11084         if (result && strict && (get_token() != token_type::end_of_input))
11085         {
11086             return sax->parse_error(m_lexer.get_position(),
11087                                     m_lexer.get_token_string(),
11088                                     parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11089         }
11090 
11091         return result;
11092     }
11093 
11094   private:
11095     template<typename SAX>
11096     JSON_HEDLEY_NON_NULL(2)
sax_parse_internal(SAX * sax)11097     bool sax_parse_internal(SAX* sax)
11098     {
11099         // stack to remember the hierarchy of structured values we are parsing
11100         // true = array; false = object
11101         std::vector<bool> states;
11102         // value to avoid a goto (see comment where set to true)
11103         bool skip_to_state_evaluation = false;
11104 
11105         while (true)
11106         {
11107             if (!skip_to_state_evaluation)
11108             {
11109                 // invariant: get_token() was called before each iteration
11110                 switch (last_token)
11111                 {
11112                     case token_type::begin_object:
11113                     {
11114                         if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
11115                         {
11116                             return false;
11117                         }
11118 
11119                         // closing } -> we are done
11120                         if (get_token() == token_type::end_object)
11121                         {
11122                             if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11123                             {
11124                                 return false;
11125                             }
11126                             break;
11127                         }
11128 
11129                         // parse key
11130                         if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11131                         {
11132                             return sax->parse_error(m_lexer.get_position(),
11133                                                     m_lexer.get_token_string(),
11134                                                     parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11135                         }
11136                         if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11137                         {
11138                             return false;
11139                         }
11140 
11141                         // parse separator (:)
11142                         if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11143                         {
11144                             return sax->parse_error(m_lexer.get_position(),
11145                                                     m_lexer.get_token_string(),
11146                                                     parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11147                         }
11148 
11149                         // remember we are now inside an object
11150                         states.push_back(false);
11151 
11152                         // parse values
11153                         get_token();
11154                         continue;
11155                     }
11156 
11157                     case token_type::begin_array:
11158                     {
11159                         if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
11160                         {
11161                             return false;
11162                         }
11163 
11164                         // closing ] -> we are done
11165                         if (get_token() == token_type::end_array)
11166                         {
11167                             if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11168                             {
11169                                 return false;
11170                             }
11171                             break;
11172                         }
11173 
11174                         // remember we are now inside an array
11175                         states.push_back(true);
11176 
11177                         // parse values (no need to call get_token)
11178                         continue;
11179                     }
11180 
11181                     case token_type::value_float:
11182                     {
11183                         const auto res = m_lexer.get_number_float();
11184 
11185                         if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11186                         {
11187                             return sax->parse_error(m_lexer.get_position(),
11188                                                     m_lexer.get_token_string(),
11189                                                     out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
11190                         }
11191 
11192                         if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11193                         {
11194                             return false;
11195                         }
11196 
11197                         break;
11198                     }
11199 
11200                     case token_type::literal_false:
11201                     {
11202                         if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11203                         {
11204                             return false;
11205                         }
11206                         break;
11207                     }
11208 
11209                     case token_type::literal_null:
11210                     {
11211                         if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11212                         {
11213                             return false;
11214                         }
11215                         break;
11216                     }
11217 
11218                     case token_type::literal_true:
11219                     {
11220                         if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11221                         {
11222                             return false;
11223                         }
11224                         break;
11225                     }
11226 
11227                     case token_type::value_integer:
11228                     {
11229                         if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11230                         {
11231                             return false;
11232                         }
11233                         break;
11234                     }
11235 
11236                     case token_type::value_string:
11237                     {
11238                         if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11239                         {
11240                             return false;
11241                         }
11242                         break;
11243                     }
11244 
11245                     case token_type::value_unsigned:
11246                     {
11247                         if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11248                         {
11249                             return false;
11250                         }
11251                         break;
11252                     }
11253 
11254                     case token_type::parse_error:
11255                     {
11256                         // using "uninitialized" to avoid "expected" message
11257                         return sax->parse_error(m_lexer.get_position(),
11258                                                 m_lexer.get_token_string(),
11259                                                 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
11260                     }
11261 
11262                     case token_type::uninitialized:
11263                     case token_type::end_array:
11264                     case token_type::end_object:
11265                     case token_type::name_separator:
11266                     case token_type::value_separator:
11267                     case token_type::end_of_input:
11268                     case token_type::literal_or_value:
11269                     default: // the last token was unexpected
11270                     {
11271                         return sax->parse_error(m_lexer.get_position(),
11272                                                 m_lexer.get_token_string(),
11273                                                 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
11274                     }
11275                 }
11276             }
11277             else
11278             {
11279                 skip_to_state_evaluation = false;
11280             }
11281 
11282             // we reached this line after we successfully parsed a value
11283             if (states.empty())
11284             {
11285                 // empty stack: we reached the end of the hierarchy: done
11286                 return true;
11287             }
11288 
11289             if (states.back())  // array
11290             {
11291                 // comma -> next value
11292                 if (get_token() == token_type::value_separator)
11293                 {
11294                     // parse a new value
11295                     get_token();
11296                     continue;
11297                 }
11298 
11299                 // closing ]
11300                 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11301                 {
11302                     if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11303                     {
11304                         return false;
11305                     }
11306 
11307                     // We are done with this array. Before we can parse a
11308                     // new value, we need to evaluate the new state first.
11309                     // By setting skip_to_state_evaluation to false, we
11310                     // are effectively jumping to the beginning of this if.
11311                     JSON_ASSERT(!states.empty());
11312                     states.pop_back();
11313                     skip_to_state_evaluation = true;
11314                     continue;
11315                 }
11316 
11317                 return sax->parse_error(m_lexer.get_position(),
11318                                         m_lexer.get_token_string(),
11319                                         parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11320             }
11321 
11322             // states.back() is false -> object
11323 
11324             // comma -> next value
11325             if (get_token() == token_type::value_separator)
11326             {
11327                 // parse key
11328                 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11329                 {
11330                     return sax->parse_error(m_lexer.get_position(),
11331                                             m_lexer.get_token_string(),
11332                                             parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11333                 }
11334 
11335                 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11336                 {
11337                     return false;
11338                 }
11339 
11340                 // parse separator (:)
11341                 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11342                 {
11343                     return sax->parse_error(m_lexer.get_position(),
11344                                             m_lexer.get_token_string(),
11345                                             parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11346                 }
11347 
11348                 // parse values
11349                 get_token();
11350                 continue;
11351             }
11352 
11353             // closing }
11354             if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11355             {
11356                 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11357                 {
11358                     return false;
11359                 }
11360 
11361                 // We are done with this object. Before we can parse a
11362                 // new value, we need to evaluate the new state first.
11363                 // By setting skip_to_state_evaluation to false, we
11364                 // are effectively jumping to the beginning of this if.
11365                 JSON_ASSERT(!states.empty());
11366                 states.pop_back();
11367                 skip_to_state_evaluation = true;
11368                 continue;
11369             }
11370 
11371             return sax->parse_error(m_lexer.get_position(),
11372                                     m_lexer.get_token_string(),
11373                                     parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11374         }
11375     }
11376 
11377     /// get next token from lexer
get_token()11378     token_type get_token()
11379     {
11380         return last_token = m_lexer.scan();
11381     }
11382 
exception_message(const token_type expected,const std::string & context)11383     std::string exception_message(const token_type expected, const std::string& context)
11384     {
11385         std::string error_msg = "syntax error ";
11386 
11387         if (!context.empty())
11388         {
11389             error_msg += "while parsing " + context + " ";
11390         }
11391 
11392         error_msg += "- ";
11393 
11394         if (last_token == token_type::parse_error)
11395         {
11396             error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
11397                          m_lexer.get_token_string() + "'";
11398         }
11399         else
11400         {
11401             error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
11402         }
11403 
11404         if (expected != token_type::uninitialized)
11405         {
11406             error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
11407         }
11408 
11409         return error_msg;
11410     }
11411 
11412   private:
11413     /// callback function
11414     const parser_callback_t<BasicJsonType> callback = nullptr;
11415     /// the type of the last read token
11416     token_type last_token = token_type::uninitialized;
11417     /// the lexer
11418     lexer_t m_lexer;
11419     /// whether to throw exceptions in case of errors
11420     const bool allow_exceptions = true;
11421 };
11422 
11423 }  // namespace detail
11424 }  // namespace nlohmann
11425 
11426 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
11427 
11428 
11429 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11430 
11431 
11432 #include <cstddef> // ptrdiff_t
11433 #include <limits>  // numeric_limits
11434 
11435 // #include <nlohmann/detail/macro_scope.hpp>
11436 
11437 
11438 namespace nlohmann
11439 {
11440 namespace detail
11441 {
11442 /*
11443 @brief an iterator for primitive JSON types
11444 
11445 This class models an iterator for primitive JSON types (boolean, number,
11446 string). It's only purpose is to allow the iterator/const_iterator classes
11447 to "iterate" over primitive values. Internally, the iterator is modeled by
11448 a `difference_type` variable. Value begin_value (`0`) models the begin,
11449 end_value (`1`) models past the end.
11450 */
11451 class primitive_iterator_t
11452 {
11453   private:
11454     using difference_type = std::ptrdiff_t;
11455     static constexpr difference_type begin_value = 0;
11456     static constexpr difference_type end_value = begin_value + 1;
11457 
11458   JSON_PRIVATE_UNLESS_TESTED:
11459     /// iterator as signed integer type
11460     difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11461 
11462   public:
get_value() const11463     constexpr difference_type get_value() const noexcept
11464     {
11465         return m_it;
11466     }
11467 
11468     /// set iterator to a defined beginning
set_begin()11469     void set_begin() noexcept
11470     {
11471         m_it = begin_value;
11472     }
11473 
11474     /// set iterator to a defined past the end
set_end()11475     void set_end() noexcept
11476     {
11477         m_it = end_value;
11478     }
11479 
11480     /// return whether the iterator can be dereferenced
is_begin() const11481     constexpr bool is_begin() const noexcept
11482     {
11483         return m_it == begin_value;
11484     }
11485 
11486     /// return whether the iterator is at end
is_end() const11487     constexpr bool is_end() const noexcept
11488     {
11489         return m_it == end_value;
11490     }
11491 
operator ==(primitive_iterator_t lhs,primitive_iterator_t rhs)11492     friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11493     {
11494         return lhs.m_it == rhs.m_it;
11495     }
11496 
operator <(primitive_iterator_t lhs,primitive_iterator_t rhs)11497     friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11498     {
11499         return lhs.m_it < rhs.m_it;
11500     }
11501 
operator +(difference_type n)11502     primitive_iterator_t operator+(difference_type n) noexcept
11503     {
11504         auto result = *this;
11505         result += n;
11506         return result;
11507     }
11508 
operator -(primitive_iterator_t lhs,primitive_iterator_t rhs)11509     friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11510     {
11511         return lhs.m_it - rhs.m_it;
11512     }
11513 
operator ++()11514     primitive_iterator_t& operator++() noexcept
11515     {
11516         ++m_it;
11517         return *this;
11518     }
11519 
operator ++(int)11520     primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
11521     {
11522         auto result = *this;
11523         ++m_it;
11524         return result;
11525     }
11526 
operator --()11527     primitive_iterator_t& operator--() noexcept
11528     {
11529         --m_it;
11530         return *this;
11531     }
11532 
operator --(int)11533     primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
11534     {
11535         auto result = *this;
11536         --m_it;
11537         return result;
11538     }
11539 
operator +=(difference_type n)11540     primitive_iterator_t& operator+=(difference_type n) noexcept
11541     {
11542         m_it += n;
11543         return *this;
11544     }
11545 
operator -=(difference_type n)11546     primitive_iterator_t& operator-=(difference_type n) noexcept
11547     {
11548         m_it -= n;
11549         return *this;
11550     }
11551 };
11552 }  // namespace detail
11553 }  // namespace nlohmann
11554 
11555 
11556 namespace nlohmann
11557 {
11558 namespace detail
11559 {
11560 /*!
11561 @brief an iterator value
11562 
11563 @note This structure could easily be a union, but MSVC currently does not allow
11564 unions members with complex constructors, see https://github.com/nlohmann/json/pull/105.
11565 */
11566 template<typename BasicJsonType> struct internal_iterator
11567 {
11568     /// iterator for JSON objects
11569     typename BasicJsonType::object_t::iterator object_iterator {};
11570     /// iterator for JSON arrays
11571     typename BasicJsonType::array_t::iterator array_iterator {};
11572     /// generic iterator for all other types
11573     primitive_iterator_t primitive_iterator {};
11574 };
11575 }  // namespace detail
11576 }  // namespace nlohmann
11577 
11578 // #include <nlohmann/detail/iterators/iter_impl.hpp>
11579 
11580 
11581 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
11582 #include <type_traits> // conditional, is_const, remove_const
11583 
11584 // #include <nlohmann/detail/exceptions.hpp>
11585 
11586 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
11587 
11588 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11589 
11590 // #include <nlohmann/detail/macro_scope.hpp>
11591 
11592 // #include <nlohmann/detail/meta/cpp_future.hpp>
11593 
11594 // #include <nlohmann/detail/meta/type_traits.hpp>
11595 
11596 // #include <nlohmann/detail/value_t.hpp>
11597 
11598 
11599 namespace nlohmann
11600 {
11601 namespace detail
11602 {
11603 // forward declare, to be able to friend it later on
11604 template<typename IteratorType> class iteration_proxy;
11605 template<typename IteratorType> class iteration_proxy_value;
11606 
11607 /*!
11608 @brief a template for a bidirectional iterator for the @ref basic_json class
11609 This class implements a both iterators (iterator and const_iterator) for the
11610 @ref basic_json class.
11611 @note An iterator is called *initialized* when a pointer to a JSON value has
11612       been set (e.g., by a constructor or a copy assignment). If the iterator is
11613       default-constructed, it is *uninitialized* and most methods are undefined.
11614       **The library uses assertions to detect calls on uninitialized iterators.**
11615 @requirement The class satisfies the following concept requirements:
11616 -
11617 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
11618   The iterator that can be moved can be moved in both directions (i.e.
11619   incremented and decremented).
11620 @since version 1.0.0, simplified in version 2.0.9, change to bidirectional
11621        iterators in version 3.0.0 (see https://github.com/nlohmann/json/issues/593)
11622 */
11623 template<typename BasicJsonType>
11624 class iter_impl
11625 {
11626     /// the iterator with BasicJsonType of different const-ness
11627     using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
11628     /// allow basic_json to access private members
11629     friend other_iter_impl;
11630     friend BasicJsonType;
11631     friend iteration_proxy<iter_impl>;
11632     friend iteration_proxy_value<iter_impl>;
11633 
11634     using object_t = typename BasicJsonType::object_t;
11635     using array_t = typename BasicJsonType::array_t;
11636     // make sure BasicJsonType is basic_json or const basic_json
11637     static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
11638                   "iter_impl only accepts (const) basic_json");
11639 
11640   public:
11641 
11642     /// The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
11643     /// The C++ Standard has never required user-defined iterators to derive from std::iterator.
11644     /// A user-defined iterator should provide publicly accessible typedefs named
11645     /// iterator_category, value_type, difference_type, pointer, and reference.
11646     /// Note that value_type is required to be non-const, even for constant iterators.
11647     using iterator_category = std::bidirectional_iterator_tag;
11648 
11649     /// the type of the values when the iterator is dereferenced
11650     using value_type = typename BasicJsonType::value_type;
11651     /// a type to represent differences between iterators
11652     using difference_type = typename BasicJsonType::difference_type;
11653     /// defines a pointer to the type iterated over (value_type)
11654     using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
11655           typename BasicJsonType::const_pointer,
11656           typename BasicJsonType::pointer>::type;
11657     /// defines a reference to the type iterated over (value_type)
11658     using reference =
11659         typename std::conditional<std::is_const<BasicJsonType>::value,
11660         typename BasicJsonType::const_reference,
11661         typename BasicJsonType::reference>::type;
11662 
11663     iter_impl() = default;
11664     ~iter_impl() = default;
11665     iter_impl(iter_impl&&) noexcept = default;
11666     iter_impl& operator=(iter_impl&&) noexcept = default;
11667 
11668     /*!
11669     @brief constructor for a given JSON instance
11670     @param[in] object  pointer to a JSON object for this iterator
11671     @pre object != nullptr
11672     @post The iterator is initialized; i.e. `m_object != nullptr`.
11673     */
iter_impl(pointer object)11674     explicit iter_impl(pointer object) noexcept : m_object(object)
11675     {
11676         JSON_ASSERT(m_object != nullptr);
11677 
11678         switch (m_object->m_type)
11679         {
11680             case value_t::object:
11681             {
11682                 m_it.object_iterator = typename object_t::iterator();
11683                 break;
11684             }
11685 
11686             case value_t::array:
11687             {
11688                 m_it.array_iterator = typename array_t::iterator();
11689                 break;
11690             }
11691 
11692             case value_t::null:
11693             case value_t::string:
11694             case value_t::boolean:
11695             case value_t::number_integer:
11696             case value_t::number_unsigned:
11697             case value_t::number_float:
11698             case value_t::binary:
11699             case value_t::discarded:
11700             default:
11701             {
11702                 m_it.primitive_iterator = primitive_iterator_t();
11703                 break;
11704             }
11705         }
11706     }
11707 
11708     /*!
11709     @note The conventional copy constructor and copy assignment are implicitly
11710           defined. Combined with the following converting constructor and
11711           assignment, they support: (1) copy from iterator to iterator, (2)
11712           copy from const iterator to const iterator, and (3) conversion from
11713           iterator to const iterator. However conversion from const iterator
11714           to iterator is not defined.
11715     */
11716 
11717     /*!
11718     @brief const copy constructor
11719     @param[in] other const iterator to copy from
11720     @note This copy constructor had to be defined explicitly to circumvent a bug
11721           occurring on msvc v19.0 compiler (VS 2015) debug build. For more
11722           information refer to: https://github.com/nlohmann/json/issues/1608
11723     */
iter_impl(const iter_impl<const BasicJsonType> & other)11724     iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
11725         : m_object(other.m_object), m_it(other.m_it)
11726     {}
11727 
11728     /*!
11729     @brief converting assignment
11730     @param[in] other const iterator to copy from
11731     @return const/non-const iterator
11732     @note It is not checked whether @a other is initialized.
11733     */
operator =(const iter_impl<const BasicJsonType> & other)11734     iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
11735     {
11736         if (&other != this)
11737         {
11738             m_object = other.m_object;
11739             m_it = other.m_it;
11740         }
11741         return *this;
11742     }
11743 
11744     /*!
11745     @brief converting constructor
11746     @param[in] other  non-const iterator to copy from
11747     @note It is not checked whether @a other is initialized.
11748     */
iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)11749     iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
11750         : m_object(other.m_object), m_it(other.m_it)
11751     {}
11752 
11753     /*!
11754     @brief converting assignment
11755     @param[in] other  non-const iterator to copy from
11756     @return const/non-const iterator
11757     @note It is not checked whether @a other is initialized.
11758     */
operator =(const iter_impl<typename std::remove_const<BasicJsonType>::type> & other)11759     iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
11760     {
11761         m_object = other.m_object;
11762         m_it = other.m_it;
11763         return *this;
11764     }
11765 
11766   JSON_PRIVATE_UNLESS_TESTED:
11767     /*!
11768     @brief set the iterator to the first value
11769     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11770     */
11771     void set_begin() noexcept
11772     {
11773         JSON_ASSERT(m_object != nullptr);
11774 
11775         switch (m_object->m_type)
11776         {
11777             case value_t::object:
11778             {
11779                 m_it.object_iterator = m_object->m_value.object->begin();
11780                 break;
11781             }
11782 
11783             case value_t::array:
11784             {
11785                 m_it.array_iterator = m_object->m_value.array->begin();
11786                 break;
11787             }
11788 
11789             case value_t::null:
11790             {
11791                 // set to end so begin()==end() is true: null is empty
11792                 m_it.primitive_iterator.set_end();
11793                 break;
11794             }
11795 
11796             case value_t::string:
11797             case value_t::boolean:
11798             case value_t::number_integer:
11799             case value_t::number_unsigned:
11800             case value_t::number_float:
11801             case value_t::binary:
11802             case value_t::discarded:
11803             default:
11804             {
11805                 m_it.primitive_iterator.set_begin();
11806                 break;
11807             }
11808         }
11809     }
11810 
11811     /*!
11812     @brief set the iterator past the last value
11813     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11814     */
set_end()11815     void set_end() noexcept
11816     {
11817         JSON_ASSERT(m_object != nullptr);
11818 
11819         switch (m_object->m_type)
11820         {
11821             case value_t::object:
11822             {
11823                 m_it.object_iterator = m_object->m_value.object->end();
11824                 break;
11825             }
11826 
11827             case value_t::array:
11828             {
11829                 m_it.array_iterator = m_object->m_value.array->end();
11830                 break;
11831             }
11832 
11833             case value_t::null:
11834             case value_t::string:
11835             case value_t::boolean:
11836             case value_t::number_integer:
11837             case value_t::number_unsigned:
11838             case value_t::number_float:
11839             case value_t::binary:
11840             case value_t::discarded:
11841             default:
11842             {
11843                 m_it.primitive_iterator.set_end();
11844                 break;
11845             }
11846         }
11847     }
11848 
11849   public:
11850     /*!
11851     @brief return a reference to the value pointed to by the iterator
11852     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11853     */
operator *() const11854     reference operator*() const
11855     {
11856         JSON_ASSERT(m_object != nullptr);
11857 
11858         switch (m_object->m_type)
11859         {
11860             case value_t::object:
11861             {
11862                 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11863                 return m_it.object_iterator->second;
11864             }
11865 
11866             case value_t::array:
11867             {
11868                 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11869                 return *m_it.array_iterator;
11870             }
11871 
11872             case value_t::null:
11873                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11874 
11875             case value_t::string:
11876             case value_t::boolean:
11877             case value_t::number_integer:
11878             case value_t::number_unsigned:
11879             case value_t::number_float:
11880             case value_t::binary:
11881             case value_t::discarded:
11882             default:
11883             {
11884                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11885                 {
11886                     return *m_object;
11887                 }
11888 
11889                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11890             }
11891         }
11892     }
11893 
11894     /*!
11895     @brief dereference the iterator
11896     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11897     */
operator ->() const11898     pointer operator->() const
11899     {
11900         JSON_ASSERT(m_object != nullptr);
11901 
11902         switch (m_object->m_type)
11903         {
11904             case value_t::object:
11905             {
11906                 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11907                 return &(m_it.object_iterator->second);
11908             }
11909 
11910             case value_t::array:
11911             {
11912                 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11913                 return &*m_it.array_iterator;
11914             }
11915 
11916             case value_t::null:
11917             case value_t::string:
11918             case value_t::boolean:
11919             case value_t::number_integer:
11920             case value_t::number_unsigned:
11921             case value_t::number_float:
11922             case value_t::binary:
11923             case value_t::discarded:
11924             default:
11925             {
11926                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11927                 {
11928                     return m_object;
11929                 }
11930 
11931                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11932             }
11933         }
11934     }
11935 
11936     /*!
11937     @brief post-increment (it++)
11938     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11939     */
operator ++(int)11940     iter_impl const operator++(int) // NOLINT(readability-const-return-type)
11941     {
11942         auto result = *this;
11943         ++(*this);
11944         return result;
11945     }
11946 
11947     /*!
11948     @brief pre-increment (++it)
11949     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11950     */
operator ++()11951     iter_impl& operator++()
11952     {
11953         JSON_ASSERT(m_object != nullptr);
11954 
11955         switch (m_object->m_type)
11956         {
11957             case value_t::object:
11958             {
11959                 std::advance(m_it.object_iterator, 1);
11960                 break;
11961             }
11962 
11963             case value_t::array:
11964             {
11965                 std::advance(m_it.array_iterator, 1);
11966                 break;
11967             }
11968 
11969             case value_t::null:
11970             case value_t::string:
11971             case value_t::boolean:
11972             case value_t::number_integer:
11973             case value_t::number_unsigned:
11974             case value_t::number_float:
11975             case value_t::binary:
11976             case value_t::discarded:
11977             default:
11978             {
11979                 ++m_it.primitive_iterator;
11980                 break;
11981             }
11982         }
11983 
11984         return *this;
11985     }
11986 
11987     /*!
11988     @brief post-decrement (it--)
11989     @pre The iterator is initialized; i.e. `m_object != nullptr`.
11990     */
operator --(int)11991     iter_impl const operator--(int) // NOLINT(readability-const-return-type)
11992     {
11993         auto result = *this;
11994         --(*this);
11995         return result;
11996     }
11997 
11998     /*!
11999     @brief pre-decrement (--it)
12000     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12001     */
operator --()12002     iter_impl& operator--()
12003     {
12004         JSON_ASSERT(m_object != nullptr);
12005 
12006         switch (m_object->m_type)
12007         {
12008             case value_t::object:
12009             {
12010                 std::advance(m_it.object_iterator, -1);
12011                 break;
12012             }
12013 
12014             case value_t::array:
12015             {
12016                 std::advance(m_it.array_iterator, -1);
12017                 break;
12018             }
12019 
12020             case value_t::null:
12021             case value_t::string:
12022             case value_t::boolean:
12023             case value_t::number_integer:
12024             case value_t::number_unsigned:
12025             case value_t::number_float:
12026             case value_t::binary:
12027             case value_t::discarded:
12028             default:
12029             {
12030                 --m_it.primitive_iterator;
12031                 break;
12032             }
12033         }
12034 
12035         return *this;
12036     }
12037 
12038     /*!
12039     @brief comparison: equal
12040     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12041     */
12042     template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
operator ==(const IterImpl & other) const12043     bool operator==(const IterImpl& other) const
12044     {
12045         // if objects are not the same, the comparison is undefined
12046         if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12047         {
12048             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12049         }
12050 
12051         JSON_ASSERT(m_object != nullptr);
12052 
12053         switch (m_object->m_type)
12054         {
12055             case value_t::object:
12056                 return (m_it.object_iterator == other.m_it.object_iterator);
12057 
12058             case value_t::array:
12059                 return (m_it.array_iterator == other.m_it.array_iterator);
12060 
12061             case value_t::null:
12062             case value_t::string:
12063             case value_t::boolean:
12064             case value_t::number_integer:
12065             case value_t::number_unsigned:
12066             case value_t::number_float:
12067             case value_t::binary:
12068             case value_t::discarded:
12069             default:
12070                 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
12071         }
12072     }
12073 
12074     /*!
12075     @brief comparison: not equal
12076     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12077     */
12078     template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
operator !=(const IterImpl & other) const12079     bool operator!=(const IterImpl& other) const
12080     {
12081         return !operator==(other);
12082     }
12083 
12084     /*!
12085     @brief comparison: smaller
12086     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12087     */
operator <(const iter_impl & other) const12088     bool operator<(const iter_impl& other) const
12089     {
12090         // if objects are not the same, the comparison is undefined
12091         if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12092         {
12093             JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12094         }
12095 
12096         JSON_ASSERT(m_object != nullptr);
12097 
12098         switch (m_object->m_type)
12099         {
12100             case value_t::object:
12101                 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
12102 
12103             case value_t::array:
12104                 return (m_it.array_iterator < other.m_it.array_iterator);
12105 
12106             case value_t::null:
12107             case value_t::string:
12108             case value_t::boolean:
12109             case value_t::number_integer:
12110             case value_t::number_unsigned:
12111             case value_t::number_float:
12112             case value_t::binary:
12113             case value_t::discarded:
12114             default:
12115                 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
12116         }
12117     }
12118 
12119     /*!
12120     @brief comparison: less than or equal
12121     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12122     */
operator <=(const iter_impl & other) const12123     bool operator<=(const iter_impl& other) const
12124     {
12125         return !other.operator < (*this);
12126     }
12127 
12128     /*!
12129     @brief comparison: greater than
12130     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12131     */
operator >(const iter_impl & other) const12132     bool operator>(const iter_impl& other) const
12133     {
12134         return !operator<=(other);
12135     }
12136 
12137     /*!
12138     @brief comparison: greater than or equal
12139     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12140     */
operator >=(const iter_impl & other) const12141     bool operator>=(const iter_impl& other) const
12142     {
12143         return !operator<(other);
12144     }
12145 
12146     /*!
12147     @brief add to iterator
12148     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12149     */
operator +=(difference_type i)12150     iter_impl& operator+=(difference_type i)
12151     {
12152         JSON_ASSERT(m_object != nullptr);
12153 
12154         switch (m_object->m_type)
12155         {
12156             case value_t::object:
12157                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12158 
12159             case value_t::array:
12160             {
12161                 std::advance(m_it.array_iterator, i);
12162                 break;
12163             }
12164 
12165             case value_t::null:
12166             case value_t::string:
12167             case value_t::boolean:
12168             case value_t::number_integer:
12169             case value_t::number_unsigned:
12170             case value_t::number_float:
12171             case value_t::binary:
12172             case value_t::discarded:
12173             default:
12174             {
12175                 m_it.primitive_iterator += i;
12176                 break;
12177             }
12178         }
12179 
12180         return *this;
12181     }
12182 
12183     /*!
12184     @brief subtract from iterator
12185     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12186     */
operator -=(difference_type i)12187     iter_impl& operator-=(difference_type i)
12188     {
12189         return operator+=(-i);
12190     }
12191 
12192     /*!
12193     @brief add to iterator
12194     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12195     */
operator +(difference_type i) const12196     iter_impl operator+(difference_type i) const
12197     {
12198         auto result = *this;
12199         result += i;
12200         return result;
12201     }
12202 
12203     /*!
12204     @brief addition of distance and iterator
12205     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12206     */
operator +(difference_type i,const iter_impl & it)12207     friend iter_impl operator+(difference_type i, const iter_impl& it)
12208     {
12209         auto result = it;
12210         result += i;
12211         return result;
12212     }
12213 
12214     /*!
12215     @brief subtract from iterator
12216     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12217     */
operator -(difference_type i) const12218     iter_impl operator-(difference_type i) const
12219     {
12220         auto result = *this;
12221         result -= i;
12222         return result;
12223     }
12224 
12225     /*!
12226     @brief return difference
12227     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12228     */
operator -(const iter_impl & other) const12229     difference_type operator-(const iter_impl& other) const
12230     {
12231         JSON_ASSERT(m_object != nullptr);
12232 
12233         switch (m_object->m_type)
12234         {
12235             case value_t::object:
12236                 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12237 
12238             case value_t::array:
12239                 return m_it.array_iterator - other.m_it.array_iterator;
12240 
12241             case value_t::null:
12242             case value_t::string:
12243             case value_t::boolean:
12244             case value_t::number_integer:
12245             case value_t::number_unsigned:
12246             case value_t::number_float:
12247             case value_t::binary:
12248             case value_t::discarded:
12249             default:
12250                 return m_it.primitive_iterator - other.m_it.primitive_iterator;
12251         }
12252     }
12253 
12254     /*!
12255     @brief access to successor
12256     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12257     */
operator [](difference_type n) const12258     reference operator[](difference_type n) const
12259     {
12260         JSON_ASSERT(m_object != nullptr);
12261 
12262         switch (m_object->m_type)
12263         {
12264             case value_t::object:
12265                 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
12266 
12267             case value_t::array:
12268                 return *std::next(m_it.array_iterator, n);
12269 
12270             case value_t::null:
12271                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12272 
12273             case value_t::string:
12274             case value_t::boolean:
12275             case value_t::number_integer:
12276             case value_t::number_unsigned:
12277             case value_t::number_float:
12278             case value_t::binary:
12279             case value_t::discarded:
12280             default:
12281             {
12282                 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
12283                 {
12284                     return *m_object;
12285                 }
12286 
12287                 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12288             }
12289         }
12290     }
12291 
12292     /*!
12293     @brief return the key of an object iterator
12294     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12295     */
key() const12296     const typename object_t::key_type& key() const
12297     {
12298         JSON_ASSERT(m_object != nullptr);
12299 
12300         if (JSON_HEDLEY_LIKELY(m_object->is_object()))
12301         {
12302             return m_it.object_iterator->first;
12303         }
12304 
12305         JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
12306     }
12307 
12308     /*!
12309     @brief return the value of an iterator
12310     @pre The iterator is initialized; i.e. `m_object != nullptr`.
12311     */
value() const12312     reference value() const
12313     {
12314         return operator*();
12315     }
12316 
12317   JSON_PRIVATE_UNLESS_TESTED:
12318     /// associated JSON instance
12319     pointer m_object = nullptr;
12320     /// the actual iterator of the associated instance
12321     internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
12322 };
12323 } // namespace detail
12324 } // namespace nlohmann
12325 
12326 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12327 
12328 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12329 
12330 
12331 #include <cstddef> // ptrdiff_t
12332 #include <iterator> // reverse_iterator
12333 #include <utility> // declval
12334 
12335 namespace nlohmann
12336 {
12337 namespace detail
12338 {
12339 //////////////////////
12340 // reverse_iterator //
12341 //////////////////////
12342 
12343 /*!
12344 @brief a template for a reverse iterator class
12345 
12346 @tparam Base the base iterator type to reverse. Valid types are @ref
12347 iterator (to create @ref reverse_iterator) and @ref const_iterator (to
12348 create @ref const_reverse_iterator).
12349 
12350 @requirement The class satisfies the following concept requirements:
12351 -
12352 [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator):
12353   The iterator that can be moved can be moved in both directions (i.e.
12354   incremented and decremented).
12355 - [OutputIterator](https://en.cppreference.com/w/cpp/named_req/OutputIterator):
12356   It is possible to write to the pointed-to element (only if @a Base is
12357   @ref iterator).
12358 
12359 @since version 1.0.0
12360 */
12361 template<typename Base>
12362 class json_reverse_iterator : public std::reverse_iterator<Base>
12363 {
12364   public:
12365     using difference_type = std::ptrdiff_t;
12366     /// shortcut to the reverse iterator adapter
12367     using base_iterator = std::reverse_iterator<Base>;
12368     /// the reference type for the pointed-to element
12369     using reference = typename Base::reference;
12370 
12371     /// create reverse iterator from iterator
json_reverse_iterator(const typename base_iterator::iterator_type & it)12372     explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
12373         : base_iterator(it) {}
12374 
12375     /// create reverse iterator from base class
json_reverse_iterator(const base_iterator & it)12376     explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12377 
12378     /// post-increment (it++)
operator ++(int)12379     json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
12380     {
12381         return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12382     }
12383 
12384     /// pre-increment (++it)
operator ++()12385     json_reverse_iterator& operator++()
12386     {
12387         return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12388     }
12389 
12390     /// post-decrement (it--)
operator --(int)12391     json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
12392     {
12393         return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12394     }
12395 
12396     /// pre-decrement (--it)
operator --()12397     json_reverse_iterator& operator--()
12398     {
12399         return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12400     }
12401 
12402     /// add to iterator
operator +=(difference_type i)12403     json_reverse_iterator& operator+=(difference_type i)
12404     {
12405         return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12406     }
12407 
12408     /// add to iterator
operator +(difference_type i) const12409     json_reverse_iterator operator+(difference_type i) const
12410     {
12411         return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12412     }
12413 
12414     /// subtract from iterator
operator -(difference_type i) const12415     json_reverse_iterator operator-(difference_type i) const
12416     {
12417         return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12418     }
12419 
12420     /// return difference
operator -(const json_reverse_iterator & other) const12421     difference_type operator-(const json_reverse_iterator& other) const
12422     {
12423         return base_iterator(*this) - base_iterator(other);
12424     }
12425 
12426     /// access to successor
operator [](difference_type n) const12427     reference operator[](difference_type n) const
12428     {
12429         return *(this->operator+(n));
12430     }
12431 
12432     /// return the key of an object iterator
key() const12433     auto key() const -> decltype(std::declval<Base>().key())
12434     {
12435         auto it = --this->base();
12436         return it.key();
12437     }
12438 
12439     /// return the value of an iterator
value() const12440     reference value() const
12441     {
12442         auto it = --this->base();
12443         return it.operator * ();
12444     }
12445 };
12446 }  // namespace detail
12447 }  // namespace nlohmann
12448 
12449 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12450 
12451 // #include <nlohmann/detail/json_pointer.hpp>
12452 
12453 
12454 #include <algorithm> // all_of
12455 #include <cctype> // isdigit
12456 #include <limits> // max
12457 #include <numeric> // accumulate
12458 #include <string> // string
12459 #include <utility> // move
12460 #include <vector> // vector
12461 
12462 // #include <nlohmann/detail/exceptions.hpp>
12463 
12464 // #include <nlohmann/detail/macro_scope.hpp>
12465 
12466 // #include <nlohmann/detail/string_escape.hpp>
12467 
12468 // #include <nlohmann/detail/value_t.hpp>
12469 
12470 
12471 namespace nlohmann
12472 {
12473 template<typename BasicJsonType>
12474 class json_pointer
12475 {
12476     // allow basic_json to access private members
12477     NLOHMANN_BASIC_JSON_TPL_DECLARATION
12478     friend class basic_json;
12479 
12480   public:
12481     /*!
12482     @brief create JSON pointer
12483 
12484     Create a JSON pointer according to the syntax described in
12485     [Section 3 of RFC6901](https://tools.ietf.org/html/rfc6901#section-3).
12486 
12487     @param[in] s  string representing the JSON pointer; if omitted, the empty
12488                   string is assumed which references the whole JSON value
12489 
12490     @throw parse_error.107 if the given JSON pointer @a s is nonempty and does
12491                            not begin with a slash (`/`); see example below
12492 
12493     @throw parse_error.108 if a tilde (`~`) in the given JSON pointer @a s is
12494     not followed by `0` (representing `~`) or `1` (representing `/`); see
12495     example below
12496 
12497     @liveexample{The example shows the construction several valid JSON pointers
12498     as well as the exceptional behavior.,json_pointer}
12499 
12500     @since version 2.0.0
12501     */
json_pointer(const std::string & s="")12502     explicit json_pointer(const std::string& s = "")
12503         : reference_tokens(split(s))
12504     {}
12505 
12506     /*!
12507     @brief return a string representation of the JSON pointer
12508 
12509     @invariant For each JSON pointer `ptr`, it holds:
12510     @code {.cpp}
12511     ptr == json_pointer(ptr.to_string());
12512     @endcode
12513 
12514     @return a string representation of the JSON pointer
12515 
12516     @liveexample{The example shows the result of `to_string`.,json_pointer__to_string}
12517 
12518     @since version 2.0.0
12519     */
to_string() const12520     std::string to_string() const
12521     {
12522         return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12523                                std::string{},
12524                                [](const std::string & a, const std::string & b)
12525         {
12526             return a + "/" + detail::escape(b);
12527         });
12528     }
12529 
12530     /// @copydoc to_string()
operator std::string() const12531     operator std::string() const
12532     {
12533         return to_string();
12534     }
12535 
12536     /*!
12537     @brief append another JSON pointer at the end of this JSON pointer
12538 
12539     @param[in] ptr  JSON pointer to append
12540     @return JSON pointer with @a ptr appended
12541 
12542     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12543 
12544     @complexity Linear in the length of @a ptr.
12545 
12546     @sa see @ref operator/=(std::string) to append a reference token
12547     @sa see @ref operator/=(std::size_t) to append an array index
12548     @sa see @ref operator/(const json_pointer&, const json_pointer&) for a binary operator
12549 
12550     @since version 3.6.0
12551     */
operator /=(const json_pointer & ptr)12552     json_pointer& operator/=(const json_pointer& ptr)
12553     {
12554         reference_tokens.insert(reference_tokens.end(),
12555                                 ptr.reference_tokens.begin(),
12556                                 ptr.reference_tokens.end());
12557         return *this;
12558     }
12559 
12560     /*!
12561     @brief append an unescaped reference token at the end of this JSON pointer
12562 
12563     @param[in] token  reference token to append
12564     @return JSON pointer with @a token appended without escaping @a token
12565 
12566     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12567 
12568     @complexity Amortized constant.
12569 
12570     @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12571     @sa see @ref operator/=(std::size_t) to append an array index
12572     @sa see @ref operator/(const json_pointer&, std::size_t) for a binary operator
12573 
12574     @since version 3.6.0
12575     */
operator /=(std::string token)12576     json_pointer& operator/=(std::string token)
12577     {
12578         push_back(std::move(token));
12579         return *this;
12580     }
12581 
12582     /*!
12583     @brief append an array index at the end of this JSON pointer
12584 
12585     @param[in] array_idx  array index to append
12586     @return JSON pointer with @a array_idx appended
12587 
12588     @liveexample{The example shows the usage of `operator/=`.,json_pointer__operator_add}
12589 
12590     @complexity Amortized constant.
12591 
12592     @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12593     @sa see @ref operator/=(std::string) to append a reference token
12594     @sa see @ref operator/(const json_pointer&, std::string) for a binary operator
12595 
12596     @since version 3.6.0
12597     */
operator /=(std::size_t array_idx)12598     json_pointer& operator/=(std::size_t array_idx)
12599     {
12600         return *this /= std::to_string(array_idx);
12601     }
12602 
12603     /*!
12604     @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
12605 
12606     @param[in] lhs  JSON pointer
12607     @param[in] rhs  JSON pointer
12608     @return a new JSON pointer with @a rhs appended to @a lhs
12609 
12610     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12611 
12612     @complexity Linear in the length of @a lhs and @a rhs.
12613 
12614     @sa see @ref operator/=(const json_pointer&) to append a JSON pointer
12615 
12616     @since version 3.6.0
12617     */
operator /(const json_pointer & lhs,const json_pointer & rhs)12618     friend json_pointer operator/(const json_pointer& lhs,
12619                                   const json_pointer& rhs)
12620     {
12621         return json_pointer(lhs) /= rhs;
12622     }
12623 
12624     /*!
12625     @brief create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
12626 
12627     @param[in] ptr  JSON pointer
12628     @param[in] token  reference token
12629     @return a new JSON pointer with unescaped @a token appended to @a ptr
12630 
12631     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12632 
12633     @complexity Linear in the length of @a ptr.
12634 
12635     @sa see @ref operator/=(std::string) to append a reference token
12636 
12637     @since version 3.6.0
12638     */
operator /(const json_pointer & ptr,std::string token)12639     friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param)
12640     {
12641         return json_pointer(ptr) /= std::move(token);
12642     }
12643 
12644     /*!
12645     @brief create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
12646 
12647     @param[in] ptr  JSON pointer
12648     @param[in] array_idx  array index
12649     @return a new JSON pointer with @a array_idx appended to @a ptr
12650 
12651     @liveexample{The example shows the usage of `operator/`.,json_pointer__operator_add_binary}
12652 
12653     @complexity Linear in the length of @a ptr.
12654 
12655     @sa see @ref operator/=(std::size_t) to append an array index
12656 
12657     @since version 3.6.0
12658     */
operator /(const json_pointer & ptr,std::size_t array_idx)12659     friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
12660     {
12661         return json_pointer(ptr) /= array_idx;
12662     }
12663 
12664     /*!
12665     @brief returns the parent of this JSON pointer
12666 
12667     @return parent of this JSON pointer; in case this JSON pointer is the root,
12668             the root itself is returned
12669 
12670     @complexity Linear in the length of the JSON pointer.
12671 
12672     @liveexample{The example shows the result of `parent_pointer` for different
12673     JSON Pointers.,json_pointer__parent_pointer}
12674 
12675     @since version 3.6.0
12676     */
parent_pointer() const12677     json_pointer parent_pointer() const
12678     {
12679         if (empty())
12680         {
12681             return *this;
12682         }
12683 
12684         json_pointer res = *this;
12685         res.pop_back();
12686         return res;
12687     }
12688 
12689     /*!
12690     @brief remove last reference token
12691 
12692     @pre not `empty()`
12693 
12694     @liveexample{The example shows the usage of `pop_back`.,json_pointer__pop_back}
12695 
12696     @complexity Constant.
12697 
12698     @throw out_of_range.405 if JSON pointer has no parent
12699 
12700     @since version 3.6.0
12701     */
pop_back()12702     void pop_back()
12703     {
12704         if (JSON_HEDLEY_UNLIKELY(empty()))
12705         {
12706             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12707         }
12708 
12709         reference_tokens.pop_back();
12710     }
12711 
12712     /*!
12713     @brief return last reference token
12714 
12715     @pre not `empty()`
12716     @return last reference token
12717 
12718     @liveexample{The example shows the usage of `back`.,json_pointer__back}
12719 
12720     @complexity Constant.
12721 
12722     @throw out_of_range.405 if JSON pointer has no parent
12723 
12724     @since version 3.6.0
12725     */
back() const12726     const std::string& back() const
12727     {
12728         if (JSON_HEDLEY_UNLIKELY(empty()))
12729         {
12730             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12731         }
12732 
12733         return reference_tokens.back();
12734     }
12735 
12736     /*!
12737     @brief append an unescaped token at the end of the reference pointer
12738 
12739     @param[in] token  token to add
12740 
12741     @complexity Amortized constant.
12742 
12743     @liveexample{The example shows the result of `push_back` for different
12744     JSON Pointers.,json_pointer__push_back}
12745 
12746     @since version 3.6.0
12747     */
push_back(const std::string & token)12748     void push_back(const std::string& token)
12749     {
12750         reference_tokens.push_back(token);
12751     }
12752 
12753     /// @copydoc push_back(const std::string&)
push_back(std::string && token)12754     void push_back(std::string&& token)
12755     {
12756         reference_tokens.push_back(std::move(token));
12757     }
12758 
12759     /*!
12760     @brief return whether pointer points to the root document
12761 
12762     @return true iff the JSON pointer points to the root document
12763 
12764     @complexity Constant.
12765 
12766     @exceptionsafety No-throw guarantee: this function never throws exceptions.
12767 
12768     @liveexample{The example shows the result of `empty` for different JSON
12769     Pointers.,json_pointer__empty}
12770 
12771     @since version 3.6.0
12772     */
empty() const12773     bool empty() const noexcept
12774     {
12775         return reference_tokens.empty();
12776     }
12777 
12778   private:
12779     /*!
12780     @param[in] s  reference token to be converted into an array index
12781 
12782     @return integer representation of @a s
12783 
12784     @throw parse_error.106  if an array index begins with '0'
12785     @throw parse_error.109  if an array index begins not with a digit
12786     @throw out_of_range.404 if string @a s could not be converted to an integer
12787     @throw out_of_range.410 if an array index exceeds size_type
12788     */
array_index(const std::string & s)12789     static typename BasicJsonType::size_type array_index(const std::string& s)
12790     {
12791         using size_type = typename BasicJsonType::size_type;
12792 
12793         // error condition (cf. RFC 6901, Sect. 4)
12794         if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
12795         {
12796             JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
12797         }
12798 
12799         // error condition (cf. RFC 6901, Sect. 4)
12800         if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
12801         {
12802             JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
12803         }
12804 
12805         std::size_t processed_chars = 0;
12806         unsigned long long res = 0;  // NOLINT(runtime/int)
12807         JSON_TRY
12808         {
12809             res = std::stoull(s, &processed_chars);
12810         }
12811         JSON_CATCH(std::out_of_range&)
12812         {
12813             JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12814         }
12815 
12816         // check if the string was completely read
12817         if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
12818         {
12819             JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12820         }
12821 
12822         // only triggered on special platforms (like 32bit), see also
12823         // https://github.com/nlohmann/json/pull/2203
12824         if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)()))  // NOLINT(runtime/int)
12825         {
12826             JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
12827         }
12828 
12829         return static_cast<size_type>(res);
12830     }
12831 
12832   JSON_PRIVATE_UNLESS_TESTED:
12833     json_pointer top() const
12834     {
12835         if (JSON_HEDLEY_UNLIKELY(empty()))
12836         {
12837             JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12838         }
12839 
12840         json_pointer result = *this;
12841         result.reference_tokens = {reference_tokens[0]};
12842         return result;
12843     }
12844 
12845   private:
12846     /*!
12847     @brief create and return a reference to the pointed to value
12848 
12849     @complexity Linear in the number of reference tokens.
12850 
12851     @throw parse_error.109 if array index is not a number
12852     @throw type_error.313 if value cannot be unflattened
12853     */
get_and_create(BasicJsonType & j) const12854     BasicJsonType& get_and_create(BasicJsonType& j) const
12855     {
12856         auto* result = &j;
12857 
12858         // in case no reference tokens exist, return a reference to the JSON value
12859         // j which will be overwritten by a primitive value
12860         for (const auto& reference_token : reference_tokens)
12861         {
12862             switch (result->type())
12863             {
12864                 case detail::value_t::null:
12865                 {
12866                     if (reference_token == "0")
12867                     {
12868                         // start a new array if reference token is 0
12869                         result = &result->operator[](0);
12870                     }
12871                     else
12872                     {
12873                         // start a new object otherwise
12874                         result = &result->operator[](reference_token);
12875                     }
12876                     break;
12877                 }
12878 
12879                 case detail::value_t::object:
12880                 {
12881                     // create an entry in the object
12882                     result = &result->operator[](reference_token);
12883                     break;
12884                 }
12885 
12886                 case detail::value_t::array:
12887                 {
12888                     // create an entry in the array
12889                     result = &result->operator[](array_index(reference_token));
12890                     break;
12891                 }
12892 
12893                 /*
12894                 The following code is only reached if there exists a reference
12895                 token _and_ the current value is primitive. In this case, we have
12896                 an error situation, because primitive values may only occur as
12897                 single value; that is, with an empty list of reference tokens.
12898                 */
12899                 case detail::value_t::string:
12900                 case detail::value_t::boolean:
12901                 case detail::value_t::number_integer:
12902                 case detail::value_t::number_unsigned:
12903                 case detail::value_t::number_float:
12904                 case detail::value_t::binary:
12905                 case detail::value_t::discarded:
12906                 default:
12907                     JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
12908             }
12909         }
12910 
12911         return *result;
12912     }
12913 
12914     /*!
12915     @brief return a reference to the pointed to value
12916 
12917     @note This version does not throw if a value is not present, but tries to
12918           create nested values instead. For instance, calling this function
12919           with pointer `"/this/that"` on a null value is equivalent to calling
12920           `operator[]("this").operator[]("that")` on that value, effectively
12921           changing the null value to an object.
12922 
12923     @param[in] ptr  a JSON value
12924 
12925     @return reference to the JSON value pointed to by the JSON pointer
12926 
12927     @complexity Linear in the length of the JSON pointer.
12928 
12929     @throw parse_error.106   if an array index begins with '0'
12930     @throw parse_error.109   if an array index was not a number
12931     @throw out_of_range.404  if the JSON pointer can not be resolved
12932     */
get_unchecked(BasicJsonType * ptr) const12933     BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12934     {
12935         for (const auto& reference_token : reference_tokens)
12936         {
12937             // convert null values to arrays or objects before continuing
12938             if (ptr->is_null())
12939             {
12940                 // check if reference token is a number
12941                 const bool nums =
12942                     std::all_of(reference_token.begin(), reference_token.end(),
12943                                 [](const unsigned char x)
12944                 {
12945                     return std::isdigit(x);
12946                 });
12947 
12948                 // change value to array for numbers or "-" or to object otherwise
12949                 *ptr = (nums || reference_token == "-")
12950                        ? detail::value_t::array
12951                        : detail::value_t::object;
12952             }
12953 
12954             switch (ptr->type())
12955             {
12956                 case detail::value_t::object:
12957                 {
12958                     // use unchecked object access
12959                     ptr = &ptr->operator[](reference_token);
12960                     break;
12961                 }
12962 
12963                 case detail::value_t::array:
12964                 {
12965                     if (reference_token == "-")
12966                     {
12967                         // explicitly treat "-" as index beyond the end
12968                         ptr = &ptr->operator[](ptr->m_value.array->size());
12969                     }
12970                     else
12971                     {
12972                         // convert array index to number; unchecked access
12973                         ptr = &ptr->operator[](array_index(reference_token));
12974                     }
12975                     break;
12976                 }
12977 
12978                 case detail::value_t::null:
12979                 case detail::value_t::string:
12980                 case detail::value_t::boolean:
12981                 case detail::value_t::number_integer:
12982                 case detail::value_t::number_unsigned:
12983                 case detail::value_t::number_float:
12984                 case detail::value_t::binary:
12985                 case detail::value_t::discarded:
12986                 default:
12987                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12988             }
12989         }
12990 
12991         return *ptr;
12992     }
12993 
12994     /*!
12995     @throw parse_error.106   if an array index begins with '0'
12996     @throw parse_error.109   if an array index was not a number
12997     @throw out_of_range.402  if the array index '-' is used
12998     @throw out_of_range.404  if the JSON pointer can not be resolved
12999     */
get_checked(BasicJsonType * ptr) const13000     BasicJsonType& get_checked(BasicJsonType* ptr) const
13001     {
13002         for (const auto& reference_token : reference_tokens)
13003         {
13004             switch (ptr->type())
13005             {
13006                 case detail::value_t::object:
13007                 {
13008                     // note: at performs range check
13009                     ptr = &ptr->at(reference_token);
13010                     break;
13011                 }
13012 
13013                 case detail::value_t::array:
13014                 {
13015                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13016                     {
13017                         // "-" always fails the range check
13018                         JSON_THROW(detail::out_of_range::create(402,
13019                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13020                                                                 ") is out of range", *ptr));
13021                     }
13022 
13023                     // note: at performs range check
13024                     ptr = &ptr->at(array_index(reference_token));
13025                     break;
13026                 }
13027 
13028                 case detail::value_t::null:
13029                 case detail::value_t::string:
13030                 case detail::value_t::boolean:
13031                 case detail::value_t::number_integer:
13032                 case detail::value_t::number_unsigned:
13033                 case detail::value_t::number_float:
13034                 case detail::value_t::binary:
13035                 case detail::value_t::discarded:
13036                 default:
13037                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13038             }
13039         }
13040 
13041         return *ptr;
13042     }
13043 
13044     /*!
13045     @brief return a const reference to the pointed to value
13046 
13047     @param[in] ptr  a JSON value
13048 
13049     @return const reference to the JSON value pointed to by the JSON
13050     pointer
13051 
13052     @throw parse_error.106   if an array index begins with '0'
13053     @throw parse_error.109   if an array index was not a number
13054     @throw out_of_range.402  if the array index '-' is used
13055     @throw out_of_range.404  if the JSON pointer can not be resolved
13056     */
get_unchecked(const BasicJsonType * ptr) const13057     const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
13058     {
13059         for (const auto& reference_token : reference_tokens)
13060         {
13061             switch (ptr->type())
13062             {
13063                 case detail::value_t::object:
13064                 {
13065                     // use unchecked object access
13066                     ptr = &ptr->operator[](reference_token);
13067                     break;
13068                 }
13069 
13070                 case detail::value_t::array:
13071                 {
13072                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13073                     {
13074                         // "-" cannot be used for const access
13075                         JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
13076                     }
13077 
13078                     // use unchecked array access
13079                     ptr = &ptr->operator[](array_index(reference_token));
13080                     break;
13081                 }
13082 
13083                 case detail::value_t::null:
13084                 case detail::value_t::string:
13085                 case detail::value_t::boolean:
13086                 case detail::value_t::number_integer:
13087                 case detail::value_t::number_unsigned:
13088                 case detail::value_t::number_float:
13089                 case detail::value_t::binary:
13090                 case detail::value_t::discarded:
13091                 default:
13092                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13093             }
13094         }
13095 
13096         return *ptr;
13097     }
13098 
13099     /*!
13100     @throw parse_error.106   if an array index begins with '0'
13101     @throw parse_error.109   if an array index was not a number
13102     @throw out_of_range.402  if the array index '-' is used
13103     @throw out_of_range.404  if the JSON pointer can not be resolved
13104     */
get_checked(const BasicJsonType * ptr) const13105     const BasicJsonType& get_checked(const BasicJsonType* ptr) const
13106     {
13107         for (const auto& reference_token : reference_tokens)
13108         {
13109             switch (ptr->type())
13110             {
13111                 case detail::value_t::object:
13112                 {
13113                     // note: at performs range check
13114                     ptr = &ptr->at(reference_token);
13115                     break;
13116                 }
13117 
13118                 case detail::value_t::array:
13119                 {
13120                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13121                     {
13122                         // "-" always fails the range check
13123                         JSON_THROW(detail::out_of_range::create(402,
13124                                                                 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13125                                                                 ") is out of range", *ptr));
13126                     }
13127 
13128                     // note: at performs range check
13129                     ptr = &ptr->at(array_index(reference_token));
13130                     break;
13131                 }
13132 
13133                 case detail::value_t::null:
13134                 case detail::value_t::string:
13135                 case detail::value_t::boolean:
13136                 case detail::value_t::number_integer:
13137                 case detail::value_t::number_unsigned:
13138                 case detail::value_t::number_float:
13139                 case detail::value_t::binary:
13140                 case detail::value_t::discarded:
13141                 default:
13142                     JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13143             }
13144         }
13145 
13146         return *ptr;
13147     }
13148 
13149     /*!
13150     @throw parse_error.106   if an array index begins with '0'
13151     @throw parse_error.109   if an array index was not a number
13152     */
contains(const BasicJsonType * ptr) const13153     bool contains(const BasicJsonType* ptr) const
13154     {
13155         for (const auto& reference_token : reference_tokens)
13156         {
13157             switch (ptr->type())
13158             {
13159                 case detail::value_t::object:
13160                 {
13161                     if (!ptr->contains(reference_token))
13162                     {
13163                         // we did not find the key in the object
13164                         return false;
13165                     }
13166 
13167                     ptr = &ptr->operator[](reference_token);
13168                     break;
13169                 }
13170 
13171                 case detail::value_t::array:
13172                 {
13173                     if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13174                     {
13175                         // "-" always fails the range check
13176                         return false;
13177                     }
13178                     if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13179                     {
13180                         // invalid char
13181                         return false;
13182                     }
13183                     if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
13184                     {
13185                         if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13186                         {
13187                             // first char should be between '1' and '9'
13188                             return false;
13189                         }
13190                         for (std::size_t i = 1; i < reference_token.size(); i++)
13191                         {
13192                             if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13193                             {
13194                                 // other char should be between '0' and '9'
13195                                 return false;
13196                             }
13197                         }
13198                     }
13199 
13200                     const auto idx = array_index(reference_token);
13201                     if (idx >= ptr->size())
13202                     {
13203                         // index out of range
13204                         return false;
13205                     }
13206 
13207                     ptr = &ptr->operator[](idx);
13208                     break;
13209                 }
13210 
13211                 case detail::value_t::null:
13212                 case detail::value_t::string:
13213                 case detail::value_t::boolean:
13214                 case detail::value_t::number_integer:
13215                 case detail::value_t::number_unsigned:
13216                 case detail::value_t::number_float:
13217                 case detail::value_t::binary:
13218                 case detail::value_t::discarded:
13219                 default:
13220                 {
13221                     // we do not expect primitive values if there is still a
13222                     // reference token to process
13223                     return false;
13224                 }
13225             }
13226         }
13227 
13228         // no reference token left means we found a primitive value
13229         return true;
13230     }
13231 
13232     /*!
13233     @brief split the string input to reference tokens
13234 
13235     @note This function is only called by the json_pointer constructor.
13236           All exceptions below are documented there.
13237 
13238     @throw parse_error.107  if the pointer is not empty or begins with '/'
13239     @throw parse_error.108  if character '~' is not followed by '0' or '1'
13240     */
split(const std::string & reference_string)13241     static std::vector<std::string> split(const std::string& reference_string)
13242     {
13243         std::vector<std::string> result;
13244 
13245         // special case: empty reference string -> no reference tokens
13246         if (reference_string.empty())
13247         {
13248             return result;
13249         }
13250 
13251         // check if nonempty reference string begins with slash
13252         if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
13253         {
13254             JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
13255         }
13256 
13257         // extract the reference tokens:
13258         // - slash: position of the last read slash (or end of string)
13259         // - start: position after the previous slash
13260         for (
13261             // search for the first slash after the first character
13262             std::size_t slash = reference_string.find_first_of('/', 1),
13263             // set the beginning of the first reference token
13264             start = 1;
13265             // we can stop if start == 0 (if slash == std::string::npos)
13266             start != 0;
13267             // set the beginning of the next reference token
13268             // (will eventually be 0 if slash == std::string::npos)
13269             start = (slash == std::string::npos) ? 0 : slash + 1,
13270             // find next slash
13271             slash = reference_string.find_first_of('/', start))
13272         {
13273             // use the text between the beginning of the reference token
13274             // (start) and the last slash (slash).
13275             auto reference_token = reference_string.substr(start, slash - start);
13276 
13277             // check reference tokens are properly escaped
13278             for (std::size_t pos = reference_token.find_first_of('~');
13279                     pos != std::string::npos;
13280                     pos = reference_token.find_first_of('~', pos + 1))
13281             {
13282                 JSON_ASSERT(reference_token[pos] == '~');
13283 
13284                 // ~ must be followed by 0 or 1
13285                 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
13286                                          (reference_token[pos + 1] != '0' &&
13287                                           reference_token[pos + 1] != '1')))
13288                 {
13289                     JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
13290                 }
13291             }
13292 
13293             // finally, store the reference token
13294             detail::unescape(reference_token);
13295             result.push_back(reference_token);
13296         }
13297 
13298         return result;
13299     }
13300 
13301   private:
13302     /*!
13303     @param[in] reference_string  the reference string to the current value
13304     @param[in] value             the value to consider
13305     @param[in,out] result        the result object to insert values to
13306 
13307     @note Empty objects or arrays are flattened to `null`.
13308     */
flatten(const std::string & reference_string,const BasicJsonType & value,BasicJsonType & result)13309     static void flatten(const std::string& reference_string,
13310                         const BasicJsonType& value,
13311                         BasicJsonType& result)
13312     {
13313         switch (value.type())
13314         {
13315             case detail::value_t::array:
13316             {
13317                 if (value.m_value.array->empty())
13318                 {
13319                     // flatten empty array as null
13320                     result[reference_string] = nullptr;
13321                 }
13322                 else
13323                 {
13324                     // iterate array and use index as reference string
13325                     for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13326                     {
13327                         flatten(reference_string + "/" + std::to_string(i),
13328                                 value.m_value.array->operator[](i), result);
13329                     }
13330                 }
13331                 break;
13332             }
13333 
13334             case detail::value_t::object:
13335             {
13336                 if (value.m_value.object->empty())
13337                 {
13338                     // flatten empty object as null
13339                     result[reference_string] = nullptr;
13340                 }
13341                 else
13342                 {
13343                     // iterate object and use keys as reference string
13344                     for (const auto& element : *value.m_value.object)
13345                     {
13346                         flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
13347                     }
13348                 }
13349                 break;
13350             }
13351 
13352             case detail::value_t::null:
13353             case detail::value_t::string:
13354             case detail::value_t::boolean:
13355             case detail::value_t::number_integer:
13356             case detail::value_t::number_unsigned:
13357             case detail::value_t::number_float:
13358             case detail::value_t::binary:
13359             case detail::value_t::discarded:
13360             default:
13361             {
13362                 // add primitive value with its reference string
13363                 result[reference_string] = value;
13364                 break;
13365             }
13366         }
13367     }
13368 
13369     /*!
13370     @param[in] value  flattened JSON
13371 
13372     @return unflattened JSON
13373 
13374     @throw parse_error.109 if array index is not a number
13375     @throw type_error.314  if value is not an object
13376     @throw type_error.315  if object values are not primitive
13377     @throw type_error.313  if value cannot be unflattened
13378     */
13379     static BasicJsonType
unflatten(const BasicJsonType & value)13380     unflatten(const BasicJsonType& value)
13381     {
13382         if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
13383         {
13384             JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
13385         }
13386 
13387         BasicJsonType result;
13388 
13389         // iterate the JSON object values
13390         for (const auto& element : *value.m_value.object)
13391         {
13392             if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
13393             {
13394                 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
13395             }
13396 
13397             // assign value to reference pointed to by JSON pointer; Note that if
13398             // the JSON pointer is "" (i.e., points to the whole value), function
13399             // get_and_create returns a reference to result itself. An assignment
13400             // will then create a primitive value.
13401             json_pointer(element.first).get_and_create(result) = element.second;
13402         }
13403 
13404         return result;
13405     }
13406 
13407     /*!
13408     @brief compares two JSON pointers for equality
13409 
13410     @param[in] lhs  JSON pointer to compare
13411     @param[in] rhs  JSON pointer to compare
13412     @return whether @a lhs is equal to @a rhs
13413 
13414     @complexity Linear in the length of the JSON pointer
13415 
13416     @exceptionsafety No-throw guarantee: this function never throws exceptions.
13417     */
operator ==(json_pointer const & lhs,json_pointer const & rhs)13418     friend bool operator==(json_pointer const& lhs,
13419                            json_pointer const& rhs) noexcept
13420     {
13421         return lhs.reference_tokens == rhs.reference_tokens;
13422     }
13423 
13424     /*!
13425     @brief compares two JSON pointers for inequality
13426 
13427     @param[in] lhs  JSON pointer to compare
13428     @param[in] rhs  JSON pointer to compare
13429     @return whether @a lhs is not equal @a rhs
13430 
13431     @complexity Linear in the length of the JSON pointer
13432 
13433     @exceptionsafety No-throw guarantee: this function never throws exceptions.
13434     */
operator !=(json_pointer const & lhs,json_pointer const & rhs)13435     friend bool operator!=(json_pointer const& lhs,
13436                            json_pointer const& rhs) noexcept
13437     {
13438         return !(lhs == rhs);
13439     }
13440 
13441     /// the reference tokens
13442     std::vector<std::string> reference_tokens;
13443 };
13444 }  // namespace nlohmann
13445 
13446 // #include <nlohmann/detail/json_ref.hpp>
13447 
13448 
13449 #include <initializer_list>
13450 #include <utility>
13451 
13452 // #include <nlohmann/detail/meta/type_traits.hpp>
13453 
13454 
13455 namespace nlohmann
13456 {
13457 namespace detail
13458 {
13459 template<typename BasicJsonType>
13460 class json_ref
13461 {
13462   public:
13463     using value_type = BasicJsonType;
13464 
json_ref(value_type && value)13465     json_ref(value_type&& value)
13466         : owned_value(std::move(value))
13467     {}
13468 
json_ref(const value_type & value)13469     json_ref(const value_type& value)
13470         : value_ref(&value)
13471     {}
13472 
json_ref(std::initializer_list<json_ref> init)13473     json_ref(std::initializer_list<json_ref> init)
13474         : owned_value(init)
13475     {}
13476 
13477     template <
13478         class... Args,
13479         enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
json_ref(Args &&...args)13480     json_ref(Args && ... args)
13481         : owned_value(std::forward<Args>(args)...)
13482     {}
13483 
13484     // class should be movable only
13485     json_ref(json_ref&&) noexcept = default;
13486     json_ref(const json_ref&) = delete;
13487     json_ref& operator=(const json_ref&) = delete;
13488     json_ref& operator=(json_ref&&) = delete;
13489     ~json_ref() = default;
13490 
moved_or_copied() const13491     value_type moved_or_copied() const
13492     {
13493         if (value_ref == nullptr)
13494         {
13495             return std::move(owned_value);
13496         }
13497         return *value_ref;
13498     }
13499 
operator *() const13500     value_type const& operator*() const
13501     {
13502         return value_ref ? *value_ref : owned_value;
13503     }
13504 
operator ->() const13505     value_type const* operator->() const
13506     {
13507         return &** this;
13508     }
13509 
13510   private:
13511     mutable value_type owned_value = nullptr;
13512     value_type const* value_ref = nullptr;
13513 };
13514 }  // namespace detail
13515 }  // namespace nlohmann
13516 
13517 // #include <nlohmann/detail/macro_scope.hpp>
13518 
13519 // #include <nlohmann/detail/string_escape.hpp>
13520 
13521 // #include <nlohmann/detail/meta/cpp_future.hpp>
13522 
13523 // #include <nlohmann/detail/meta/type_traits.hpp>
13524 
13525 // #include <nlohmann/detail/output/binary_writer.hpp>
13526 
13527 
13528 #include <algorithm> // reverse
13529 #include <array> // array
13530 #include <cmath> // isnan, isinf
13531 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13532 #include <cstring> // memcpy
13533 #include <limits> // numeric_limits
13534 #include <string> // string
13535 #include <utility> // move
13536 
13537 // #include <nlohmann/detail/input/binary_reader.hpp>
13538 
13539 // #include <nlohmann/detail/macro_scope.hpp>
13540 
13541 // #include <nlohmann/detail/output/output_adapters.hpp>
13542 
13543 
13544 #include <algorithm> // copy
13545 #include <cstddef> // size_t
13546 #include <iterator> // back_inserter
13547 #include <memory> // shared_ptr, make_shared
13548 #include <string> // basic_string
13549 #include <vector> // vector
13550 
13551 #ifndef JSON_NO_IO
13552     #include <ios>      // streamsize
13553     #include <ostream>  // basic_ostream
13554 #endif  // JSON_NO_IO
13555 
13556 // #include <nlohmann/detail/macro_scope.hpp>
13557 
13558 
13559 namespace nlohmann
13560 {
13561 namespace detail
13562 {
13563 /// abstract output adapter interface
13564 template<typename CharType> struct output_adapter_protocol
13565 {
13566     virtual void write_character(CharType c) = 0;
13567     virtual void write_characters(const CharType* s, std::size_t length) = 0;
13568     virtual ~output_adapter_protocol() = default;
13569 
13570     output_adapter_protocol() = default;
13571     output_adapter_protocol(const output_adapter_protocol&) = default;
13572     output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
13573     output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
13574     output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
13575 };
13576 
13577 /// a type to simplify interfaces
13578 template<typename CharType>
13579 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13580 
13581 /// output adapter for byte vectors
13582 template<typename CharType, typename AllocatorType = std::allocator<CharType>>
13583 class output_vector_adapter : public output_adapter_protocol<CharType>
13584 {
13585   public:
output_vector_adapter(std::vector<CharType,AllocatorType> & vec)13586     explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
13587         : v(vec)
13588     {}
13589 
write_character(CharType c)13590     void write_character(CharType c) override
13591     {
13592         v.push_back(c);
13593     }
13594 
13595     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)13596     void write_characters(const CharType* s, std::size_t length) override
13597     {
13598         std::copy(s, s + length, std::back_inserter(v));
13599     }
13600 
13601   private:
13602     std::vector<CharType, AllocatorType>& v;
13603 };
13604 
13605 #ifndef JSON_NO_IO
13606 /// output adapter for output streams
13607 template<typename CharType>
13608 class output_stream_adapter : public output_adapter_protocol<CharType>
13609 {
13610   public:
output_stream_adapter(std::basic_ostream<CharType> & s)13611     explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13612         : stream(s)
13613     {}
13614 
write_character(CharType c)13615     void write_character(CharType c) override
13616     {
13617         stream.put(c);
13618     }
13619 
13620     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)13621     void write_characters(const CharType* s, std::size_t length) override
13622     {
13623         stream.write(s, static_cast<std::streamsize>(length));
13624     }
13625 
13626   private:
13627     std::basic_ostream<CharType>& stream;
13628 };
13629 #endif  // JSON_NO_IO
13630 
13631 /// output adapter for basic_string
13632 template<typename CharType, typename StringType = std::basic_string<CharType>>
13633 class output_string_adapter : public output_adapter_protocol<CharType>
13634 {
13635   public:
output_string_adapter(StringType & s)13636     explicit output_string_adapter(StringType& s) noexcept
13637         : str(s)
13638     {}
13639 
write_character(CharType c)13640     void write_character(CharType c) override
13641     {
13642         str.push_back(c);
13643     }
13644 
13645     JSON_HEDLEY_NON_NULL(2)
write_characters(const CharType * s,std::size_t length)13646     void write_characters(const CharType* s, std::size_t length) override
13647     {
13648         str.append(s, length);
13649     }
13650 
13651   private:
13652     StringType& str;
13653 };
13654 
13655 template<typename CharType, typename StringType = std::basic_string<CharType>>
13656 class output_adapter
13657 {
13658   public:
13659     template<typename AllocatorType = std::allocator<CharType>>
output_adapter(std::vector<CharType,AllocatorType> & vec)13660     output_adapter(std::vector<CharType, AllocatorType>& vec)
13661         : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
13662 
13663 #ifndef JSON_NO_IO
output_adapter(std::basic_ostream<CharType> & s)13664     output_adapter(std::basic_ostream<CharType>& s)
13665         : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
13666 #endif  // JSON_NO_IO
13667 
output_adapter(StringType & s)13668     output_adapter(StringType& s)
13669         : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
13670 
operator output_adapter_t<CharType>()13671     operator output_adapter_t<CharType>()
13672     {
13673         return oa;
13674     }
13675 
13676   private:
13677     output_adapter_t<CharType> oa = nullptr;
13678 };
13679 }  // namespace detail
13680 }  // namespace nlohmann
13681 
13682 
13683 namespace nlohmann
13684 {
13685 namespace detail
13686 {
13687 ///////////////////
13688 // binary writer //
13689 ///////////////////
13690 
13691 /*!
13692 @brief serialization to CBOR and MessagePack values
13693 */
13694 template<typename BasicJsonType, typename CharType>
13695 class binary_writer
13696 {
13697     using string_t = typename BasicJsonType::string_t;
13698     using binary_t = typename BasicJsonType::binary_t;
13699     using number_float_t = typename BasicJsonType::number_float_t;
13700 
13701   public:
13702     /*!
13703     @brief create a binary writer
13704 
13705     @param[in] adapter  output adapter to write to
13706     */
binary_writer(output_adapter_t<CharType> adapter)13707     explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
13708     {
13709         JSON_ASSERT(oa);
13710     }
13711 
13712     /*!
13713     @param[in] j  JSON value to serialize
13714     @pre       j.type() == value_t::object
13715     */
write_bson(const BasicJsonType & j)13716     void write_bson(const BasicJsonType& j)
13717     {
13718         switch (j.type())
13719         {
13720             case value_t::object:
13721             {
13722                 write_bson_object(*j.m_value.object);
13723                 break;
13724             }
13725 
13726             case value_t::null:
13727             case value_t::array:
13728             case value_t::string:
13729             case value_t::boolean:
13730             case value_t::number_integer:
13731             case value_t::number_unsigned:
13732             case value_t::number_float:
13733             case value_t::binary:
13734             case value_t::discarded:
13735             default:
13736             {
13737                 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));
13738             }
13739         }
13740     }
13741 
13742     /*!
13743     @param[in] j  JSON value to serialize
13744     */
write_cbor(const BasicJsonType & j)13745     void write_cbor(const BasicJsonType& j)
13746     {
13747         switch (j.type())
13748         {
13749             case value_t::null:
13750             {
13751                 oa->write_character(to_char_type(0xF6));
13752                 break;
13753             }
13754 
13755             case value_t::boolean:
13756             {
13757                 oa->write_character(j.m_value.boolean
13758                                     ? to_char_type(0xF5)
13759                                     : to_char_type(0xF4));
13760                 break;
13761             }
13762 
13763             case value_t::number_integer:
13764             {
13765                 if (j.m_value.number_integer >= 0)
13766                 {
13767                     // CBOR does not differentiate between positive signed
13768                     // integers and unsigned integers. Therefore, we used the
13769                     // code from the value_t::number_unsigned case here.
13770                     if (j.m_value.number_integer <= 0x17)
13771                     {
13772                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13773                     }
13774                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13775                     {
13776                         oa->write_character(to_char_type(0x18));
13777                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13778                     }
13779                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
13780                     {
13781                         oa->write_character(to_char_type(0x19));
13782                         write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13783                     }
13784                     else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
13785                     {
13786                         oa->write_character(to_char_type(0x1A));
13787                         write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13788                     }
13789                     else
13790                     {
13791                         oa->write_character(to_char_type(0x1B));
13792                         write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13793                     }
13794                 }
13795                 else
13796                 {
13797                     // The conversions below encode the sign in the first
13798                     // byte, and the value is converted to a positive number.
13799                     const auto positive_number = -1 - j.m_value.number_integer;
13800                     if (j.m_value.number_integer >= -24)
13801                     {
13802                         write_number(static_cast<std::uint8_t>(0x20 + positive_number));
13803                     }
13804                     else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
13805                     {
13806                         oa->write_character(to_char_type(0x38));
13807                         write_number(static_cast<std::uint8_t>(positive_number));
13808                     }
13809                     else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
13810                     {
13811                         oa->write_character(to_char_type(0x39));
13812                         write_number(static_cast<std::uint16_t>(positive_number));
13813                     }
13814                     else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
13815                     {
13816                         oa->write_character(to_char_type(0x3A));
13817                         write_number(static_cast<std::uint32_t>(positive_number));
13818                     }
13819                     else
13820                     {
13821                         oa->write_character(to_char_type(0x3B));
13822                         write_number(static_cast<std::uint64_t>(positive_number));
13823                     }
13824                 }
13825                 break;
13826             }
13827 
13828             case value_t::number_unsigned:
13829             {
13830                 if (j.m_value.number_unsigned <= 0x17)
13831                 {
13832                     write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13833                 }
13834                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13835                 {
13836                     oa->write_character(to_char_type(0x18));
13837                     write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13838                 }
13839                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13840                 {
13841                     oa->write_character(to_char_type(0x19));
13842                     write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
13843                 }
13844                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13845                 {
13846                     oa->write_character(to_char_type(0x1A));
13847                     write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
13848                 }
13849                 else
13850                 {
13851                     oa->write_character(to_char_type(0x1B));
13852                     write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
13853                 }
13854                 break;
13855             }
13856 
13857             case value_t::number_float:
13858             {
13859                 if (std::isnan(j.m_value.number_float))
13860                 {
13861                     // NaN is 0xf97e00 in CBOR
13862                     oa->write_character(to_char_type(0xF9));
13863                     oa->write_character(to_char_type(0x7E));
13864                     oa->write_character(to_char_type(0x00));
13865                 }
13866                 else if (std::isinf(j.m_value.number_float))
13867                 {
13868                     // Infinity is 0xf97c00, -Infinity is 0xf9fc00
13869                     oa->write_character(to_char_type(0xf9));
13870                     oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
13871                     oa->write_character(to_char_type(0x00));
13872                 }
13873                 else
13874                 {
13875                     write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
13876                 }
13877                 break;
13878             }
13879 
13880             case value_t::string:
13881             {
13882                 // step 1: write control byte and the string length
13883                 const auto N = j.m_value.string->size();
13884                 if (N <= 0x17)
13885                 {
13886                     write_number(static_cast<std::uint8_t>(0x60 + N));
13887                 }
13888                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13889                 {
13890                     oa->write_character(to_char_type(0x78));
13891                     write_number(static_cast<std::uint8_t>(N));
13892                 }
13893                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13894                 {
13895                     oa->write_character(to_char_type(0x79));
13896                     write_number(static_cast<std::uint16_t>(N));
13897                 }
13898                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13899                 {
13900                     oa->write_character(to_char_type(0x7A));
13901                     write_number(static_cast<std::uint32_t>(N));
13902                 }
13903                 // LCOV_EXCL_START
13904                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13905                 {
13906                     oa->write_character(to_char_type(0x7B));
13907                     write_number(static_cast<std::uint64_t>(N));
13908                 }
13909                 // LCOV_EXCL_STOP
13910 
13911                 // step 2: write the string
13912                 oa->write_characters(
13913                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13914                     j.m_value.string->size());
13915                 break;
13916             }
13917 
13918             case value_t::array:
13919             {
13920                 // step 1: write control byte and the array size
13921                 const auto N = j.m_value.array->size();
13922                 if (N <= 0x17)
13923                 {
13924                     write_number(static_cast<std::uint8_t>(0x80 + N));
13925                 }
13926                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13927                 {
13928                     oa->write_character(to_char_type(0x98));
13929                     write_number(static_cast<std::uint8_t>(N));
13930                 }
13931                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13932                 {
13933                     oa->write_character(to_char_type(0x99));
13934                     write_number(static_cast<std::uint16_t>(N));
13935                 }
13936                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13937                 {
13938                     oa->write_character(to_char_type(0x9A));
13939                     write_number(static_cast<std::uint32_t>(N));
13940                 }
13941                 // LCOV_EXCL_START
13942                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13943                 {
13944                     oa->write_character(to_char_type(0x9B));
13945                     write_number(static_cast<std::uint64_t>(N));
13946                 }
13947                 // LCOV_EXCL_STOP
13948 
13949                 // step 2: write each element
13950                 for (const auto& el : *j.m_value.array)
13951                 {
13952                     write_cbor(el);
13953                 }
13954                 break;
13955             }
13956 
13957             case value_t::binary:
13958             {
13959                 if (j.m_value.binary->has_subtype())
13960                 {
13961                     if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
13962                     {
13963                         write_number(static_cast<std::uint8_t>(0xd8));
13964                         write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
13965                     }
13966                     else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
13967                     {
13968                         write_number(static_cast<std::uint8_t>(0xd9));
13969                         write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
13970                     }
13971                     else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
13972                     {
13973                         write_number(static_cast<std::uint8_t>(0xda));
13974                         write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
13975                     }
13976                     else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
13977                     {
13978                         write_number(static_cast<std::uint8_t>(0xdb));
13979                         write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
13980                     }
13981                 }
13982 
13983                 // step 1: write control byte and the binary array size
13984                 const auto N = j.m_value.binary->size();
13985                 if (N <= 0x17)
13986                 {
13987                     write_number(static_cast<std::uint8_t>(0x40 + N));
13988                 }
13989                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13990                 {
13991                     oa->write_character(to_char_type(0x58));
13992                     write_number(static_cast<std::uint8_t>(N));
13993                 }
13994                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13995                 {
13996                     oa->write_character(to_char_type(0x59));
13997                     write_number(static_cast<std::uint16_t>(N));
13998                 }
13999                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14000                 {
14001                     oa->write_character(to_char_type(0x5A));
14002                     write_number(static_cast<std::uint32_t>(N));
14003                 }
14004                 // LCOV_EXCL_START
14005                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14006                 {
14007                     oa->write_character(to_char_type(0x5B));
14008                     write_number(static_cast<std::uint64_t>(N));
14009                 }
14010                 // LCOV_EXCL_STOP
14011 
14012                 // step 2: write each element
14013                 oa->write_characters(
14014                     reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14015                     N);
14016 
14017                 break;
14018             }
14019 
14020             case value_t::object:
14021             {
14022                 // step 1: write control byte and the object size
14023                 const auto N = j.m_value.object->size();
14024                 if (N <= 0x17)
14025                 {
14026                     write_number(static_cast<std::uint8_t>(0xA0 + N));
14027                 }
14028                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14029                 {
14030                     oa->write_character(to_char_type(0xB8));
14031                     write_number(static_cast<std::uint8_t>(N));
14032                 }
14033                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14034                 {
14035                     oa->write_character(to_char_type(0xB9));
14036                     write_number(static_cast<std::uint16_t>(N));
14037                 }
14038                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14039                 {
14040                     oa->write_character(to_char_type(0xBA));
14041                     write_number(static_cast<std::uint32_t>(N));
14042                 }
14043                 // LCOV_EXCL_START
14044                 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14045                 {
14046                     oa->write_character(to_char_type(0xBB));
14047                     write_number(static_cast<std::uint64_t>(N));
14048                 }
14049                 // LCOV_EXCL_STOP
14050 
14051                 // step 2: write each element
14052                 for (const auto& el : *j.m_value.object)
14053                 {
14054                     write_cbor(el.first);
14055                     write_cbor(el.second);
14056                 }
14057                 break;
14058             }
14059 
14060             case value_t::discarded:
14061             default:
14062                 break;
14063         }
14064     }
14065 
14066     /*!
14067     @param[in] j  JSON value to serialize
14068     */
write_msgpack(const BasicJsonType & j)14069     void write_msgpack(const BasicJsonType& j)
14070     {
14071         switch (j.type())
14072         {
14073             case value_t::null: // nil
14074             {
14075                 oa->write_character(to_char_type(0xC0));
14076                 break;
14077             }
14078 
14079             case value_t::boolean: // true and false
14080             {
14081                 oa->write_character(j.m_value.boolean
14082                                     ? to_char_type(0xC3)
14083                                     : to_char_type(0xC2));
14084                 break;
14085             }
14086 
14087             case value_t::number_integer:
14088             {
14089                 if (j.m_value.number_integer >= 0)
14090                 {
14091                     // MessagePack does not differentiate between positive
14092                     // signed integers and unsigned integers. Therefore, we used
14093                     // the code from the value_t::number_unsigned case here.
14094                     if (j.m_value.number_unsigned < 128)
14095                     {
14096                         // positive fixnum
14097                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14098                     }
14099                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14100                     {
14101                         // uint 8
14102                         oa->write_character(to_char_type(0xCC));
14103                         write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14104                     }
14105                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14106                     {
14107                         // uint 16
14108                         oa->write_character(to_char_type(0xCD));
14109                         write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14110                     }
14111                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14112                     {
14113                         // uint 32
14114                         oa->write_character(to_char_type(0xCE));
14115                         write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14116                     }
14117                     else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14118                     {
14119                         // uint 64
14120                         oa->write_character(to_char_type(0xCF));
14121                         write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14122                     }
14123                 }
14124                 else
14125                 {
14126                     if (j.m_value.number_integer >= -32)
14127                     {
14128                         // negative fixnum
14129                         write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14130                     }
14131                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14132                              j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14133                     {
14134                         // int 8
14135                         oa->write_character(to_char_type(0xD0));
14136                         write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14137                     }
14138                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14139                              j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14140                     {
14141                         // int 16
14142                         oa->write_character(to_char_type(0xD1));
14143                         write_number(static_cast<std::int16_t>(j.m_value.number_integer));
14144                     }
14145                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14146                              j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14147                     {
14148                         // int 32
14149                         oa->write_character(to_char_type(0xD2));
14150                         write_number(static_cast<std::int32_t>(j.m_value.number_integer));
14151                     }
14152                     else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14153                              j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14154                     {
14155                         // int 64
14156                         oa->write_character(to_char_type(0xD3));
14157                         write_number(static_cast<std::int64_t>(j.m_value.number_integer));
14158                     }
14159                 }
14160                 break;
14161             }
14162 
14163             case value_t::number_unsigned:
14164             {
14165                 if (j.m_value.number_unsigned < 128)
14166                 {
14167                     // positive fixnum
14168                     write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14169                 }
14170                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14171                 {
14172                     // uint 8
14173                     oa->write_character(to_char_type(0xCC));
14174                     write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14175                 }
14176                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14177                 {
14178                     // uint 16
14179                     oa->write_character(to_char_type(0xCD));
14180                     write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14181                 }
14182                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14183                 {
14184                     // uint 32
14185                     oa->write_character(to_char_type(0xCE));
14186                     write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14187                 }
14188                 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14189                 {
14190                     // uint 64
14191                     oa->write_character(to_char_type(0xCF));
14192                     write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14193                 }
14194                 break;
14195             }
14196 
14197             case value_t::number_float:
14198             {
14199                 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
14200                 break;
14201             }
14202 
14203             case value_t::string:
14204             {
14205                 // step 1: write control byte and the string length
14206                 const auto N = j.m_value.string->size();
14207                 if (N <= 31)
14208                 {
14209                     // fixstr
14210                     write_number(static_cast<std::uint8_t>(0xA0 | N));
14211                 }
14212                 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14213                 {
14214                     // str 8
14215                     oa->write_character(to_char_type(0xD9));
14216                     write_number(static_cast<std::uint8_t>(N));
14217                 }
14218                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14219                 {
14220                     // str 16
14221                     oa->write_character(to_char_type(0xDA));
14222                     write_number(static_cast<std::uint16_t>(N));
14223                 }
14224                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14225                 {
14226                     // str 32
14227                     oa->write_character(to_char_type(0xDB));
14228                     write_number(static_cast<std::uint32_t>(N));
14229                 }
14230 
14231                 // step 2: write the string
14232                 oa->write_characters(
14233                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14234                     j.m_value.string->size());
14235                 break;
14236             }
14237 
14238             case value_t::array:
14239             {
14240                 // step 1: write control byte and the array size
14241                 const auto N = j.m_value.array->size();
14242                 if (N <= 15)
14243                 {
14244                     // fixarray
14245                     write_number(static_cast<std::uint8_t>(0x90 | N));
14246                 }
14247                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14248                 {
14249                     // array 16
14250                     oa->write_character(to_char_type(0xDC));
14251                     write_number(static_cast<std::uint16_t>(N));
14252                 }
14253                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14254                 {
14255                     // array 32
14256                     oa->write_character(to_char_type(0xDD));
14257                     write_number(static_cast<std::uint32_t>(N));
14258                 }
14259 
14260                 // step 2: write each element
14261                 for (const auto& el : *j.m_value.array)
14262                 {
14263                     write_msgpack(el);
14264                 }
14265                 break;
14266             }
14267 
14268             case value_t::binary:
14269             {
14270                 // step 0: determine if the binary type has a set subtype to
14271                 // determine whether or not to use the ext or fixext types
14272                 const bool use_ext = j.m_value.binary->has_subtype();
14273 
14274                 // step 1: write control byte and the byte string length
14275                 const auto N = j.m_value.binary->size();
14276                 if (N <= (std::numeric_limits<std::uint8_t>::max)())
14277                 {
14278                     std::uint8_t output_type{};
14279                     bool fixed = true;
14280                     if (use_ext)
14281                     {
14282                         switch (N)
14283                         {
14284                             case 1:
14285                                 output_type = 0xD4; // fixext 1
14286                                 break;
14287                             case 2:
14288                                 output_type = 0xD5; // fixext 2
14289                                 break;
14290                             case 4:
14291                                 output_type = 0xD6; // fixext 4
14292                                 break;
14293                             case 8:
14294                                 output_type = 0xD7; // fixext 8
14295                                 break;
14296                             case 16:
14297                                 output_type = 0xD8; // fixext 16
14298                                 break;
14299                             default:
14300                                 output_type = 0xC7; // ext 8
14301                                 fixed = false;
14302                                 break;
14303                         }
14304 
14305                     }
14306                     else
14307                     {
14308                         output_type = 0xC4; // bin 8
14309                         fixed = false;
14310                     }
14311 
14312                     oa->write_character(to_char_type(output_type));
14313                     if (!fixed)
14314                     {
14315                         write_number(static_cast<std::uint8_t>(N));
14316                     }
14317                 }
14318                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14319                 {
14320                     std::uint8_t output_type = use_ext
14321                                                ? 0xC8 // ext 16
14322                                                : 0xC5; // bin 16
14323 
14324                     oa->write_character(to_char_type(output_type));
14325                     write_number(static_cast<std::uint16_t>(N));
14326                 }
14327                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14328                 {
14329                     std::uint8_t output_type = use_ext
14330                                                ? 0xC9 // ext 32
14331                                                : 0xC6; // bin 32
14332 
14333                     oa->write_character(to_char_type(output_type));
14334                     write_number(static_cast<std::uint32_t>(N));
14335                 }
14336 
14337                 // step 1.5: if this is an ext type, write the subtype
14338                 if (use_ext)
14339                 {
14340                     write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14341                 }
14342 
14343                 // step 2: write the byte string
14344                 oa->write_characters(
14345                     reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14346                     N);
14347 
14348                 break;
14349             }
14350 
14351             case value_t::object:
14352             {
14353                 // step 1: write control byte and the object size
14354                 const auto N = j.m_value.object->size();
14355                 if (N <= 15)
14356                 {
14357                     // fixmap
14358                     write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
14359                 }
14360                 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14361                 {
14362                     // map 16
14363                     oa->write_character(to_char_type(0xDE));
14364                     write_number(static_cast<std::uint16_t>(N));
14365                 }
14366                 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14367                 {
14368                     // map 32
14369                     oa->write_character(to_char_type(0xDF));
14370                     write_number(static_cast<std::uint32_t>(N));
14371                 }
14372 
14373                 // step 2: write each element
14374                 for (const auto& el : *j.m_value.object)
14375                 {
14376                     write_msgpack(el.first);
14377                     write_msgpack(el.second);
14378                 }
14379                 break;
14380             }
14381 
14382             case value_t::discarded:
14383             default:
14384                 break;
14385         }
14386     }
14387 
14388     /*!
14389     @param[in] j  JSON value to serialize
14390     @param[in] use_count   whether to use '#' prefixes (optimized format)
14391     @param[in] use_type    whether to use '$' prefixes (optimized format)
14392     @param[in] add_prefix  whether prefixes need to be used for this value
14393     */
write_ubjson(const BasicJsonType & j,const bool use_count,const bool use_type,const bool add_prefix=true)14394     void write_ubjson(const BasicJsonType& j, const bool use_count,
14395                       const bool use_type, const bool add_prefix = true)
14396     {
14397         switch (j.type())
14398         {
14399             case value_t::null:
14400             {
14401                 if (add_prefix)
14402                 {
14403                     oa->write_character(to_char_type('Z'));
14404                 }
14405                 break;
14406             }
14407 
14408             case value_t::boolean:
14409             {
14410                 if (add_prefix)
14411                 {
14412                     oa->write_character(j.m_value.boolean
14413                                         ? to_char_type('T')
14414                                         : to_char_type('F'));
14415                 }
14416                 break;
14417             }
14418 
14419             case value_t::number_integer:
14420             {
14421                 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
14422                 break;
14423             }
14424 
14425             case value_t::number_unsigned:
14426             {
14427                 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
14428                 break;
14429             }
14430 
14431             case value_t::number_float:
14432             {
14433                 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
14434                 break;
14435             }
14436 
14437             case value_t::string:
14438             {
14439                 if (add_prefix)
14440                 {
14441                     oa->write_character(to_char_type('S'));
14442                 }
14443                 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
14444                 oa->write_characters(
14445                     reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14446                     j.m_value.string->size());
14447                 break;
14448             }
14449 
14450             case value_t::array:
14451             {
14452                 if (add_prefix)
14453                 {
14454                     oa->write_character(to_char_type('['));
14455                 }
14456 
14457                 bool prefix_required = true;
14458                 if (use_type && !j.m_value.array->empty())
14459                 {
14460                     JSON_ASSERT(use_count);
14461                     const CharType first_prefix = ubjson_prefix(j.front());
14462                     const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14463                                                          [this, first_prefix](const BasicJsonType & v)
14464                     {
14465                         return ubjson_prefix(v) == first_prefix;
14466                     });
14467 
14468                     if (same_prefix)
14469                     {
14470                         prefix_required = false;
14471                         oa->write_character(to_char_type('$'));
14472                         oa->write_character(first_prefix);
14473                     }
14474                 }
14475 
14476                 if (use_count)
14477                 {
14478                     oa->write_character(to_char_type('#'));
14479                     write_number_with_ubjson_prefix(j.m_value.array->size(), true);
14480                 }
14481 
14482                 for (const auto& el : *j.m_value.array)
14483                 {
14484                     write_ubjson(el, use_count, use_type, prefix_required);
14485                 }
14486 
14487                 if (!use_count)
14488                 {
14489                     oa->write_character(to_char_type(']'));
14490                 }
14491 
14492                 break;
14493             }
14494 
14495             case value_t::binary:
14496             {
14497                 if (add_prefix)
14498                 {
14499                     oa->write_character(to_char_type('['));
14500                 }
14501 
14502                 if (use_type && !j.m_value.binary->empty())
14503                 {
14504                     JSON_ASSERT(use_count);
14505                     oa->write_character(to_char_type('$'));
14506                     oa->write_character('U');
14507                 }
14508 
14509                 if (use_count)
14510                 {
14511                     oa->write_character(to_char_type('#'));
14512                     write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
14513                 }
14514 
14515                 if (use_type)
14516                 {
14517                     oa->write_characters(
14518                         reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14519                         j.m_value.binary->size());
14520                 }
14521                 else
14522                 {
14523                     for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14524                     {
14525                         oa->write_character(to_char_type('U'));
14526                         oa->write_character(j.m_value.binary->data()[i]);
14527                     }
14528                 }
14529 
14530                 if (!use_count)
14531                 {
14532                     oa->write_character(to_char_type(']'));
14533                 }
14534 
14535                 break;
14536             }
14537 
14538             case value_t::object:
14539             {
14540                 if (add_prefix)
14541                 {
14542                     oa->write_character(to_char_type('{'));
14543                 }
14544 
14545                 bool prefix_required = true;
14546                 if (use_type && !j.m_value.object->empty())
14547                 {
14548                     JSON_ASSERT(use_count);
14549                     const CharType first_prefix = ubjson_prefix(j.front());
14550                     const bool same_prefix = std::all_of(j.begin(), j.end(),
14551                                                          [this, first_prefix](const BasicJsonType & v)
14552                     {
14553                         return ubjson_prefix(v) == first_prefix;
14554                     });
14555 
14556                     if (same_prefix)
14557                     {
14558                         prefix_required = false;
14559                         oa->write_character(to_char_type('$'));
14560                         oa->write_character(first_prefix);
14561                     }
14562                 }
14563 
14564                 if (use_count)
14565                 {
14566                     oa->write_character(to_char_type('#'));
14567                     write_number_with_ubjson_prefix(j.m_value.object->size(), true);
14568                 }
14569 
14570                 for (const auto& el : *j.m_value.object)
14571                 {
14572                     write_number_with_ubjson_prefix(el.first.size(), true);
14573                     oa->write_characters(
14574                         reinterpret_cast<const CharType*>(el.first.c_str()),
14575                         el.first.size());
14576                     write_ubjson(el.second, use_count, use_type, prefix_required);
14577                 }
14578 
14579                 if (!use_count)
14580                 {
14581                     oa->write_character(to_char_type('}'));
14582                 }
14583 
14584                 break;
14585             }
14586 
14587             case value_t::discarded:
14588             default:
14589                 break;
14590         }
14591     }
14592 
14593   private:
14594     //////////
14595     // BSON //
14596     //////////
14597 
14598     /*!
14599     @return The size of a BSON document entry header, including the id marker
14600             and the entry name size (and its null-terminator).
14601     */
calc_bson_entry_header_size(const string_t & name,const BasicJsonType & j)14602     static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14603     {
14604         const auto it = name.find(static_cast<typename string_t::value_type>(0));
14605         if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14606         {
14607             JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
14608             static_cast<void>(j);
14609         }
14610 
14611         return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14612     }
14613 
14614     /*!
14615     @brief Writes the given @a element_type and @a name to the output adapter
14616     */
write_bson_entry_header(const string_t & name,const std::uint8_t element_type)14617     void write_bson_entry_header(const string_t& name,
14618                                  const std::uint8_t element_type)
14619     {
14620         oa->write_character(to_char_type(element_type)); // boolean
14621         oa->write_characters(
14622             reinterpret_cast<const CharType*>(name.c_str()),
14623             name.size() + 1u);
14624     }
14625 
14626     /*!
14627     @brief Writes a BSON element with key @a name and boolean value @a value
14628     */
write_bson_boolean(const string_t & name,const bool value)14629     void write_bson_boolean(const string_t& name,
14630                             const bool value)
14631     {
14632         write_bson_entry_header(name, 0x08);
14633         oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
14634     }
14635 
14636     /*!
14637     @brief Writes a BSON element with key @a name and double value @a value
14638     */
write_bson_double(const string_t & name,const double value)14639     void write_bson_double(const string_t& name,
14640                            const double value)
14641     {
14642         write_bson_entry_header(name, 0x01);
14643         write_number<double, true>(value);
14644     }
14645 
14646     /*!
14647     @return The size of the BSON-encoded string in @a value
14648     */
calc_bson_string_size(const string_t & value)14649     static std::size_t calc_bson_string_size(const string_t& value)
14650     {
14651         return sizeof(std::int32_t) + value.size() + 1ul;
14652     }
14653 
14654     /*!
14655     @brief Writes a BSON element with key @a name and string value @a value
14656     */
write_bson_string(const string_t & name,const string_t & value)14657     void write_bson_string(const string_t& name,
14658                            const string_t& value)
14659     {
14660         write_bson_entry_header(name, 0x02);
14661 
14662         write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
14663         oa->write_characters(
14664             reinterpret_cast<const CharType*>(value.c_str()),
14665             value.size() + 1);
14666     }
14667 
14668     /*!
14669     @brief Writes a BSON element with key @a name and null value
14670     */
write_bson_null(const string_t & name)14671     void write_bson_null(const string_t& name)
14672     {
14673         write_bson_entry_header(name, 0x0A);
14674     }
14675 
14676     /*!
14677     @return The size of the BSON-encoded integer @a value
14678     */
calc_bson_integer_size(const std::int64_t value)14679     static std::size_t calc_bson_integer_size(const std::int64_t value)
14680     {
14681         return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
14682                ? sizeof(std::int32_t)
14683                : sizeof(std::int64_t);
14684     }
14685 
14686     /*!
14687     @brief Writes a BSON element with key @a name and integer @a value
14688     */
write_bson_integer(const string_t & name,const std::int64_t value)14689     void write_bson_integer(const string_t& name,
14690                             const std::int64_t value)
14691     {
14692         if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
14693         {
14694             write_bson_entry_header(name, 0x10); // int32
14695             write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
14696         }
14697         else
14698         {
14699             write_bson_entry_header(name, 0x12); // int64
14700             write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
14701         }
14702     }
14703 
14704     /*!
14705     @return The size of the BSON-encoded unsigned integer in @a j
14706     */
calc_bson_unsigned_size(const std::uint64_t value)14707     static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
14708     {
14709         return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14710                ? sizeof(std::int32_t)
14711                : sizeof(std::int64_t);
14712     }
14713 
14714     /*!
14715     @brief Writes a BSON element with key @a name and unsigned @a value
14716     */
write_bson_unsigned(const string_t & name,const BasicJsonType & j)14717     void write_bson_unsigned(const string_t& name,
14718                              const BasicJsonType& j)
14719     {
14720         if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14721         {
14722             write_bson_entry_header(name, 0x10 /* int32 */);
14723             write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
14724         }
14725         else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14726         {
14727             write_bson_entry_header(name, 0x12 /* int64 */);
14728             write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
14729         }
14730         else
14731         {
14732             JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(j.m_value.number_unsigned) + " cannot be represented by BSON as it does not fit int64", j));
14733         }
14734     }
14735 
14736     /*!
14737     @brief Writes a BSON element with key @a name and object @a value
14738     */
write_bson_object_entry(const string_t & name,const typename BasicJsonType::object_t & value)14739     void write_bson_object_entry(const string_t& name,
14740                                  const typename BasicJsonType::object_t& value)
14741     {
14742         write_bson_entry_header(name, 0x03); // object
14743         write_bson_object(value);
14744     }
14745 
14746     /*!
14747     @return The size of the BSON-encoded array @a value
14748     */
calc_bson_array_size(const typename BasicJsonType::array_t & value)14749     static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
14750     {
14751         std::size_t array_index = 0ul;
14752 
14753         const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
14754         {
14755             return result + calc_bson_element_size(std::to_string(array_index++), el);
14756         });
14757 
14758         return sizeof(std::int32_t) + embedded_document_size + 1ul;
14759     }
14760 
14761     /*!
14762     @return The size of the BSON-encoded binary array @a value
14763     */
calc_bson_binary_size(const typename BasicJsonType::binary_t & value)14764     static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
14765     {
14766         return sizeof(std::int32_t) + value.size() + 1ul;
14767     }
14768 
14769     /*!
14770     @brief Writes a BSON element with key @a name and array @a value
14771     */
write_bson_array(const string_t & name,const typename BasicJsonType::array_t & value)14772     void write_bson_array(const string_t& name,
14773                           const typename BasicJsonType::array_t& value)
14774     {
14775         write_bson_entry_header(name, 0x04); // array
14776         write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
14777 
14778         std::size_t array_index = 0ul;
14779 
14780         for (const auto& el : value)
14781         {
14782             write_bson_element(std::to_string(array_index++), el);
14783         }
14784 
14785         oa->write_character(to_char_type(0x00));
14786     }
14787 
14788     /*!
14789     @brief Writes a BSON element with key @a name and binary value @a value
14790     */
write_bson_binary(const string_t & name,const binary_t & value)14791     void write_bson_binary(const string_t& name,
14792                            const binary_t& value)
14793     {
14794         write_bson_entry_header(name, 0x05);
14795 
14796         write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
14797         write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : std::uint8_t(0x00));
14798 
14799         oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
14800     }
14801 
14802     /*!
14803     @brief Calculates the size necessary to serialize the JSON value @a j with its @a name
14804     @return The calculated size for the BSON document entry for @a j with the given @a name.
14805     */
calc_bson_element_size(const string_t & name,const BasicJsonType & j)14806     static std::size_t calc_bson_element_size(const string_t& name,
14807             const BasicJsonType& j)
14808     {
14809         const auto header_size = calc_bson_entry_header_size(name, j);
14810         switch (j.type())
14811         {
14812             case value_t::object:
14813                 return header_size + calc_bson_object_size(*j.m_value.object);
14814 
14815             case value_t::array:
14816                 return header_size + calc_bson_array_size(*j.m_value.array);
14817 
14818             case value_t::binary:
14819                 return header_size + calc_bson_binary_size(*j.m_value.binary);
14820 
14821             case value_t::boolean:
14822                 return header_size + 1ul;
14823 
14824             case value_t::number_float:
14825                 return header_size + 8ul;
14826 
14827             case value_t::number_integer:
14828                 return header_size + calc_bson_integer_size(j.m_value.number_integer);
14829 
14830             case value_t::number_unsigned:
14831                 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
14832 
14833             case value_t::string:
14834                 return header_size + calc_bson_string_size(*j.m_value.string);
14835 
14836             case value_t::null:
14837                 return header_size + 0ul;
14838 
14839             // LCOV_EXCL_START
14840             case value_t::discarded:
14841             default:
14842                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14843                 return 0ul;
14844                 // LCOV_EXCL_STOP
14845         }
14846     }
14847 
14848     /*!
14849     @brief Serializes the JSON value @a j to BSON and associates it with the
14850            key @a name.
14851     @param name The name to associate with the JSON entity @a j within the
14852                 current BSON document
14853     */
write_bson_element(const string_t & name,const BasicJsonType & j)14854     void write_bson_element(const string_t& name,
14855                             const BasicJsonType& j)
14856     {
14857         switch (j.type())
14858         {
14859             case value_t::object:
14860                 return write_bson_object_entry(name, *j.m_value.object);
14861 
14862             case value_t::array:
14863                 return write_bson_array(name, *j.m_value.array);
14864 
14865             case value_t::binary:
14866                 return write_bson_binary(name, *j.m_value.binary);
14867 
14868             case value_t::boolean:
14869                 return write_bson_boolean(name, j.m_value.boolean);
14870 
14871             case value_t::number_float:
14872                 return write_bson_double(name, j.m_value.number_float);
14873 
14874             case value_t::number_integer:
14875                 return write_bson_integer(name, j.m_value.number_integer);
14876 
14877             case value_t::number_unsigned:
14878                 return write_bson_unsigned(name, j);
14879 
14880             case value_t::string:
14881                 return write_bson_string(name, *j.m_value.string);
14882 
14883             case value_t::null:
14884                 return write_bson_null(name);
14885 
14886             // LCOV_EXCL_START
14887             case value_t::discarded:
14888             default:
14889                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14890                 return;
14891                 // LCOV_EXCL_STOP
14892         }
14893     }
14894 
14895     /*!
14896     @brief Calculates the size of the BSON serialization of the given
14897            JSON-object @a j.
14898     @param[in] value  JSON value to serialize
14899     @pre       value.type() == value_t::object
14900     */
calc_bson_object_size(const typename BasicJsonType::object_t & value)14901     static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14902     {
14903         std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
14904                                     [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14905         {
14906             return result += calc_bson_element_size(el.first, el.second);
14907         });
14908 
14909         return sizeof(std::int32_t) + document_size + 1ul;
14910     }
14911 
14912     /*!
14913     @param[in] value  JSON value to serialize
14914     @pre       value.type() == value_t::object
14915     */
write_bson_object(const typename BasicJsonType::object_t & value)14916     void write_bson_object(const typename BasicJsonType::object_t& value)
14917     {
14918         write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14919 
14920         for (const auto& el : value)
14921         {
14922             write_bson_element(el.first, el.second);
14923         }
14924 
14925         oa->write_character(to_char_type(0x00));
14926     }
14927 
14928     //////////
14929     // CBOR //
14930     //////////
14931 
get_cbor_float_prefix(float)14932     static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14933     {
14934         return to_char_type(0xFA);  // Single-Precision Float
14935     }
14936 
get_cbor_float_prefix(double)14937     static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14938     {
14939         return to_char_type(0xFB);  // Double-Precision Float
14940     }
14941 
14942     /////////////
14943     // MsgPack //
14944     /////////////
14945 
get_msgpack_float_prefix(float)14946     static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14947     {
14948         return to_char_type(0xCA);  // float 32
14949     }
14950 
get_msgpack_float_prefix(double)14951     static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14952     {
14953         return to_char_type(0xCB);  // float 64
14954     }
14955 
14956     ////////////
14957     // UBJSON //
14958     ////////////
14959 
14960     // UBJSON: write number (floating point)
14961     template<typename NumberType, typename std::enable_if<
14962                  std::is_floating_point<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)14963     void write_number_with_ubjson_prefix(const NumberType n,
14964                                          const bool add_prefix)
14965     {
14966         if (add_prefix)
14967         {
14968             oa->write_character(get_ubjson_float_prefix(n));
14969         }
14970         write_number(n);
14971     }
14972 
14973     // UBJSON: write number (unsigned integer)
14974     template<typename NumberType, typename std::enable_if<
14975                  std::is_unsigned<NumberType>::value, int>::type = 0>
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)14976     void write_number_with_ubjson_prefix(const NumberType n,
14977                                          const bool add_prefix)
14978     {
14979         if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14980         {
14981             if (add_prefix)
14982             {
14983                 oa->write_character(to_char_type('i'));  // int8
14984             }
14985             write_number(static_cast<std::uint8_t>(n));
14986         }
14987         else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14988         {
14989             if (add_prefix)
14990             {
14991                 oa->write_character(to_char_type('U'));  // uint8
14992             }
14993             write_number(static_cast<std::uint8_t>(n));
14994         }
14995         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14996         {
14997             if (add_prefix)
14998             {
14999                 oa->write_character(to_char_type('I'));  // int16
15000             }
15001             write_number(static_cast<std::int16_t>(n));
15002         }
15003         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15004         {
15005             if (add_prefix)
15006             {
15007                 oa->write_character(to_char_type('l'));  // int32
15008             }
15009             write_number(static_cast<std::int32_t>(n));
15010         }
15011         else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15012         {
15013             if (add_prefix)
15014             {
15015                 oa->write_character(to_char_type('L'));  // int64
15016             }
15017             write_number(static_cast<std::int64_t>(n));
15018         }
15019         else
15020         {
15021             if (add_prefix)
15022             {
15023                 oa->write_character(to_char_type('H'));  // high-precision number
15024             }
15025 
15026             const auto number = BasicJsonType(n).dump();
15027             write_number_with_ubjson_prefix(number.size(), true);
15028             for (std::size_t i = 0; i < number.size(); ++i)
15029             {
15030                 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15031             }
15032         }
15033     }
15034 
15035     // UBJSON: write number (signed integer)
15036     template < typename NumberType, typename std::enable_if <
15037                    std::is_signed<NumberType>::value&&
15038                    !std::is_floating_point<NumberType>::value, int >::type = 0 >
write_number_with_ubjson_prefix(const NumberType n,const bool add_prefix)15039     void write_number_with_ubjson_prefix(const NumberType n,
15040                                          const bool add_prefix)
15041     {
15042         if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
15043         {
15044             if (add_prefix)
15045             {
15046                 oa->write_character(to_char_type('i'));  // int8
15047             }
15048             write_number(static_cast<std::int8_t>(n));
15049         }
15050         else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
15051         {
15052             if (add_prefix)
15053             {
15054                 oa->write_character(to_char_type('U'));  // uint8
15055             }
15056             write_number(static_cast<std::uint8_t>(n));
15057         }
15058         else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
15059         {
15060             if (add_prefix)
15061             {
15062                 oa->write_character(to_char_type('I'));  // int16
15063             }
15064             write_number(static_cast<std::int16_t>(n));
15065         }
15066         else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
15067         {
15068             if (add_prefix)
15069             {
15070                 oa->write_character(to_char_type('l'));  // int32
15071             }
15072             write_number(static_cast<std::int32_t>(n));
15073         }
15074         else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
15075         {
15076             if (add_prefix)
15077             {
15078                 oa->write_character(to_char_type('L'));  // int64
15079             }
15080             write_number(static_cast<std::int64_t>(n));
15081         }
15082         // LCOV_EXCL_START
15083         else
15084         {
15085             if (add_prefix)
15086             {
15087                 oa->write_character(to_char_type('H'));  // high-precision number
15088             }
15089 
15090             const auto number = BasicJsonType(n).dump();
15091             write_number_with_ubjson_prefix(number.size(), true);
15092             for (std::size_t i = 0; i < number.size(); ++i)
15093             {
15094                 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15095             }
15096         }
15097         // LCOV_EXCL_STOP
15098     }
15099 
15100     /*!
15101     @brief determine the type prefix of container values
15102     */
ubjson_prefix(const BasicJsonType & j) const15103     CharType ubjson_prefix(const BasicJsonType& j) const noexcept
15104     {
15105         switch (j.type())
15106         {
15107             case value_t::null:
15108                 return 'Z';
15109 
15110             case value_t::boolean:
15111                 return j.m_value.boolean ? 'T' : 'F';
15112 
15113             case value_t::number_integer:
15114             {
15115                 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15116                 {
15117                     return 'i';
15118                 }
15119                 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15120                 {
15121                     return 'U';
15122                 }
15123                 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15124                 {
15125                     return 'I';
15126                 }
15127                 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15128                 {
15129                     return 'l';
15130                 }
15131                 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15132                 {
15133                     return 'L';
15134                 }
15135                 // anything else is treated as high-precision number
15136                 return 'H'; // LCOV_EXCL_LINE
15137             }
15138 
15139             case value_t::number_unsigned:
15140             {
15141                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15142                 {
15143                     return 'i';
15144                 }
15145                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15146                 {
15147                     return 'U';
15148                 }
15149                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15150                 {
15151                     return 'I';
15152                 }
15153                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15154                 {
15155                     return 'l';
15156                 }
15157                 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15158                 {
15159                     return 'L';
15160                 }
15161                 // anything else is treated as high-precision number
15162                 return 'H'; // LCOV_EXCL_LINE
15163             }
15164 
15165             case value_t::number_float:
15166                 return get_ubjson_float_prefix(j.m_value.number_float);
15167 
15168             case value_t::string:
15169                 return 'S';
15170 
15171             case value_t::array: // fallthrough
15172             case value_t::binary:
15173                 return '[';
15174 
15175             case value_t::object:
15176                 return '{';
15177 
15178             case value_t::discarded:
15179             default:  // discarded values
15180                 return 'N';
15181         }
15182     }
15183 
get_ubjson_float_prefix(float)15184     static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15185     {
15186         return 'd';  // float 32
15187     }
15188 
get_ubjson_float_prefix(double)15189     static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15190     {
15191         return 'D';  // float 64
15192     }
15193 
15194     ///////////////////////
15195     // Utility functions //
15196     ///////////////////////
15197 
15198     /*
15199     @brief write a number to output input
15200     @param[in] n number of type @a NumberType
15201     @tparam NumberType the type of the number
15202     @tparam OutputIsLittleEndian Set to true if output data is
15203                                  required to be little endian
15204 
15205     @note This function needs to respect the system's endianess, because bytes
15206           in CBOR, MessagePack, and UBJSON are stored in network order (big
15207           endian) and therefore need reordering on little endian systems.
15208     */
15209     template<typename NumberType, bool OutputIsLittleEndian = false>
write_number(const NumberType n)15210     void write_number(const NumberType n)
15211     {
15212         // step 1: write number to array of length NumberType
15213         std::array<CharType, sizeof(NumberType)> vec{};
15214         std::memcpy(vec.data(), &n, sizeof(NumberType));
15215 
15216         // step 2: write array to output (with possible reordering)
15217         if (is_little_endian != OutputIsLittleEndian)
15218         {
15219             // reverse byte order prior to conversion if necessary
15220             std::reverse(vec.begin(), vec.end());
15221         }
15222 
15223         oa->write_characters(vec.data(), sizeof(NumberType));
15224     }
15225 
write_compact_float(const number_float_t n,detail::input_format_t format)15226     void write_compact_float(const number_float_t n, detail::input_format_t format)
15227     {
15228 #ifdef __GNUC__
15229 #pragma GCC diagnostic push
15230 #pragma GCC diagnostic ignored "-Wfloat-equal"
15231 #endif
15232         if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
15233                 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
15234                 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
15235         {
15236             oa->write_character(format == detail::input_format_t::cbor
15237                                 ? get_cbor_float_prefix(static_cast<float>(n))
15238                                 : get_msgpack_float_prefix(static_cast<float>(n)));
15239             write_number(static_cast<float>(n));
15240         }
15241         else
15242         {
15243             oa->write_character(format == detail::input_format_t::cbor
15244                                 ? get_cbor_float_prefix(n)
15245                                 : get_msgpack_float_prefix(n));
15246             write_number(n);
15247         }
15248 #ifdef __GNUC__
15249 #pragma GCC diagnostic pop
15250 #endif
15251     }
15252 
15253   public:
15254     // The following to_char_type functions are implement the conversion
15255     // between uint8_t and CharType. In case CharType is not unsigned,
15256     // such a conversion is required to allow values greater than 128.
15257     // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
15258     template < typename C = CharType,
15259                enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
to_char_type(std::uint8_t x)15260     static constexpr CharType to_char_type(std::uint8_t x) noexcept
15261     {
15262         return *reinterpret_cast<char*>(&x);
15263     }
15264 
15265     template < typename C = CharType,
15266                enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
to_char_type(std::uint8_t x)15267     static CharType to_char_type(std::uint8_t x) noexcept
15268     {
15269         static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
15270         static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
15271         CharType result;
15272         std::memcpy(&result, &x, sizeof(x));
15273         return result;
15274     }
15275 
15276     template<typename C = CharType,
15277              enable_if_t<std::is_unsigned<C>::value>* = nullptr>
to_char_type(std::uint8_t x)15278     static constexpr CharType to_char_type(std::uint8_t x) noexcept
15279     {
15280         return x;
15281     }
15282 
15283     template < typename InputCharType, typename C = CharType,
15284                enable_if_t <
15285                    std::is_signed<C>::value &&
15286                    std::is_signed<char>::value &&
15287                    std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
15288                    > * = nullptr >
to_char_type(InputCharType x)15289     static constexpr CharType to_char_type(InputCharType x) noexcept
15290     {
15291         return x;
15292     }
15293 
15294   private:
15295     /// whether we can assume little endianess
15296     const bool is_little_endian = little_endianess();
15297 
15298     /// the output
15299     output_adapter_t<CharType> oa = nullptr;
15300 };
15301 }  // namespace detail
15302 }  // namespace nlohmann
15303 
15304 // #include <nlohmann/detail/output/output_adapters.hpp>
15305 
15306 // #include <nlohmann/detail/output/serializer.hpp>
15307 
15308 
15309 #include <algorithm> // reverse, remove, fill, find, none_of
15310 #include <array> // array
15311 #include <clocale> // localeconv, lconv
15312 #include <cmath> // labs, isfinite, isnan, signbit
15313 #include <cstddef> // size_t, ptrdiff_t
15314 #include <cstdint> // uint8_t
15315 #include <cstdio> // snprintf
15316 #include <limits> // numeric_limits
15317 #include <string> // string, char_traits
15318 #include <type_traits> // is_same
15319 #include <utility> // move
15320 
15321 // #include <nlohmann/detail/conversions/to_chars.hpp>
15322 
15323 
15324 #include <array> // array
15325 #include <cmath>   // signbit, isfinite
15326 #include <cstdint> // intN_t, uintN_t
15327 #include <cstring> // memcpy, memmove
15328 #include <limits> // numeric_limits
15329 #include <type_traits> // conditional
15330 
15331 // #include <nlohmann/detail/macro_scope.hpp>
15332 
15333 
15334 namespace nlohmann
15335 {
15336 namespace detail
15337 {
15338 
15339 /*!
15340 @brief implements the Grisu2 algorithm for binary to decimal floating-point
15341 conversion.
15342 
15343 This implementation is a slightly modified version of the reference
15344 implementation which may be obtained from
15345 http://florian.loitsch.com/publications (bench.tar.gz).
15346 
15347 The code is distributed under the MIT license, Copyright (c) 2009 Florian Loitsch.
15348 
15349 For a detailed description of the algorithm see:
15350 
15351 [1] Loitsch, "Printing Floating-Point Numbers Quickly and Accurately with
15352     Integers", Proceedings of the ACM SIGPLAN 2010 Conference on Programming
15353     Language Design and Implementation, PLDI 2010
15354 [2] Burger, Dybvig, "Printing Floating-Point Numbers Quickly and Accurately",
15355     Proceedings of the ACM SIGPLAN 1996 Conference on Programming Language
15356     Design and Implementation, PLDI 1996
15357 */
15358 namespace dtoa_impl
15359 {
15360 
15361 template<typename Target, typename Source>
15362 Target reinterpret_bits(const Source source)
15363 {
15364     static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
15365 
15366     Target target;
15367     std::memcpy(&target, &source, sizeof(Source));
15368     return target;
15369 }
15370 
15371 struct diyfp // f * 2^e
15372 {
15373     static constexpr int kPrecision = 64; // = q
15374 
15375     std::uint64_t f = 0;
15376     int e = 0;
15377 
diyfpnlohmann::detail::dtoa_impl::diyfp15378     constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
15379 
15380     /*!
15381     @brief returns x - y
15382     @pre x.e == y.e and x.f >= y.f
15383     */
subnlohmann::detail::dtoa_impl::diyfp15384     static diyfp sub(const diyfp& x, const diyfp& y) noexcept
15385     {
15386         JSON_ASSERT(x.e == y.e);
15387         JSON_ASSERT(x.f >= y.f);
15388 
15389         return {x.f - y.f, x.e};
15390     }
15391 
15392     /*!
15393     @brief returns x * y
15394     @note The result is rounded. (Only the upper q bits are returned.)
15395     */
mulnlohmann::detail::dtoa_impl::diyfp15396     static diyfp mul(const diyfp& x, const diyfp& y) noexcept
15397     {
15398         static_assert(kPrecision == 64, "internal error");
15399 
15400         // Computes:
15401         //  f = round((x.f * y.f) / 2^q)
15402         //  e = x.e + y.e + q
15403 
15404         // Emulate the 64-bit * 64-bit multiplication:
15405         //
15406         // p = u * v
15407         //   = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15408         //   = (u_lo v_lo         ) + 2^32 ((u_lo v_hi         ) + (u_hi v_lo         )) + 2^64 (u_hi v_hi         )
15409         //   = (p0                ) + 2^32 ((p1                ) + (p2                )) + 2^64 (p3                )
15410         //   = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3                )
15411         //   = (p0_lo             ) + 2^32 (p0_hi + p1_lo + p2_lo                      ) + 2^64 (p1_hi + p2_hi + p3)
15412         //   = (p0_lo             ) + 2^32 (Q                                          ) + 2^64 (H                 )
15413         //   = (p0_lo             ) + 2^32 (Q_lo + 2^32 Q_hi                           ) + 2^64 (H                 )
15414         //
15415         // (Since Q might be larger than 2^32 - 1)
15416         //
15417         //   = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15418         //
15419         // (Q_hi + H does not overflow a 64-bit int)
15420         //
15421         //   = p_lo + 2^64 p_hi
15422 
15423         const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15424         const std::uint64_t u_hi = x.f >> 32u;
15425         const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15426         const std::uint64_t v_hi = y.f >> 32u;
15427 
15428         const std::uint64_t p0 = u_lo * v_lo;
15429         const std::uint64_t p1 = u_lo * v_hi;
15430         const std::uint64_t p2 = u_hi * v_lo;
15431         const std::uint64_t p3 = u_hi * v_hi;
15432 
15433         const std::uint64_t p0_hi = p0 >> 32u;
15434         const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15435         const std::uint64_t p1_hi = p1 >> 32u;
15436         const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15437         const std::uint64_t p2_hi = p2 >> 32u;
15438 
15439         std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15440 
15441         // The full product might now be computed as
15442         //
15443         // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
15444         // p_lo = p0_lo + (Q << 32)
15445         //
15446         // But in this particular case here, the full p_lo is not required.
15447         // Effectively we only need to add the highest bit in p_lo to p_hi (and
15448         // Q_hi + 1 does not overflow).
15449 
15450         Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
15451 
15452         const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15453 
15454         return {h, x.e + y.e + 64};
15455     }
15456 
15457     /*!
15458     @brief normalize x such that the significand is >= 2^(q-1)
15459     @pre x.f != 0
15460     */
normalizenlohmann::detail::dtoa_impl::diyfp15461     static diyfp normalize(diyfp x) noexcept
15462     {
15463         JSON_ASSERT(x.f != 0);
15464 
15465         while ((x.f >> 63u) == 0)
15466         {
15467             x.f <<= 1u;
15468             x.e--;
15469         }
15470 
15471         return x;
15472     }
15473 
15474     /*!
15475     @brief normalize x such that the result has the exponent E
15476     @pre e >= x.e and the upper e - x.e bits of x.f must be zero.
15477     */
normalize_tonlohmann::detail::dtoa_impl::diyfp15478     static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
15479     {
15480         const int delta = x.e - target_exponent;
15481 
15482         JSON_ASSERT(delta >= 0);
15483         JSON_ASSERT(((x.f << delta) >> delta) == x.f);
15484 
15485         return {x.f << delta, target_exponent};
15486     }
15487 };
15488 
15489 struct boundaries
15490 {
15491     diyfp w;
15492     diyfp minus;
15493     diyfp plus;
15494 };
15495 
15496 /*!
15497 Compute the (normalized) diyfp representing the input number 'value' and its
15498 boundaries.
15499 
15500 @pre value must be finite and positive
15501 */
15502 template<typename FloatType>
compute_boundaries(FloatType value)15503 boundaries compute_boundaries(FloatType value)
15504 {
15505     JSON_ASSERT(std::isfinite(value));
15506     JSON_ASSERT(value > 0);
15507 
15508     // Convert the IEEE representation into a diyfp.
15509     //
15510     // If v is denormal:
15511     //      value = 0.F * 2^(1 - bias) = (          F) * 2^(1 - bias - (p-1))
15512     // If v is normalized:
15513     //      value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
15514 
15515     static_assert(std::numeric_limits<FloatType>::is_iec559,
15516                   "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
15517 
15518     constexpr int      kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
15519     constexpr int      kBias      = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
15520     constexpr int      kMinExp    = 1 - kBias;
15521     constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
15522 
15523     using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
15524 
15525     const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
15526     const std::uint64_t E = bits >> (kPrecision - 1);
15527     const std::uint64_t F = bits & (kHiddenBit - 1);
15528 
15529     const bool is_denormal = E == 0;
15530     const diyfp v = is_denormal
15531                     ? diyfp(F, kMinExp)
15532                     : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
15533 
15534     // Compute the boundaries m- and m+ of the floating-point value
15535     // v = f * 2^e.
15536     //
15537     // Determine v- and v+, the floating-point predecessor and successor if v,
15538     // respectively.
15539     //
15540     //      v- = v - 2^e        if f != 2^(p-1) or e == e_min                (A)
15541     //         = v - 2^(e-1)    if f == 2^(p-1) and e > e_min                (B)
15542     //
15543     //      v+ = v + 2^e
15544     //
15545     // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
15546     // between m- and m+ round to v, regardless of how the input rounding
15547     // algorithm breaks ties.
15548     //
15549     //      ---+-------------+-------------+-------------+-------------+---  (A)
15550     //         v-            m-            v             m+            v+
15551     //
15552     //      -----------------+------+------+-------------+-------------+---  (B)
15553     //                       v-     m-     v             m+            v+
15554 
15555     const bool lower_boundary_is_closer = F == 0 && E > 1;
15556     const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
15557     const diyfp m_minus = lower_boundary_is_closer
15558                           ? diyfp(4 * v.f - 1, v.e - 2)  // (B)
15559                           : diyfp(2 * v.f - 1, v.e - 1); // (A)
15560 
15561     // Determine the normalized w+ = m+.
15562     const diyfp w_plus = diyfp::normalize(m_plus);
15563 
15564     // Determine w- = m- such that e_(w-) = e_(w+).
15565     const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
15566 
15567     return {diyfp::normalize(v), w_minus, w_plus};
15568 }
15569 
15570 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
15571 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
15572 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
15573 //
15574 //      alpha <= e = e_c + e_w + q <= gamma
15575 //
15576 // or
15577 //
15578 //      f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
15579 //                          <= f_c * f_w * 2^gamma
15580 //
15581 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
15582 //
15583 //      2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
15584 //
15585 // or
15586 //
15587 //      2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
15588 //
15589 // The choice of (alpha,gamma) determines the size of the table and the form of
15590 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
15591 // in practice:
15592 //
15593 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
15594 // processed independently: An integral part p1, and a fractional part p2:
15595 //
15596 //      f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
15597 //              = (f div 2^-e) + (f mod 2^-e) * 2^e
15598 //              = p1 + p2 * 2^e
15599 //
15600 // The conversion of p1 into decimal form requires a series of divisions and
15601 // modulos by (a power of) 10. These operations are faster for 32-bit than for
15602 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
15603 // achieved by choosing
15604 //
15605 //      -e >= 32   or   e <= -32 := gamma
15606 //
15607 // In order to convert the fractional part
15608 //
15609 //      p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
15610 //
15611 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
15612 // d[-i] are extracted in order:
15613 //
15614 //      (10 * p2) div 2^-e = d[-1]
15615 //      (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
15616 //
15617 // The multiplication by 10 must not overflow. It is sufficient to choose
15618 //
15619 //      10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
15620 //
15621 // Since p2 = f mod 2^-e < 2^-e,
15622 //
15623 //      -e <= 60   or   e >= -60 := alpha
15624 
15625 constexpr int kAlpha = -60;
15626 constexpr int kGamma = -32;
15627 
15628 struct cached_power // c = f * 2^e ~= 10^k
15629 {
15630     std::uint64_t f;
15631     int e;
15632     int k;
15633 };
15634 
15635 /*!
15636 For a normalized diyfp w = f * 2^e, this function returns a (normalized) cached
15637 power-of-ten c = f_c * 2^e_c, such that the exponent of the product w * c
15638 satisfies (Definition 3.2 from [1])
15639 
15640      alpha <= e_c + e + q <= gamma.
15641 */
get_cached_power_for_binary_exponent(int e)15642 inline cached_power get_cached_power_for_binary_exponent(int e)
15643 {
15644     // Now
15645     //
15646     //      alpha <= e_c + e + q <= gamma                                    (1)
15647     //      ==> f_c * 2^alpha <= c * 2^e * 2^q
15648     //
15649     // and since the c's are normalized, 2^(q-1) <= f_c,
15650     //
15651     //      ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
15652     //      ==> 2^(alpha - e - 1) <= c
15653     //
15654     // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
15655     //
15656     //      k = ceil( log_10( 2^(alpha - e - 1) ) )
15657     //        = ceil( (alpha - e - 1) * log_10(2) )
15658     //
15659     // From the paper:
15660     // "In theory the result of the procedure could be wrong since c is rounded,
15661     //  and the computation itself is approximated [...]. In practice, however,
15662     //  this simple function is sufficient."
15663     //
15664     // For IEEE double precision floating-point numbers converted into
15665     // normalized diyfp's w = f * 2^e, with q = 64,
15666     //
15667     //      e >= -1022      (min IEEE exponent)
15668     //           -52        (p - 1)
15669     //           -52        (p - 1, possibly normalize denormal IEEE numbers)
15670     //           -11        (normalize the diyfp)
15671     //         = -1137
15672     //
15673     // and
15674     //
15675     //      e <= +1023      (max IEEE exponent)
15676     //           -52        (p - 1)
15677     //           -11        (normalize the diyfp)
15678     //         = 960
15679     //
15680     // This binary exponent range [-1137,960] results in a decimal exponent
15681     // range [-307,324]. One does not need to store a cached power for each
15682     // k in this range. For each such k it suffices to find a cached power
15683     // such that the exponent of the product lies in [alpha,gamma].
15684     // This implies that the difference of the decimal exponents of adjacent
15685     // table entries must be less than or equal to
15686     //
15687     //      floor( (gamma - alpha) * log_10(2) ) = 8.
15688     //
15689     // (A smaller distance gamma-alpha would require a larger table.)
15690 
15691     // NB:
15692     // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
15693 
15694     constexpr int kCachedPowersMinDecExp = -300;
15695     constexpr int kCachedPowersDecStep = 8;
15696 
15697     static constexpr std::array<cached_power, 79> kCachedPowers =
15698     {
15699         {
15700             { 0xAB70FE17C79AC6CA, -1060, -300 },
15701             { 0xFF77B1FCBEBCDC4F, -1034, -292 },
15702             { 0xBE5691EF416BD60C, -1007, -284 },
15703             { 0x8DD01FAD907FFC3C,  -980, -276 },
15704             { 0xD3515C2831559A83,  -954, -268 },
15705             { 0x9D71AC8FADA6C9B5,  -927, -260 },
15706             { 0xEA9C227723EE8BCB,  -901, -252 },
15707             { 0xAECC49914078536D,  -874, -244 },
15708             { 0x823C12795DB6CE57,  -847, -236 },
15709             { 0xC21094364DFB5637,  -821, -228 },
15710             { 0x9096EA6F3848984F,  -794, -220 },
15711             { 0xD77485CB25823AC7,  -768, -212 },
15712             { 0xA086CFCD97BF97F4,  -741, -204 },
15713             { 0xEF340A98172AACE5,  -715, -196 },
15714             { 0xB23867FB2A35B28E,  -688, -188 },
15715             { 0x84C8D4DFD2C63F3B,  -661, -180 },
15716             { 0xC5DD44271AD3CDBA,  -635, -172 },
15717             { 0x936B9FCEBB25C996,  -608, -164 },
15718             { 0xDBAC6C247D62A584,  -582, -156 },
15719             { 0xA3AB66580D5FDAF6,  -555, -148 },
15720             { 0xF3E2F893DEC3F126,  -529, -140 },
15721             { 0xB5B5ADA8AAFF80B8,  -502, -132 },
15722             { 0x87625F056C7C4A8B,  -475, -124 },
15723             { 0xC9BCFF6034C13053,  -449, -116 },
15724             { 0x964E858C91BA2655,  -422, -108 },
15725             { 0xDFF9772470297EBD,  -396, -100 },
15726             { 0xA6DFBD9FB8E5B88F,  -369,  -92 },
15727             { 0xF8A95FCF88747D94,  -343,  -84 },
15728             { 0xB94470938FA89BCF,  -316,  -76 },
15729             { 0x8A08F0F8BF0F156B,  -289,  -68 },
15730             { 0xCDB02555653131B6,  -263,  -60 },
15731             { 0x993FE2C6D07B7FAC,  -236,  -52 },
15732             { 0xE45C10C42A2B3B06,  -210,  -44 },
15733             { 0xAA242499697392D3,  -183,  -36 },
15734             { 0xFD87B5F28300CA0E,  -157,  -28 },
15735             { 0xBCE5086492111AEB,  -130,  -20 },
15736             { 0x8CBCCC096F5088CC,  -103,  -12 },
15737             { 0xD1B71758E219652C,   -77,   -4 },
15738             { 0x9C40000000000000,   -50,    4 },
15739             { 0xE8D4A51000000000,   -24,   12 },
15740             { 0xAD78EBC5AC620000,     3,   20 },
15741             { 0x813F3978F8940984,    30,   28 },
15742             { 0xC097CE7BC90715B3,    56,   36 },
15743             { 0x8F7E32CE7BEA5C70,    83,   44 },
15744             { 0xD5D238A4ABE98068,   109,   52 },
15745             { 0x9F4F2726179A2245,   136,   60 },
15746             { 0xED63A231D4C4FB27,   162,   68 },
15747             { 0xB0DE65388CC8ADA8,   189,   76 },
15748             { 0x83C7088E1AAB65DB,   216,   84 },
15749             { 0xC45D1DF942711D9A,   242,   92 },
15750             { 0x924D692CA61BE758,   269,  100 },
15751             { 0xDA01EE641A708DEA,   295,  108 },
15752             { 0xA26DA3999AEF774A,   322,  116 },
15753             { 0xF209787BB47D6B85,   348,  124 },
15754             { 0xB454E4A179DD1877,   375,  132 },
15755             { 0x865B86925B9BC5C2,   402,  140 },
15756             { 0xC83553C5C8965D3D,   428,  148 },
15757             { 0x952AB45CFA97A0B3,   455,  156 },
15758             { 0xDE469FBD99A05FE3,   481,  164 },
15759             { 0xA59BC234DB398C25,   508,  172 },
15760             { 0xF6C69A72A3989F5C,   534,  180 },
15761             { 0xB7DCBF5354E9BECE,   561,  188 },
15762             { 0x88FCF317F22241E2,   588,  196 },
15763             { 0xCC20CE9BD35C78A5,   614,  204 },
15764             { 0x98165AF37B2153DF,   641,  212 },
15765             { 0xE2A0B5DC971F303A,   667,  220 },
15766             { 0xA8D9D1535CE3B396,   694,  228 },
15767             { 0xFB9B7CD9A4A7443C,   720,  236 },
15768             { 0xBB764C4CA7A44410,   747,  244 },
15769             { 0x8BAB8EEFB6409C1A,   774,  252 },
15770             { 0xD01FEF10A657842C,   800,  260 },
15771             { 0x9B10A4E5E9913129,   827,  268 },
15772             { 0xE7109BFBA19C0C9D,   853,  276 },
15773             { 0xAC2820D9623BF429,   880,  284 },
15774             { 0x80444B5E7AA7CF85,   907,  292 },
15775             { 0xBF21E44003ACDD2D,   933,  300 },
15776             { 0x8E679C2F5E44FF8F,   960,  308 },
15777             { 0xD433179D9C8CB841,   986,  316 },
15778             { 0x9E19DB92B4E31BA9,  1013,  324 },
15779         }
15780     };
15781 
15782     // This computation gives exactly the same results for k as
15783     //      k = ceil((kAlpha - e - 1) * 0.30102999566398114)
15784     // for |e| <= 1500, but doesn't require floating-point operations.
15785     // NB: log_10(2) ~= 78913 / 2^18
15786     JSON_ASSERT(e >= -1500);
15787     JSON_ASSERT(e <=  1500);
15788     const int f = kAlpha - e - 1;
15789     const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
15790 
15791     const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
15792     JSON_ASSERT(index >= 0);
15793     JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
15794 
15795     const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
15796     JSON_ASSERT(kAlpha <= cached.e + e + 64);
15797     JSON_ASSERT(kGamma >= cached.e + e + 64);
15798 
15799     return cached;
15800 }
15801 
15802 /*!
15803 For n != 0, returns k, such that pow10 := 10^(k-1) <= n < 10^k.
15804 For n == 0, returns 1 and sets pow10 := 1.
15805 */
find_largest_pow10(const std::uint32_t n,std::uint32_t & pow10)15806 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
15807 {
15808     // LCOV_EXCL_START
15809     if (n >= 1000000000)
15810     {
15811         pow10 = 1000000000;
15812         return 10;
15813     }
15814     // LCOV_EXCL_STOP
15815     if (n >= 100000000)
15816     {
15817         pow10 = 100000000;
15818         return  9;
15819     }
15820     if (n >= 10000000)
15821     {
15822         pow10 = 10000000;
15823         return  8;
15824     }
15825     if (n >= 1000000)
15826     {
15827         pow10 = 1000000;
15828         return  7;
15829     }
15830     if (n >= 100000)
15831     {
15832         pow10 = 100000;
15833         return  6;
15834     }
15835     if (n >= 10000)
15836     {
15837         pow10 = 10000;
15838         return  5;
15839     }
15840     if (n >= 1000)
15841     {
15842         pow10 = 1000;
15843         return  4;
15844     }
15845     if (n >= 100)
15846     {
15847         pow10 = 100;
15848         return  3;
15849     }
15850     if (n >= 10)
15851     {
15852         pow10 = 10;
15853         return  2;
15854     }
15855 
15856     pow10 = 1;
15857     return 1;
15858 }
15859 
grisu2_round(char * buf,int len,std::uint64_t dist,std::uint64_t delta,std::uint64_t rest,std::uint64_t ten_k)15860 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
15861                          std::uint64_t rest, std::uint64_t ten_k)
15862 {
15863     JSON_ASSERT(len >= 1);
15864     JSON_ASSERT(dist <= delta);
15865     JSON_ASSERT(rest <= delta);
15866     JSON_ASSERT(ten_k > 0);
15867 
15868     //               <--------------------------- delta ---->
15869     //                                  <---- dist --------->
15870     // --------------[------------------+-------------------]--------------
15871     //               M-                 w                   M+
15872     //
15873     //                                  ten_k
15874     //                                <------>
15875     //                                       <---- rest ---->
15876     // --------------[------------------+----+--------------]--------------
15877     //                                  w    V
15878     //                                       = buf * 10^k
15879     //
15880     // ten_k represents a unit-in-the-last-place in the decimal representation
15881     // stored in buf.
15882     // Decrement buf by ten_k while this takes buf closer to w.
15883 
15884     // The tests are written in this order to avoid overflow in unsigned
15885     // integer arithmetic.
15886 
15887     while (rest < dist
15888             && delta - rest >= ten_k
15889             && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
15890     {
15891         JSON_ASSERT(buf[len - 1] != '0');
15892         buf[len - 1]--;
15893         rest += ten_k;
15894     }
15895 }
15896 
15897 /*!
15898 Generates V = buffer * 10^decimal_exponent, such that M- <= V <= M+.
15899 M- and M+ must be normalized and share the same exponent -60 <= e <= -32.
15900 */
grisu2_digit_gen(char * buffer,int & length,int & decimal_exponent,diyfp M_minus,diyfp w,diyfp M_plus)15901 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
15902                              diyfp M_minus, diyfp w, diyfp M_plus)
15903 {
15904     static_assert(kAlpha >= -60, "internal error");
15905     static_assert(kGamma <= -32, "internal error");
15906 
15907     // Generates the digits (and the exponent) of a decimal floating-point
15908     // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15909     // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15910     //
15911     //               <--------------------------- delta ---->
15912     //                                  <---- dist --------->
15913     // --------------[------------------+-------------------]--------------
15914     //               M-                 w                   M+
15915     //
15916     // Grisu2 generates the digits of M+ from left to right and stops as soon as
15917     // V is in [M-,M+].
15918 
15919     JSON_ASSERT(M_plus.e >= kAlpha);
15920     JSON_ASSERT(M_plus.e <= kGamma);
15921 
15922     std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15923     std::uint64_t dist  = diyfp::sub(M_plus, w      ).f; // (significand of (M+ - w ), implicit exponent is e)
15924 
15925     // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15926     //
15927     //      M+ = f * 2^e
15928     //         = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15929     //         = ((p1        ) * 2^-e + (p2        )) * 2^e
15930     //         = p1 + p2 * 2^e
15931 
15932     const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15933 
15934     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.)
15935     std::uint64_t p2 = M_plus.f & (one.f - 1);                    // p2 = f mod 2^-e
15936 
15937     // 1)
15938     //
15939     // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15940 
15941     JSON_ASSERT(p1 > 0);
15942 
15943     std::uint32_t pow10{};
15944     const int k = find_largest_pow10(p1, pow10);
15945 
15946     //      10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15947     //
15948     //      p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15949     //         = (d[k-1]         ) * 10^(k-1) + (p1 mod 10^(k-1))
15950     //
15951     //      M+ = p1                                             + p2 * 2^e
15952     //         = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1))          + p2 * 2^e
15953     //         = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15954     //         = d[k-1] * 10^(k-1) + (                         rest) * 2^e
15955     //
15956     // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15957     //
15958     //      p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15959     //
15960     // but stop as soon as
15961     //
15962     //      rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15963 
15964     int n = k;
15965     while (n > 0)
15966     {
15967         // Invariants:
15968         //      M+ = buffer * 10^n + (p1 + p2 * 2^e)    (buffer = 0 for n = k)
15969         //      pow10 = 10^(n-1) <= p1 < 10^n
15970         //
15971         const std::uint32_t d = p1 / pow10;  // d = p1 div 10^(n-1)
15972         const std::uint32_t r = p1 % pow10;  // r = p1 mod 10^(n-1)
15973         //
15974         //      M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15975         //         = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15976         //
15977         JSON_ASSERT(d <= 9);
15978         buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15979         //
15980         //      M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15981         //
15982         p1 = r;
15983         n--;
15984         //
15985         //      M+ = buffer * 10^n + (p1 + p2 * 2^e)
15986         //      pow10 = 10^n
15987         //
15988 
15989         // Now check if enough digits have been generated.
15990         // Compute
15991         //
15992         //      p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15993         //
15994         // Note:
15995         // Since rest and delta share the same exponent e, it suffices to
15996         // compare the significands.
15997         const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15998         if (rest <= delta)
15999         {
16000             // V = buffer * 10^n, with M- <= V <= M+.
16001 
16002             decimal_exponent += n;
16003 
16004             // We may now just stop. But instead look if the buffer could be
16005             // decremented to bring V closer to w.
16006             //
16007             // pow10 = 10^n is now 1 ulp in the decimal representation V.
16008             // The rounding procedure works with diyfp's with an implicit
16009             // exponent of e.
16010             //
16011             //      10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
16012             //
16013             const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
16014             grisu2_round(buffer, length, dist, delta, rest, ten_n);
16015 
16016             return;
16017         }
16018 
16019         pow10 /= 10;
16020         //
16021         //      pow10 = 10^(n-1) <= p1 < 10^n
16022         // Invariants restored.
16023     }
16024 
16025     // 2)
16026     //
16027     // The digits of the integral part have been generated:
16028     //
16029     //      M+ = d[k-1]...d[1]d[0] + p2 * 2^e
16030     //         = buffer            + p2 * 2^e
16031     //
16032     // Now generate the digits of the fractional part p2 * 2^e.
16033     //
16034     // Note:
16035     // No decimal point is generated: the exponent is adjusted instead.
16036     //
16037     // p2 actually represents the fraction
16038     //
16039     //      p2 * 2^e
16040     //          = p2 / 2^-e
16041     //          = d[-1] / 10^1 + d[-2] / 10^2 + ...
16042     //
16043     // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
16044     //
16045     //      p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
16046     //                      + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
16047     //
16048     // using
16049     //
16050     //      10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
16051     //                = (                   d) * 2^-e + (                   r)
16052     //
16053     // or
16054     //      10^m * p2 * 2^e = d + r * 2^e
16055     //
16056     // i.e.
16057     //
16058     //      M+ = buffer + p2 * 2^e
16059     //         = buffer + 10^-m * (d + r * 2^e)
16060     //         = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
16061     //
16062     // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
16063 
16064     JSON_ASSERT(p2 > delta);
16065 
16066     int m = 0;
16067     for (;;)
16068     {
16069         // Invariant:
16070         //      M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
16071         //         = buffer * 10^-m + 10^-m * (p2                                 ) * 2^e
16072         //         = buffer * 10^-m + 10^-m * (1/10 * (10 * p2)                   ) * 2^e
16073         //         = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
16074         //
16075         JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
16076         p2 *= 10;
16077         const std::uint64_t d = p2 >> -one.e;     // d = (10 * p2) div 2^-e
16078         const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
16079         //
16080         //      M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
16081         //         = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
16082         //         = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
16083         //
16084         JSON_ASSERT(d <= 9);
16085         buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16086         //
16087         //      M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
16088         //
16089         p2 = r;
16090         m++;
16091         //
16092         //      M+ = buffer * 10^-m + 10^-m * p2 * 2^e
16093         // Invariant restored.
16094 
16095         // Check if enough digits have been generated.
16096         //
16097         //      10^-m * p2 * 2^e <= delta * 2^e
16098         //              p2 * 2^e <= 10^m * delta * 2^e
16099         //                    p2 <= 10^m * delta
16100         delta *= 10;
16101         dist  *= 10;
16102         if (p2 <= delta)
16103         {
16104             break;
16105         }
16106     }
16107 
16108     // V = buffer * 10^-m, with M- <= V <= M+.
16109 
16110     decimal_exponent -= m;
16111 
16112     // 1 ulp in the decimal representation is now 10^-m.
16113     // Since delta and dist are now scaled by 10^m, we need to do the
16114     // same with ulp in order to keep the units in sync.
16115     //
16116     //      10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16117     //
16118     const std::uint64_t ten_m = one.f;
16119     grisu2_round(buffer, length, dist, delta, p2, ten_m);
16120 
16121     // By construction this algorithm generates the shortest possible decimal
16122     // number (Loitsch, Theorem 6.2) which rounds back to w.
16123     // For an input number of precision p, at least
16124     //
16125     //      N = 1 + ceil(p * log_10(2))
16126     //
16127     // decimal digits are sufficient to identify all binary floating-point
16128     // numbers (Matula, "In-and-Out conversions").
16129     // This implies that the algorithm does not produce more than N decimal
16130     // digits.
16131     //
16132     //      N = 17 for p = 53 (IEEE double precision)
16133     //      N = 9  for p = 24 (IEEE single precision)
16134 }
16135 
16136 /*!
16137 v = buf * 10^decimal_exponent
16138 len is the length of the buffer (number of decimal digits)
16139 The buffer must be large enough, i.e. >= max_digits10.
16140 */
16141 JSON_HEDLEY_NON_NULL(1)
grisu2(char * buf,int & len,int & decimal_exponent,diyfp m_minus,diyfp v,diyfp m_plus)16142 inline void grisu2(char* buf, int& len, int& decimal_exponent,
16143                    diyfp m_minus, diyfp v, diyfp m_plus)
16144 {
16145     JSON_ASSERT(m_plus.e == m_minus.e);
16146     JSON_ASSERT(m_plus.e == v.e);
16147 
16148     //  --------(-----------------------+-----------------------)--------    (A)
16149     //          m-                      v                       m+
16150     //
16151     //  --------------------(-----------+-----------------------)--------    (B)
16152     //                      m-          v                       m+
16153     //
16154     // First scale v (and m- and m+) such that the exponent is in the range
16155     // [alpha, gamma].
16156 
16157     const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
16158 
16159     const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
16160 
16161     // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
16162     const diyfp w       = diyfp::mul(v,       c_minus_k);
16163     const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
16164     const diyfp w_plus  = diyfp::mul(m_plus,  c_minus_k);
16165 
16166     //  ----(---+---)---------------(---+---)---------------(---+---)----
16167     //          w-                      w                       w+
16168     //          = c*m-                  = c*v                   = c*m+
16169     //
16170     // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
16171     // w+ are now off by a small amount.
16172     // In fact:
16173     //
16174     //      w - v * 10^k < 1 ulp
16175     //
16176     // To account for this inaccuracy, add resp. subtract 1 ulp.
16177     //
16178     //  --------+---[---------------(---+---)---------------]---+--------
16179     //          w-  M-                  w                   M+  w+
16180     //
16181     // Now any number in [M-, M+] (bounds included) will round to w when input,
16182     // regardless of how the input rounding algorithm breaks ties.
16183     //
16184     // And digit_gen generates the shortest possible such number in [M-, M+].
16185     // Note that this does not mean that Grisu2 always generates the shortest
16186     // possible number in the interval (m-, m+).
16187     const diyfp M_minus(w_minus.f + 1, w_minus.e);
16188     const diyfp M_plus (w_plus.f  - 1, w_plus.e );
16189 
16190     decimal_exponent = -cached.k; // = -(-k) = k
16191 
16192     grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
16193 }
16194 
16195 /*!
16196 v = buf * 10^decimal_exponent
16197 len is the length of the buffer (number of decimal digits)
16198 The buffer must be large enough, i.e. >= max_digits10.
16199 */
16200 template<typename FloatType>
16201 JSON_HEDLEY_NON_NULL(1)
grisu2(char * buf,int & len,int & decimal_exponent,FloatType value)16202 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
16203 {
16204     static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
16205                   "internal error: not enough precision");
16206 
16207     JSON_ASSERT(std::isfinite(value));
16208     JSON_ASSERT(value > 0);
16209 
16210     // If the neighbors (and boundaries) of 'value' are always computed for double-precision
16211     // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
16212     // decimal representations are not exactly "short".
16213     //
16214     // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
16215     // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
16216     // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
16217     // does.
16218     // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
16219     // representation using the corresponding std::from_chars function recovers value exactly". That
16220     // indicates that single precision floating-point numbers should be recovered using
16221     // 'std::strtof'.
16222     //
16223     // NB: If the neighbors are computed for single-precision numbers, there is a single float
16224     //     (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
16225     //     value is off by 1 ulp.
16226 #if 0
16227     const boundaries w = compute_boundaries(static_cast<double>(value));
16228 #else
16229     const boundaries w = compute_boundaries(value);
16230 #endif
16231 
16232     grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
16233 }
16234 
16235 /*!
16236 @brief appends a decimal representation of e to buf
16237 @return a pointer to the element following the exponent.
16238 @pre -1000 < e < 1000
16239 */
16240 JSON_HEDLEY_NON_NULL(1)
16241 JSON_HEDLEY_RETURNS_NON_NULL
append_exponent(char * buf,int e)16242 inline char* append_exponent(char* buf, int e)
16243 {
16244     JSON_ASSERT(e > -1000);
16245     JSON_ASSERT(e <  1000);
16246 
16247     if (e < 0)
16248     {
16249         e = -e;
16250         *buf++ = '-';
16251     }
16252     else
16253     {
16254         *buf++ = '+';
16255     }
16256 
16257     auto k = static_cast<std::uint32_t>(e);
16258     if (k < 10)
16259     {
16260         // Always print at least two digits in the exponent.
16261         // This is for compatibility with printf("%g").
16262         *buf++ = '0';
16263         *buf++ = static_cast<char>('0' + k);
16264     }
16265     else if (k < 100)
16266     {
16267         *buf++ = static_cast<char>('0' + k / 10);
16268         k %= 10;
16269         *buf++ = static_cast<char>('0' + k);
16270     }
16271     else
16272     {
16273         *buf++ = static_cast<char>('0' + k / 100);
16274         k %= 100;
16275         *buf++ = static_cast<char>('0' + k / 10);
16276         k %= 10;
16277         *buf++ = static_cast<char>('0' + k);
16278     }
16279 
16280     return buf;
16281 }
16282 
16283 /*!
16284 @brief prettify v = buf * 10^decimal_exponent
16285 
16286 If v is in the range [10^min_exp, 10^max_exp) it will be printed in fixed-point
16287 notation. Otherwise it will be printed in exponential notation.
16288 
16289 @pre min_exp < 0
16290 @pre max_exp > 0
16291 */
16292 JSON_HEDLEY_NON_NULL(1)
16293 JSON_HEDLEY_RETURNS_NON_NULL
format_buffer(char * buf,int len,int decimal_exponent,int min_exp,int max_exp)16294 inline char* format_buffer(char* buf, int len, int decimal_exponent,
16295                            int min_exp, int max_exp)
16296 {
16297     JSON_ASSERT(min_exp < 0);
16298     JSON_ASSERT(max_exp > 0);
16299 
16300     const int k = len;
16301     const int n = len + decimal_exponent;
16302 
16303     // v = buf * 10^(n-k)
16304     // k is the length of the buffer (number of decimal digits)
16305     // n is the position of the decimal point relative to the start of the buffer.
16306 
16307     if (k <= n && n <= max_exp)
16308     {
16309         // digits[000]
16310         // len <= max_exp + 2
16311 
16312         std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
16313         // Make it look like a floating-point number (#362, #378)
16314         buf[n + 0] = '.';
16315         buf[n + 1] = '0';
16316         return buf + (static_cast<size_t>(n) + 2);
16317     }
16318 
16319     if (0 < n && n <= max_exp)
16320     {
16321         // dig.its
16322         // len <= max_digits10 + 1
16323 
16324         JSON_ASSERT(k > n);
16325 
16326         std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
16327         buf[n] = '.';
16328         return buf + (static_cast<size_t>(k) + 1U);
16329     }
16330 
16331     if (min_exp < n && n <= 0)
16332     {
16333         // 0.[000]digits
16334         // len <= 2 + (-min_exp - 1) + max_digits10
16335 
16336         std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
16337         buf[0] = '0';
16338         buf[1] = '.';
16339         std::memset(buf + 2, '0', static_cast<size_t>(-n));
16340         return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
16341     }
16342 
16343     if (k == 1)
16344     {
16345         // dE+123
16346         // len <= 1 + 5
16347 
16348         buf += 1;
16349     }
16350     else
16351     {
16352         // d.igitsE+123
16353         // len <= max_digits10 + 1 + 5
16354 
16355         std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
16356         buf[1] = '.';
16357         buf += 1 + static_cast<size_t>(k);
16358     }
16359 
16360     *buf++ = 'e';
16361     return append_exponent(buf, n - 1);
16362 }
16363 
16364 } // namespace dtoa_impl
16365 
16366 /*!
16367 @brief generates a decimal representation of the floating-point number value in [first, last).
16368 
16369 The format of the resulting decimal representation is similar to printf's %g
16370 format. Returns an iterator pointing past-the-end of the decimal representation.
16371 
16372 @note The input number must be finite, i.e. NaN's and Inf's are not supported.
16373 @note The buffer must be large enough.
16374 @note The result is NOT null-terminated.
16375 */
16376 template<typename FloatType>
16377 JSON_HEDLEY_NON_NULL(1, 2)
16378 JSON_HEDLEY_RETURNS_NON_NULL
to_chars(char * first,const char * last,FloatType value)16379 char* to_chars(char* first, const char* last, FloatType value)
16380 {
16381     static_cast<void>(last); // maybe unused - fix warning
16382     JSON_ASSERT(std::isfinite(value));
16383 
16384     // Use signbit(value) instead of (value < 0) since signbit works for -0.
16385     if (std::signbit(value))
16386     {
16387         value = -value;
16388         *first++ = '-';
16389     }
16390 
16391 #ifdef __GNUC__
16392 #pragma GCC diagnostic push
16393 #pragma GCC diagnostic ignored "-Wfloat-equal"
16394 #endif
16395     if (value == 0) // +-0
16396     {
16397         *first++ = '0';
16398         // Make it look like a floating-point number (#362, #378)
16399         *first++ = '.';
16400         *first++ = '0';
16401         return first;
16402     }
16403 #ifdef __GNUC__
16404 #pragma GCC diagnostic pop
16405 #endif
16406 
16407     JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
16408 
16409     // Compute v = buffer * 10^decimal_exponent.
16410     // The decimal digits are stored in the buffer, which needs to be interpreted
16411     // as an unsigned decimal integer.
16412     // len is the length of the buffer, i.e. the number of decimal digits.
16413     int len = 0;
16414     int decimal_exponent = 0;
16415     dtoa_impl::grisu2(first, len, decimal_exponent, value);
16416 
16417     JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
16418 
16419     // Format the buffer like printf("%.*g", prec, value)
16420     constexpr int kMinExp = -4;
16421     // Use digits10 here to increase compatibility with version 2.
16422     constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
16423 
16424     JSON_ASSERT(last - first >= kMaxExp + 2);
16425     JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
16426     JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
16427 
16428     return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
16429 }
16430 
16431 } // namespace detail
16432 } // namespace nlohmann
16433 
16434 // #include <nlohmann/detail/exceptions.hpp>
16435 
16436 // #include <nlohmann/detail/macro_scope.hpp>
16437 
16438 // #include <nlohmann/detail/meta/cpp_future.hpp>
16439 
16440 // #include <nlohmann/detail/output/binary_writer.hpp>
16441 
16442 // #include <nlohmann/detail/output/output_adapters.hpp>
16443 
16444 // #include <nlohmann/detail/value_t.hpp>
16445 
16446 
16447 namespace nlohmann
16448 {
16449 namespace detail
16450 {
16451 ///////////////////
16452 // serialization //
16453 ///////////////////
16454 
16455 /// how to treat decoding errors
16456 enum class error_handler_t
16457 {
16458     strict,  ///< throw a type_error exception in case of invalid UTF-8
16459     replace, ///< replace invalid UTF-8 sequences with U+FFFD
16460     ignore   ///< ignore invalid UTF-8 sequences
16461 };
16462 
16463 template<typename BasicJsonType>
16464 class serializer
16465 {
16466     using string_t = typename BasicJsonType::string_t;
16467     using number_float_t = typename BasicJsonType::number_float_t;
16468     using number_integer_t = typename BasicJsonType::number_integer_t;
16469     using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
16470     using binary_char_t = typename BasicJsonType::binary_t::value_type;
16471     static constexpr std::uint8_t UTF8_ACCEPT = 0;
16472     static constexpr std::uint8_t UTF8_REJECT = 1;
16473 
16474   public:
16475     /*!
16476     @param[in] s  output stream to serialize to
16477     @param[in] ichar  indentation character to use
16478     @param[in] error_handler_  how to react on decoding errors
16479     */
serializer(output_adapter_t<char> s,const char ichar,error_handler_t error_handler_=error_handler_t::strict)16480     serializer(output_adapter_t<char> s, const char ichar,
16481                error_handler_t error_handler_ = error_handler_t::strict)
16482         : o(std::move(s))
16483         , loc(std::localeconv())
16484         , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
16485         , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
16486         , indent_char(ichar)
16487         , indent_string(512, indent_char)
16488         , error_handler(error_handler_)
16489     {}
16490 
16491     // delete because of pointer members
16492     serializer(const serializer&) = delete;
16493     serializer& operator=(const serializer&) = delete;
16494     serializer(serializer&&) = delete;
16495     serializer& operator=(serializer&&) = delete;
16496     ~serializer() = default;
16497 
16498     /*!
16499     @brief internal implementation of the serialization function
16500 
16501     This function is called by the public member function dump and organizes
16502     the serialization internally. The indentation level is propagated as
16503     additional parameter. In case of arrays and objects, the function is
16504     called recursively.
16505 
16506     - strings and object keys are escaped using `escape_string()`
16507     - integer numbers are converted implicitly via `operator<<`
16508     - floating-point numbers are converted to a string using `"%g"` format
16509     - binary values are serialized as objects containing the subtype and the
16510       byte array
16511 
16512     @param[in] val               value to serialize
16513     @param[in] pretty_print      whether the output shall be pretty-printed
16514     @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
16515     in the output are escaped with `\uXXXX` sequences, and the result consists
16516     of ASCII characters only.
16517     @param[in] indent_step       the indent level
16518     @param[in] current_indent    the current indent level (only used internally)
16519     */
dump(const BasicJsonType & val,const bool pretty_print,const bool ensure_ascii,const unsigned int indent_step,const unsigned int current_indent=0)16520     void dump(const BasicJsonType& val,
16521               const bool pretty_print,
16522               const bool ensure_ascii,
16523               const unsigned int indent_step,
16524               const unsigned int current_indent = 0)
16525     {
16526         switch (val.m_type)
16527         {
16528             case value_t::object:
16529             {
16530                 if (val.m_value.object->empty())
16531                 {
16532                     o->write_characters("{}", 2);
16533                     return;
16534                 }
16535 
16536                 if (pretty_print)
16537                 {
16538                     o->write_characters("{\n", 2);
16539 
16540                     // variable to hold indentation for recursive calls
16541                     const auto new_indent = current_indent + indent_step;
16542                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16543                     {
16544                         indent_string.resize(indent_string.size() * 2, ' ');
16545                     }
16546 
16547                     // first n-1 elements
16548                     auto i = val.m_value.object->cbegin();
16549                     for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16550                     {
16551                         o->write_characters(indent_string.c_str(), new_indent);
16552                         o->write_character('\"');
16553                         dump_escaped(i->first, ensure_ascii);
16554                         o->write_characters("\": ", 3);
16555                         dump(i->second, true, ensure_ascii, indent_step, new_indent);
16556                         o->write_characters(",\n", 2);
16557                     }
16558 
16559                     // last element
16560                     JSON_ASSERT(i != val.m_value.object->cend());
16561                     JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16562                     o->write_characters(indent_string.c_str(), new_indent);
16563                     o->write_character('\"');
16564                     dump_escaped(i->first, ensure_ascii);
16565                     o->write_characters("\": ", 3);
16566                     dump(i->second, true, ensure_ascii, indent_step, new_indent);
16567 
16568                     o->write_character('\n');
16569                     o->write_characters(indent_string.c_str(), current_indent);
16570                     o->write_character('}');
16571                 }
16572                 else
16573                 {
16574                     o->write_character('{');
16575 
16576                     // first n-1 elements
16577                     auto i = val.m_value.object->cbegin();
16578                     for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16579                     {
16580                         o->write_character('\"');
16581                         dump_escaped(i->first, ensure_ascii);
16582                         o->write_characters("\":", 2);
16583                         dump(i->second, false, ensure_ascii, indent_step, current_indent);
16584                         o->write_character(',');
16585                     }
16586 
16587                     // last element
16588                     JSON_ASSERT(i != val.m_value.object->cend());
16589                     JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16590                     o->write_character('\"');
16591                     dump_escaped(i->first, ensure_ascii);
16592                     o->write_characters("\":", 2);
16593                     dump(i->second, false, ensure_ascii, indent_step, current_indent);
16594 
16595                     o->write_character('}');
16596                 }
16597 
16598                 return;
16599             }
16600 
16601             case value_t::array:
16602             {
16603                 if (val.m_value.array->empty())
16604                 {
16605                     o->write_characters("[]", 2);
16606                     return;
16607                 }
16608 
16609                 if (pretty_print)
16610                 {
16611                     o->write_characters("[\n", 2);
16612 
16613                     // variable to hold indentation for recursive calls
16614                     const auto new_indent = current_indent + indent_step;
16615                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16616                     {
16617                         indent_string.resize(indent_string.size() * 2, ' ');
16618                     }
16619 
16620                     // first n-1 elements
16621                     for (auto i = val.m_value.array->cbegin();
16622                             i != val.m_value.array->cend() - 1; ++i)
16623                     {
16624                         o->write_characters(indent_string.c_str(), new_indent);
16625                         dump(*i, true, ensure_ascii, indent_step, new_indent);
16626                         o->write_characters(",\n", 2);
16627                     }
16628 
16629                     // last element
16630                     JSON_ASSERT(!val.m_value.array->empty());
16631                     o->write_characters(indent_string.c_str(), new_indent);
16632                     dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
16633 
16634                     o->write_character('\n');
16635                     o->write_characters(indent_string.c_str(), current_indent);
16636                     o->write_character(']');
16637                 }
16638                 else
16639                 {
16640                     o->write_character('[');
16641 
16642                     // first n-1 elements
16643                     for (auto i = val.m_value.array->cbegin();
16644                             i != val.m_value.array->cend() - 1; ++i)
16645                     {
16646                         dump(*i, false, ensure_ascii, indent_step, current_indent);
16647                         o->write_character(',');
16648                     }
16649 
16650                     // last element
16651                     JSON_ASSERT(!val.m_value.array->empty());
16652                     dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
16653 
16654                     o->write_character(']');
16655                 }
16656 
16657                 return;
16658             }
16659 
16660             case value_t::string:
16661             {
16662                 o->write_character('\"');
16663                 dump_escaped(*val.m_value.string, ensure_ascii);
16664                 o->write_character('\"');
16665                 return;
16666             }
16667 
16668             case value_t::binary:
16669             {
16670                 if (pretty_print)
16671                 {
16672                     o->write_characters("{\n", 2);
16673 
16674                     // variable to hold indentation for recursive calls
16675                     const auto new_indent = current_indent + indent_step;
16676                     if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16677                     {
16678                         indent_string.resize(indent_string.size() * 2, ' ');
16679                     }
16680 
16681                     o->write_characters(indent_string.c_str(), new_indent);
16682 
16683                     o->write_characters("\"bytes\": [", 10);
16684 
16685                     if (!val.m_value.binary->empty())
16686                     {
16687                         for (auto i = val.m_value.binary->cbegin();
16688                                 i != val.m_value.binary->cend() - 1; ++i)
16689                         {
16690                             dump_integer(*i);
16691                             o->write_characters(", ", 2);
16692                         }
16693                         dump_integer(val.m_value.binary->back());
16694                     }
16695 
16696                     o->write_characters("],\n", 3);
16697                     o->write_characters(indent_string.c_str(), new_indent);
16698 
16699                     o->write_characters("\"subtype\": ", 11);
16700                     if (val.m_value.binary->has_subtype())
16701                     {
16702                         dump_integer(val.m_value.binary->subtype());
16703                     }
16704                     else
16705                     {
16706                         o->write_characters("null", 4);
16707                     }
16708                     o->write_character('\n');
16709                     o->write_characters(indent_string.c_str(), current_indent);
16710                     o->write_character('}');
16711                 }
16712                 else
16713                 {
16714                     o->write_characters("{\"bytes\":[", 10);
16715 
16716                     if (!val.m_value.binary->empty())
16717                     {
16718                         for (auto i = val.m_value.binary->cbegin();
16719                                 i != val.m_value.binary->cend() - 1; ++i)
16720                         {
16721                             dump_integer(*i);
16722                             o->write_character(',');
16723                         }
16724                         dump_integer(val.m_value.binary->back());
16725                     }
16726 
16727                     o->write_characters("],\"subtype\":", 12);
16728                     if (val.m_value.binary->has_subtype())
16729                     {
16730                         dump_integer(val.m_value.binary->subtype());
16731                         o->write_character('}');
16732                     }
16733                     else
16734                     {
16735                         o->write_characters("null}", 5);
16736                     }
16737                 }
16738                 return;
16739             }
16740 
16741             case value_t::boolean:
16742             {
16743                 if (val.m_value.boolean)
16744                 {
16745                     o->write_characters("true", 4);
16746                 }
16747                 else
16748                 {
16749                     o->write_characters("false", 5);
16750                 }
16751                 return;
16752             }
16753 
16754             case value_t::number_integer:
16755             {
16756                 dump_integer(val.m_value.number_integer);
16757                 return;
16758             }
16759 
16760             case value_t::number_unsigned:
16761             {
16762                 dump_integer(val.m_value.number_unsigned);
16763                 return;
16764             }
16765 
16766             case value_t::number_float:
16767             {
16768                 dump_float(val.m_value.number_float);
16769                 return;
16770             }
16771 
16772             case value_t::discarded:
16773             {
16774                 o->write_characters("<discarded>", 11);
16775                 return;
16776             }
16777 
16778             case value_t::null:
16779             {
16780                 o->write_characters("null", 4);
16781                 return;
16782             }
16783 
16784             default:            // LCOV_EXCL_LINE
16785                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16786         }
16787     }
16788 
16789   JSON_PRIVATE_UNLESS_TESTED:
16790     /*!
16791     @brief dump escaped string
16792 
16793     Escape a string by replacing certain special characters by a sequence of an
16794     escape character (backslash) and another character and other control
16795     characters by a sequence of "\u" followed by a four-digit hex
16796     representation. The escaped string is written to output stream @a o.
16797 
16798     @param[in] s  the string to escape
16799     @param[in] ensure_ascii  whether to escape non-ASCII characters with
16800                              \uXXXX sequences
16801 
16802     @complexity Linear in the length of string @a s.
16803     */
16804     void dump_escaped(const string_t& s, const bool ensure_ascii)
16805     {
16806         std::uint32_t codepoint{};
16807         std::uint8_t state = UTF8_ACCEPT;
16808         std::size_t bytes = 0;  // number of bytes written to string_buffer
16809 
16810         // number of bytes written at the point of the last valid byte
16811         std::size_t bytes_after_last_accept = 0;
16812         std::size_t undumped_chars = 0;
16813 
16814         for (std::size_t i = 0; i < s.size(); ++i)
16815         {
16816             const auto byte = static_cast<std::uint8_t>(s[i]);
16817 
16818             switch (decode(state, codepoint, byte))
16819             {
16820                 case UTF8_ACCEPT:  // decode found a new code point
16821                 {
16822                     switch (codepoint)
16823                     {
16824                         case 0x08: // backspace
16825                         {
16826                             string_buffer[bytes++] = '\\';
16827                             string_buffer[bytes++] = 'b';
16828                             break;
16829                         }
16830 
16831                         case 0x09: // horizontal tab
16832                         {
16833                             string_buffer[bytes++] = '\\';
16834                             string_buffer[bytes++] = 't';
16835                             break;
16836                         }
16837 
16838                         case 0x0A: // newline
16839                         {
16840                             string_buffer[bytes++] = '\\';
16841                             string_buffer[bytes++] = 'n';
16842                             break;
16843                         }
16844 
16845                         case 0x0C: // formfeed
16846                         {
16847                             string_buffer[bytes++] = '\\';
16848                             string_buffer[bytes++] = 'f';
16849                             break;
16850                         }
16851 
16852                         case 0x0D: // carriage return
16853                         {
16854                             string_buffer[bytes++] = '\\';
16855                             string_buffer[bytes++] = 'r';
16856                             break;
16857                         }
16858 
16859                         case 0x22: // quotation mark
16860                         {
16861                             string_buffer[bytes++] = '\\';
16862                             string_buffer[bytes++] = '\"';
16863                             break;
16864                         }
16865 
16866                         case 0x5C: // reverse solidus
16867                         {
16868                             string_buffer[bytes++] = '\\';
16869                             string_buffer[bytes++] = '\\';
16870                             break;
16871                         }
16872 
16873                         default:
16874                         {
16875                             // escape control characters (0x00..0x1F) or, if
16876                             // ensure_ascii parameter is used, non-ASCII characters
16877                             if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
16878                             {
16879                                 if (codepoint <= 0xFFFF)
16880                                 {
16881                                     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16882                                     (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
16883                                                     static_cast<std::uint16_t>(codepoint));
16884                                     bytes += 6;
16885                                 }
16886                                 else
16887                                 {
16888                                     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16889                                     (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
16890                                                     static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
16891                                                     static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
16892                                     bytes += 12;
16893                                 }
16894                             }
16895                             else
16896                             {
16897                                 // copy byte to buffer (all previous bytes
16898                                 // been copied have in default case above)
16899                                 string_buffer[bytes++] = s[i];
16900                             }
16901                             break;
16902                         }
16903                     }
16904 
16905                     // write buffer and reset index; there must be 13 bytes
16906                     // left, as this is the maximal number of bytes to be
16907                     // written ("\uxxxx\uxxxx\0") for one code point
16908                     if (string_buffer.size() - bytes < 13)
16909                     {
16910                         o->write_characters(string_buffer.data(), bytes);
16911                         bytes = 0;
16912                     }
16913 
16914                     // remember the byte position of this accept
16915                     bytes_after_last_accept = bytes;
16916                     undumped_chars = 0;
16917                     break;
16918                 }
16919 
16920                 case UTF8_REJECT:  // decode found invalid UTF-8 byte
16921                 {
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", byte);
16929                             JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType()));
16930                         }
16931 
16932                         case error_handler_t::ignore:
16933                         case error_handler_t::replace:
16934                         {
16935                             // in case we saw this character the first time, we
16936                             // would like to read it again, because the byte
16937                             // may be OK for itself, but just not OK for the
16938                             // previous sequence
16939                             if (undumped_chars > 0)
16940                             {
16941                                 --i;
16942                             }
16943 
16944                             // reset length buffer to the last accepted index;
16945                             // thus removing/ignoring the invalid characters
16946                             bytes = bytes_after_last_accept;
16947 
16948                             if (error_handler == error_handler_t::replace)
16949                             {
16950                                 // add a replacement character
16951                                 if (ensure_ascii)
16952                                 {
16953                                     string_buffer[bytes++] = '\\';
16954                                     string_buffer[bytes++] = 'u';
16955                                     string_buffer[bytes++] = 'f';
16956                                     string_buffer[bytes++] = 'f';
16957                                     string_buffer[bytes++] = 'f';
16958                                     string_buffer[bytes++] = 'd';
16959                                 }
16960                                 else
16961                                 {
16962                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
16963                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
16964                                     string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
16965                                 }
16966 
16967                                 // write buffer and reset index; there must be 13 bytes
16968                                 // left, as this is the maximal number of bytes to be
16969                                 // written ("\uxxxx\uxxxx\0") for one code point
16970                                 if (string_buffer.size() - bytes < 13)
16971                                 {
16972                                     o->write_characters(string_buffer.data(), bytes);
16973                                     bytes = 0;
16974                                 }
16975 
16976                                 bytes_after_last_accept = bytes;
16977                             }
16978 
16979                             undumped_chars = 0;
16980 
16981                             // continue processing the string
16982                             state = UTF8_ACCEPT;
16983                             break;
16984                         }
16985 
16986                         default:            // LCOV_EXCL_LINE
16987                             JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16988                     }
16989                     break;
16990                 }
16991 
16992                 default:  // decode found yet incomplete multi-byte code point
16993                 {
16994                     if (!ensure_ascii)
16995                     {
16996                         // code point will not be escaped - copy byte to buffer
16997                         string_buffer[bytes++] = s[i];
16998                     }
16999                     ++undumped_chars;
17000                     break;
17001                 }
17002             }
17003         }
17004 
17005         // we finished processing the string
17006         if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
17007         {
17008             // write buffer
17009             if (bytes > 0)
17010             {
17011                 o->write_characters(string_buffer.data(), bytes);
17012             }
17013         }
17014         else
17015         {
17016             // we finish reading, but do not accept: string was incomplete
17017             switch (error_handler)
17018             {
17019                 case error_handler_t::strict:
17020                 {
17021                     std::string sn(9, '\0');
17022                     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17023                     (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
17024                     JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType()));
17025                 }
17026 
17027                 case error_handler_t::ignore:
17028                 {
17029                     // write all accepted bytes
17030                     o->write_characters(string_buffer.data(), bytes_after_last_accept);
17031                     break;
17032                 }
17033 
17034                 case error_handler_t::replace:
17035                 {
17036                     // write all accepted bytes
17037                     o->write_characters(string_buffer.data(), bytes_after_last_accept);
17038                     // add a replacement character
17039                     if (ensure_ascii)
17040                     {
17041                         o->write_characters("\\ufffd", 6);
17042                     }
17043                     else
17044                     {
17045                         o->write_characters("\xEF\xBF\xBD", 3);
17046                     }
17047                     break;
17048                 }
17049 
17050                 default:            // LCOV_EXCL_LINE
17051                     JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17052             }
17053         }
17054     }
17055 
17056   private:
17057     /*!
17058     @brief count digits
17059 
17060     Count the number of decimal (base 10) digits for an input unsigned integer.
17061 
17062     @param[in] x  unsigned integer number to count its digits
17063     @return    number of decimal digits
17064     */
count_digits(number_unsigned_t x)17065     inline unsigned int count_digits(number_unsigned_t x) noexcept
17066     {
17067         unsigned int n_digits = 1;
17068         for (;;)
17069         {
17070             if (x < 10)
17071             {
17072                 return n_digits;
17073             }
17074             if (x < 100)
17075             {
17076                 return n_digits + 1;
17077             }
17078             if (x < 1000)
17079             {
17080                 return n_digits + 2;
17081             }
17082             if (x < 10000)
17083             {
17084                 return n_digits + 3;
17085             }
17086             x = x / 10000u;
17087             n_digits += 4;
17088         }
17089     }
17090 
17091     /*!
17092     @brief dump an integer
17093 
17094     Dump a given integer to output stream @a o. Works internally with
17095     @a number_buffer.
17096 
17097     @param[in] x  integer number (signed or unsigned) to dump
17098     @tparam NumberType either @a number_integer_t or @a number_unsigned_t
17099     */
17100     template < typename NumberType, detail::enable_if_t <
17101                    std::is_integral<NumberType>::value ||
17102                    std::is_same<NumberType, number_unsigned_t>::value ||
17103                    std::is_same<NumberType, number_integer_t>::value ||
17104                    std::is_same<NumberType, binary_char_t>::value,
17105                    int > = 0 >
dump_integer(NumberType x)17106     void dump_integer(NumberType x)
17107     {
17108         static constexpr std::array<std::array<char, 2>, 100> digits_to_99
17109         {
17110             {
17111                 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
17112                 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
17113                 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
17114                 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
17115                 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
17116                 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17117                 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17118                 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17119                 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17120                 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17121             }
17122         };
17123 
17124         // special case for "0"
17125         if (x == 0)
17126         {
17127             o->write_character('0');
17128             return;
17129         }
17130 
17131         // use a pointer to fill the buffer
17132         auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17133 
17134         const bool is_negative = std::is_signed<NumberType>::value && !(x >= 0); // see issue #755
17135         number_unsigned_t abs_value;
17136 
17137         unsigned int n_chars{};
17138 
17139         if (is_negative)
17140         {
17141             *buffer_ptr = '-';
17142             abs_value = remove_sign(static_cast<number_integer_t>(x));
17143 
17144             // account one more byte for the minus sign
17145             n_chars = 1 + count_digits(abs_value);
17146         }
17147         else
17148         {
17149             abs_value = static_cast<number_unsigned_t>(x);
17150             n_chars = count_digits(abs_value);
17151         }
17152 
17153         // spare 1 byte for '\0'
17154         JSON_ASSERT(n_chars < number_buffer.size() - 1);
17155 
17156         // jump to the end to generate the string from backward
17157         // so we later avoid reversing the result
17158         buffer_ptr += n_chars;
17159 
17160         // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
17161         // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
17162         while (abs_value >= 100)
17163         {
17164             const auto digits_index = static_cast<unsigned>((abs_value % 100));
17165             abs_value /= 100;
17166             *(--buffer_ptr) = digits_to_99[digits_index][1];
17167             *(--buffer_ptr) = digits_to_99[digits_index][0];
17168         }
17169 
17170         if (abs_value >= 10)
17171         {
17172             const auto digits_index = static_cast<unsigned>(abs_value);
17173             *(--buffer_ptr) = digits_to_99[digits_index][1];
17174             *(--buffer_ptr) = digits_to_99[digits_index][0];
17175         }
17176         else
17177         {
17178             *(--buffer_ptr) = static_cast<char>('0' + abs_value);
17179         }
17180 
17181         o->write_characters(number_buffer.data(), n_chars);
17182     }
17183 
17184     /*!
17185     @brief dump a floating-point number
17186 
17187     Dump a given floating-point number to output stream @a o. Works internally
17188     with @a number_buffer.
17189 
17190     @param[in] x  floating-point number to dump
17191     */
dump_float(number_float_t x)17192     void dump_float(number_float_t x)
17193     {
17194         // NaN / inf
17195         if (!std::isfinite(x))
17196         {
17197             o->write_characters("null", 4);
17198             return;
17199         }
17200 
17201         // If number_float_t is an IEEE-754 single or double precision number,
17202         // use the Grisu2 algorithm to produce short numbers which are
17203         // guaranteed to round-trip, using strtof and strtod, resp.
17204         //
17205         // NB: The test below works if <long double> == <double>.
17206         static constexpr bool is_ieee_single_or_double
17207             = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
17208               (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
17209 
17210         dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
17211     }
17212 
dump_float(number_float_t x,std::true_type)17213     void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
17214     {
17215         auto* begin = number_buffer.data();
17216         auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
17217 
17218         o->write_characters(begin, static_cast<size_t>(end - begin));
17219     }
17220 
dump_float(number_float_t x,std::false_type)17221     void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
17222     {
17223         // get number of digits for a float -> text -> float round-trip
17224         static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
17225 
17226         // the actual conversion
17227         // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17228         std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
17229 
17230         // negative value indicates an error
17231         JSON_ASSERT(len > 0);
17232         // check if buffer was large enough
17233         JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
17234 
17235         // erase thousands separator
17236         if (thousands_sep != '\0')
17237         {
17238             // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
17239             const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
17240             std::fill(end, number_buffer.end(), '\0');
17241             JSON_ASSERT((end - number_buffer.begin()) <= len);
17242             len = (end - number_buffer.begin());
17243         }
17244 
17245         // convert decimal point to '.'
17246         if (decimal_point != '\0' && decimal_point != '.')
17247         {
17248             // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
17249             const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
17250             if (dec_pos != number_buffer.end())
17251             {
17252                 *dec_pos = '.';
17253             }
17254         }
17255 
17256         o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
17257 
17258         // determine if need to append ".0"
17259         const bool value_is_int_like =
17260             std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
17261                          [](char c)
17262         {
17263             return c == '.' || c == 'e';
17264         });
17265 
17266         if (value_is_int_like)
17267         {
17268             o->write_characters(".0", 2);
17269         }
17270     }
17271 
17272     /*!
17273     @brief check whether a string is UTF-8 encoded
17274 
17275     The function checks each byte of a string whether it is UTF-8 encoded. The
17276     result of the check is stored in the @a state parameter. The function must
17277     be called initially with state 0 (accept). State 1 means the string must
17278     be rejected, because the current byte is not allowed. If the string is
17279     completely processed, but the state is non-zero, the string ended
17280     prematurely; that is, the last byte indicated more bytes should have
17281     followed.
17282 
17283     @param[in,out] state  the state of the decoding
17284     @param[in,out] codep  codepoint (valid only if resulting state is UTF8_ACCEPT)
17285     @param[in] byte       next byte to decode
17286     @return               new state
17287 
17288     @note The function has been edited: a std::array is used.
17289 
17290     @copyright Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
17291     @sa http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
17292     */
decode(std::uint8_t & state,std::uint32_t & codep,const std::uint8_t byte)17293     static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
17294     {
17295         static const std::array<std::uint8_t, 400> utf8d =
17296         {
17297             {
17298                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
17299                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
17300                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
17301                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
17302                 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
17303                 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
17304                 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
17305                 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
17306                 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
17307                 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
17308                 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
17309                 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
17310                 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
17311                 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
17312             }
17313         };
17314 
17315         JSON_ASSERT(byte < utf8d.size());
17316         const std::uint8_t type = utf8d[byte];
17317 
17318         codep = (state != UTF8_ACCEPT)
17319                 ? (byte & 0x3fu) | (codep << 6u)
17320                 : (0xFFu >> type) & (byte);
17321 
17322         std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
17323         JSON_ASSERT(index < 400);
17324         state = utf8d[index];
17325         return state;
17326     }
17327 
17328     /*
17329      * Overload to make the compiler happy while it is instantiating
17330      * dump_integer for number_unsigned_t.
17331      * Must never be called.
17332      */
remove_sign(number_unsigned_t x)17333     number_unsigned_t remove_sign(number_unsigned_t x)
17334     {
17335         JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17336         return x; // LCOV_EXCL_LINE
17337     }
17338 
17339     /*
17340      * Helper function for dump_integer
17341      *
17342      * This function takes a negative signed integer and returns its absolute
17343      * value as unsigned integer. The plus/minus shuffling is necessary as we can
17344      * not directly remove the sign of an arbitrary signed integer as the
17345      * absolute values of INT_MIN and INT_MAX are usually not the same. See
17346      * #1708 for details.
17347      */
remove_sign(number_integer_t x)17348     inline number_unsigned_t remove_sign(number_integer_t x) noexcept
17349     {
17350         JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
17351         return static_cast<number_unsigned_t>(-(x + 1)) + 1;
17352     }
17353 
17354   private:
17355     /// the output of the serializer
17356     output_adapter_t<char> o = nullptr;
17357 
17358     /// a (hopefully) large enough character buffer
17359     std::array<char, 64> number_buffer{{}};
17360 
17361     /// the locale
17362     const std::lconv* loc = nullptr;
17363     /// the locale's thousand separator character
17364     const char thousands_sep = '\0';
17365     /// the locale's decimal point character
17366     const char decimal_point = '\0';
17367 
17368     /// string buffer
17369     std::array<char, 512> string_buffer{{}};
17370 
17371     /// the indentation character
17372     const char indent_char;
17373     /// the indentation string
17374     string_t indent_string;
17375 
17376     /// error_handler how to react on decoding errors
17377     const error_handler_t error_handler;
17378 };
17379 }  // namespace detail
17380 }  // namespace nlohmann
17381 
17382 // #include <nlohmann/detail/value_t.hpp>
17383 
17384 // #include <nlohmann/json_fwd.hpp>
17385 
17386 // #include <nlohmann/ordered_map.hpp>
17387 
17388 
17389 #include <functional> // less
17390 #include <initializer_list> // initializer_list
17391 #include <iterator> // input_iterator_tag, iterator_traits
17392 #include <memory> // allocator
17393 #include <stdexcept> // for out_of_range
17394 #include <type_traits> // enable_if, is_convertible
17395 #include <utility> // pair
17396 #include <vector> // vector
17397 
17398 // #include <nlohmann/detail/macro_scope.hpp>
17399 
17400 
17401 namespace nlohmann
17402 {
17403 
17404 /// ordered_map: a minimal map-like container that preserves insertion order
17405 /// for use within nlohmann::basic_json<ordered_map>
17406 template <class Key, class T, class IgnoredLess = std::less<Key>,
17407           class Allocator = std::allocator<std::pair<const Key, T>>>
17408                   struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
17409 {
17410     using key_type = Key;
17411     using mapped_type = T;
17412     using Container = std::vector<std::pair<const Key, T>, Allocator>;
17413     using typename Container::iterator;
17414     using typename Container::const_iterator;
17415     using typename Container::size_type;
17416     using typename Container::value_type;
17417 
17418     // Explicit constructors instead of `using Container::Container`
17419     // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
ordered_mapnlohmann::ordered_map17420     ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
17421     template <class It>
ordered_mapnlohmann::ordered_map17422     ordered_map(It first, It last, const Allocator& alloc = Allocator())
17423         : Container{first, last, alloc} {}
ordered_mapnlohmann::ordered_map17424     ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
17425         : Container{init, alloc} {}
17426 
emplacenlohmann::ordered_map17427     std::pair<iterator, bool> emplace(const key_type& key, T&& t)
17428     {
17429         for (auto it = this->begin(); it != this->end(); ++it)
17430         {
17431             if (it->first == key)
17432             {
17433                 return {it, false};
17434             }
17435         }
17436         Container::emplace_back(key, t);
17437         return {--this->end(), true};
17438     }
17439 
operator []nlohmann::ordered_map17440     T& operator[](const Key& key)
17441     {
17442         return emplace(key, T{}).first->second;
17443     }
17444 
operator []nlohmann::ordered_map17445     const T& operator[](const Key& key) const
17446     {
17447         return at(key);
17448     }
17449 
atnlohmann::ordered_map17450     T& at(const Key& key)
17451     {
17452         for (auto it = this->begin(); it != this->end(); ++it)
17453         {
17454             if (it->first == key)
17455             {
17456                 return it->second;
17457             }
17458         }
17459 
17460         JSON_THROW(std::out_of_range("key not found"));
17461     }
17462 
atnlohmann::ordered_map17463     const T& at(const Key& key) const
17464     {
17465         for (auto it = this->begin(); it != this->end(); ++it)
17466         {
17467             if (it->first == key)
17468             {
17469                 return it->second;
17470             }
17471         }
17472 
17473         JSON_THROW(std::out_of_range("key not found"));
17474     }
17475 
erasenlohmann::ordered_map17476     size_type erase(const Key& key)
17477     {
17478         for (auto it = this->begin(); it != this->end(); ++it)
17479         {
17480             if (it->first == key)
17481             {
17482                 // Since we cannot move const Keys, re-construct them in place
17483                 for (auto next = it; ++next != this->end(); ++it)
17484                 {
17485                     it->~value_type(); // Destroy but keep allocation
17486                     new (&*it) value_type{std::move(*next)};
17487                 }
17488                 Container::pop_back();
17489                 return 1;
17490             }
17491         }
17492         return 0;
17493     }
17494 
erasenlohmann::ordered_map17495     iterator erase(iterator pos)
17496     {
17497         auto it = pos;
17498 
17499         // Since we cannot move const Keys, re-construct them in place
17500         for (auto next = it; ++next != this->end(); ++it)
17501         {
17502             it->~value_type(); // Destroy but keep allocation
17503             new (&*it) value_type{std::move(*next)};
17504         }
17505         Container::pop_back();
17506         return pos;
17507     }
17508 
countnlohmann::ordered_map17509     size_type count(const Key& key) const
17510     {
17511         for (auto it = this->begin(); it != this->end(); ++it)
17512         {
17513             if (it->first == key)
17514             {
17515                 return 1;
17516             }
17517         }
17518         return 0;
17519     }
17520 
findnlohmann::ordered_map17521     iterator find(const Key& key)
17522     {
17523         for (auto it = this->begin(); it != this->end(); ++it)
17524         {
17525             if (it->first == key)
17526             {
17527                 return it;
17528             }
17529         }
17530         return Container::end();
17531     }
17532 
findnlohmann::ordered_map17533     const_iterator find(const Key& key) const
17534     {
17535         for (auto it = this->begin(); it != this->end(); ++it)
17536         {
17537             if (it->first == key)
17538             {
17539                 return it;
17540             }
17541         }
17542         return Container::end();
17543     }
17544 
insertnlohmann::ordered_map17545     std::pair<iterator, bool> insert( value_type&& value )
17546     {
17547         return emplace(value.first, std::move(value.second));
17548     }
17549 
insertnlohmann::ordered_map17550     std::pair<iterator, bool> insert( const value_type& value )
17551     {
17552         for (auto it = this->begin(); it != this->end(); ++it)
17553         {
17554             if (it->first == value.first)
17555             {
17556                 return {it, false};
17557             }
17558         }
17559         Container::push_back(value);
17560         return {--this->end(), true};
17561     }
17562 
17563     template<typename InputIt>
17564     using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
17565             std::input_iterator_tag>::value>::type;
17566 
17567     template<typename InputIt, typename = require_input_iter<InputIt>>
insertnlohmann::ordered_map17568     void insert(InputIt first, InputIt last)
17569     {
17570         for (auto it = first; it != last; ++it)
17571         {
17572             insert(*it);
17573         }
17574     }
17575 };
17576 
17577 }  // namespace nlohmann
17578 
17579 
17580 #if defined(JSON_HAS_CPP_17)
17581     #include <string_view>
17582 #endif
17583 
17584 /*!
17585 @brief namespace for Niels Lohmann
17586 @see https://github.com/nlohmann
17587 @since version 1.0.0
17588 */
17589 namespace nlohmann
17590 {
17591 
17592 /*!
17593 @brief a class to store JSON values
17594 
17595 @tparam ObjectType type for JSON objects (`std::map` by default; will be used
17596 in @ref object_t)
17597 @tparam ArrayType type for JSON arrays (`std::vector` by default; will be used
17598 in @ref array_t)
17599 @tparam StringType type for JSON strings and object keys (`std::string` by
17600 default; will be used in @ref string_t)
17601 @tparam BooleanType type for JSON booleans (`bool` by default; will be used
17602 in @ref boolean_t)
17603 @tparam NumberIntegerType type for JSON integer numbers (`int64_t` by
17604 default; will be used in @ref number_integer_t)
17605 @tparam NumberUnsignedType type for JSON unsigned integer numbers (@c
17606 `uint64_t` by default; will be used in @ref number_unsigned_t)
17607 @tparam NumberFloatType type for JSON floating-point numbers (`double` by
17608 default; will be used in @ref number_float_t)
17609 @tparam BinaryType type for packed binary data for compatibility with binary
17610 serialization formats (`std::vector<std::uint8_t>` by default; will be used in
17611 @ref binary_t)
17612 @tparam AllocatorType type of the allocator to use (`std::allocator` by
17613 default)
17614 @tparam JSONSerializer the serializer to resolve internal calls to `to_json()`
17615 and `from_json()` (@ref adl_serializer by default)
17616 
17617 @requirement The class satisfies the following concept requirements:
17618 - Basic
17619  - [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible):
17620    JSON values can be default constructed. The result will be a JSON null
17621    value.
17622  - [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible):
17623    A JSON value can be constructed from an rvalue argument.
17624  - [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible):
17625    A JSON value can be copy-constructed from an lvalue expression.
17626  - [MoveAssignable](https://en.cppreference.com/w/cpp/named_req/MoveAssignable):
17627    A JSON value van be assigned from an rvalue argument.
17628  - [CopyAssignable](https://en.cppreference.com/w/cpp/named_req/CopyAssignable):
17629    A JSON value can be copy-assigned from an lvalue expression.
17630  - [Destructible](https://en.cppreference.com/w/cpp/named_req/Destructible):
17631    JSON values can be destructed.
17632 - Layout
17633  - [StandardLayoutType](https://en.cppreference.com/w/cpp/named_req/StandardLayoutType):
17634    JSON values have
17635    [standard layout](https://en.cppreference.com/w/cpp/language/data_members#Standard_layout):
17636    All non-static data members are private and standard layout types, the
17637    class has no virtual functions or (virtual) base classes.
17638 - Library-wide
17639  - [EqualityComparable](https://en.cppreference.com/w/cpp/named_req/EqualityComparable):
17640    JSON values can be compared with `==`, see @ref
17641    operator==(const_reference,const_reference).
17642  - [LessThanComparable](https://en.cppreference.com/w/cpp/named_req/LessThanComparable):
17643    JSON values can be compared with `<`, see @ref
17644    operator<(const_reference,const_reference).
17645  - [Swappable](https://en.cppreference.com/w/cpp/named_req/Swappable):
17646    Any JSON lvalue or rvalue of can be swapped with any lvalue or rvalue of
17647    other compatible types, using unqualified function call @ref swap().
17648  - [NullablePointer](https://en.cppreference.com/w/cpp/named_req/NullablePointer):
17649    JSON values can be compared against `std::nullptr_t` objects which are used
17650    to model the `null` value.
17651 - Container
17652  - [Container](https://en.cppreference.com/w/cpp/named_req/Container):
17653    JSON values can be used like STL containers and provide iterator access.
17654  - [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer);
17655    JSON values can be used like STL containers and provide reverse iterator
17656    access.
17657 
17658 @invariant The member variables @a m_value and @a m_type have the following
17659 relationship:
17660 - If `m_type == value_t::object`, then `m_value.object != nullptr`.
17661 - If `m_type == value_t::array`, then `m_value.array != nullptr`.
17662 - If `m_type == value_t::string`, then `m_value.string != nullptr`.
17663 The invariants are checked by member function assert_invariant().
17664 
17665 @internal
17666 @note ObjectType trick from https://stackoverflow.com/a/9860911
17667 @endinternal
17668 
17669 @see [RFC 8259: The JavaScript Object Notation (JSON) Data Interchange
17670 Format](https://tools.ietf.org/html/rfc8259)
17671 
17672 @since version 1.0.0
17673 
17674 @nosubgrouping
17675 */
17676 NLOHMANN_BASIC_JSON_TPL_DECLARATION
17677 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
17678 {
17679   private:
17680     template<detail::value_t> friend struct detail::external_constructor;
17681     friend ::nlohmann::json_pointer<basic_json>;
17682 
17683     template<typename BasicJsonType, typename InputType>
17684     friend class ::nlohmann::detail::parser;
17685     friend ::nlohmann::detail::serializer<basic_json>;
17686     template<typename BasicJsonType>
17687     friend class ::nlohmann::detail::iter_impl;
17688     template<typename BasicJsonType, typename CharType>
17689     friend class ::nlohmann::detail::binary_writer;
17690     template<typename BasicJsonType, typename InputType, typename SAX>
17691     friend class ::nlohmann::detail::binary_reader;
17692     template<typename BasicJsonType>
17693     friend class ::nlohmann::detail::json_sax_dom_parser;
17694     template<typename BasicJsonType>
17695     friend class ::nlohmann::detail::json_sax_dom_callback_parser;
17696     friend class ::nlohmann::detail::exception;
17697 
17698     /// workaround type for MSVC
17699     using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
17700 
17701   JSON_PRIVATE_UNLESS_TESTED:
17702     // convenience aliases for types residing in namespace detail;
17703     using lexer = ::nlohmann::detail::lexer_base<basic_json>;
17704 
17705     template<typename InputAdapterType>
parser(InputAdapterType adapter,detail::parser_callback_t<basic_json> cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)17706     static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
17707         InputAdapterType adapter,
17708         detail::parser_callback_t<basic_json>cb = nullptr,
17709         const bool allow_exceptions = true,
17710         const bool ignore_comments = false
17711                                  )
17712     {
17713         return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
17714                 std::move(cb), allow_exceptions, ignore_comments);
17715     }
17716 
17717   private:
17718     using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
17719     template<typename BasicJsonType>
17720     using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
17721     template<typename BasicJsonType>
17722     using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
17723     template<typename Iterator>
17724     using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
17725     template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
17726 
17727     template<typename CharType>
17728     using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
17729 
17730     template<typename InputType>
17731     using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
17732     template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
17733 
17734   JSON_PRIVATE_UNLESS_TESTED:
17735     using serializer = ::nlohmann::detail::serializer<basic_json>;
17736 
17737   public:
17738     using value_t = detail::value_t;
17739     /// JSON Pointer, see @ref nlohmann::json_pointer
17740     using json_pointer = ::nlohmann::json_pointer<basic_json>;
17741     template<typename T, typename SFINAE>
17742     using json_serializer = JSONSerializer<T, SFINAE>;
17743     /// how to treat decoding errors
17744     using error_handler_t = detail::error_handler_t;
17745     /// how to treat CBOR tags
17746     using cbor_tag_handler_t = detail::cbor_tag_handler_t;
17747     /// helper type for initializer lists of basic_json values
17748     using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
17749 
17750     using input_format_t = detail::input_format_t;
17751     /// SAX interface type, see @ref nlohmann::json_sax
17752     using json_sax_t = json_sax<basic_json>;
17753 
17754     ////////////////
17755     // exceptions //
17756     ////////////////
17757 
17758     /// @name exceptions
17759     /// Classes to implement user-defined exceptions.
17760     /// @{
17761 
17762     /// @copydoc detail::exception
17763     using exception = detail::exception;
17764     /// @copydoc detail::parse_error
17765     using parse_error = detail::parse_error;
17766     /// @copydoc detail::invalid_iterator
17767     using invalid_iterator = detail::invalid_iterator;
17768     /// @copydoc detail::type_error
17769     using type_error = detail::type_error;
17770     /// @copydoc detail::out_of_range
17771     using out_of_range = detail::out_of_range;
17772     /// @copydoc detail::other_error
17773     using other_error = detail::other_error;
17774 
17775     /// @}
17776 
17777 
17778     /////////////////////
17779     // container types //
17780     /////////////////////
17781 
17782     /// @name container types
17783     /// The canonic container types to use @ref basic_json like any other STL
17784     /// container.
17785     /// @{
17786 
17787     /// the type of elements in a basic_json container
17788     using value_type = basic_json;
17789 
17790     /// the type of an element reference
17791     using reference = value_type&;
17792     /// the type of an element const reference
17793     using const_reference = const value_type&;
17794 
17795     /// a type to represent differences between iterators
17796     using difference_type = std::ptrdiff_t;
17797     /// a type to represent container sizes
17798     using size_type = std::size_t;
17799 
17800     /// the allocator type
17801     using allocator_type = AllocatorType<basic_json>;
17802 
17803     /// the type of an element pointer
17804     using pointer = typename std::allocator_traits<allocator_type>::pointer;
17805     /// the type of an element const pointer
17806     using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
17807 
17808     /// an iterator for a basic_json container
17809     using iterator = iter_impl<basic_json>;
17810     /// a const iterator for a basic_json container
17811     using const_iterator = iter_impl<const basic_json>;
17812     /// a reverse iterator for a basic_json container
17813     using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
17814     /// a const reverse iterator for a basic_json container
17815     using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
17816 
17817     /// @}
17818 
17819 
17820     /*!
17821     @brief returns the allocator associated with the container
17822     */
get_allocator()17823     static allocator_type get_allocator()
17824     {
17825         return allocator_type();
17826     }
17827 
17828     /*!
17829     @brief returns version information on the library
17830 
17831     This function returns a JSON object with information about the library,
17832     including the version number and information on the platform and compiler.
17833 
17834     @return JSON object holding version information
17835     key         | description
17836     ----------- | ---------------
17837     `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).
17838     `copyright` | The copyright line for the library as string.
17839     `name`      | The name of the library as string.
17840     `platform`  | The used platform as string. Possible values are `win32`, `linux`, `apple`, `unix`, and `unknown`.
17841     `url`       | The URL of the project as string.
17842     `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).
17843 
17844     @liveexample{The following code shows an example output of the `meta()`
17845     function.,meta}
17846 
17847     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
17848     changes to any JSON value.
17849 
17850     @complexity Constant.
17851 
17852     @since 2.1.0
17853     */
17854     JSON_HEDLEY_WARN_UNUSED_RESULT
meta()17855     static basic_json meta()
17856     {
17857         basic_json result;
17858 
17859         result["copyright"] = "(C) 2013-2021 Niels Lohmann";
17860         result["name"] = "JSON for Modern C++";
17861         result["url"] = "https://github.com/nlohmann/json";
17862         result["version"]["string"] =
17863             std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
17864             std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
17865             std::to_string(NLOHMANN_JSON_VERSION_PATCH);
17866         result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
17867         result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
17868         result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
17869 
17870 #ifdef _WIN32
17871         result["platform"] = "win32";
17872 #elif defined __linux__
17873         result["platform"] = "linux";
17874 #elif defined __APPLE__
17875         result["platform"] = "apple";
17876 #elif defined __unix__
17877         result["platform"] = "unix";
17878 #else
17879         result["platform"] = "unknown";
17880 #endif
17881 
17882 #if defined(__ICC) || defined(__INTEL_COMPILER)
17883         result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
17884 #elif defined(__clang__)
17885         result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
17886 #elif defined(__GNUC__) || defined(__GNUG__)
17887         result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
17888 #elif defined(__HP_cc) || defined(__HP_aCC)
17889         result["compiler"] = "hp"
17890 #elif defined(__IBMCPP__)
17891         result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
17892 #elif defined(_MSC_VER)
17893         result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
17894 #elif defined(__PGI)
17895         result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
17896 #elif defined(__SUNPRO_CC)
17897         result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
17898 #else
17899         result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
17900 #endif
17901 
17902 #ifdef __cplusplus
17903         result["compiler"]["c++"] = std::to_string(__cplusplus);
17904 #else
17905         result["compiler"]["c++"] = "unknown";
17906 #endif
17907         return result;
17908     }
17909 
17910 
17911     ///////////////////////////
17912     // JSON value data types //
17913     ///////////////////////////
17914 
17915     /// @name JSON value data types
17916     /// The data types to store a JSON value. These types are derived from
17917     /// the template arguments passed to class @ref basic_json.
17918     /// @{
17919 
17920 #if defined(JSON_HAS_CPP_14)
17921     // Use transparent comparator if possible, combined with perfect forwarding
17922     // on find() and count() calls prevents unnecessary string construction.
17923     using object_comparator_t = std::less<>;
17924 #else
17925     using object_comparator_t = std::less<StringType>;
17926 #endif
17927 
17928     /*!
17929     @brief a type for an object
17930 
17931     [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON objects as follows:
17932     > An object is an unordered collection of zero or more name/value pairs,
17933     > where a name is a string and a value is a string, number, boolean, null,
17934     > object, or array.
17935 
17936     To store objects in C++, a type is defined by the template parameters
17937     described below.
17938 
17939     @tparam ObjectType  the container to store objects (e.g., `std::map` or
17940     `std::unordered_map`)
17941     @tparam StringType the type of the keys or names (e.g., `std::string`).
17942     The comparison function `std::less<StringType>` is used to order elements
17943     inside the container.
17944     @tparam AllocatorType the allocator to use for objects (e.g.,
17945     `std::allocator`)
17946 
17947     #### Default type
17948 
17949     With the default values for @a ObjectType (`std::map`), @a StringType
17950     (`std::string`), and @a AllocatorType (`std::allocator`), the default
17951     value for @a object_t is:
17952 
17953     @code {.cpp}
17954     std::map<
17955       std::string, // key_type
17956       basic_json, // value_type
17957       std::less<std::string>, // key_compare
17958       std::allocator<std::pair<const std::string, basic_json>> // allocator_type
17959     >
17960     @endcode
17961 
17962     #### Behavior
17963 
17964     The choice of @a object_t influences the behavior of the JSON class. With
17965     the default type, objects have the following behavior:
17966 
17967     - When all names are unique, objects will be interoperable in the sense
17968       that all software implementations receiving that object will agree on
17969       the name-value mappings.
17970     - When the names within an object are not unique, it is unspecified which
17971       one of the values for a given key will be chosen. For instance,
17972       `{"key": 2, "key": 1}` could be equal to either `{"key": 1}` or
17973       `{"key": 2}`.
17974     - Internally, name/value pairs are stored in lexicographical order of the
17975       names. Objects will also be serialized (see @ref dump) in this order.
17976       For instance, `{"b": 1, "a": 2}` and `{"a": 2, "b": 1}` will be stored
17977       and serialized as `{"a": 2, "b": 1}`.
17978     - When comparing objects, the order of the name/value pairs is irrelevant.
17979       This makes objects interoperable in the sense that they will not be
17980       affected by these differences. For instance, `{"b": 1, "a": 2}` and
17981       `{"a": 2, "b": 1}` will be treated as equal.
17982 
17983     #### Limits
17984 
17985     [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
17986     > An implementation may set limits on the maximum depth of nesting.
17987 
17988     In this class, the object's limit of nesting is not explicitly constrained.
17989     However, a maximum depth of nesting may be introduced by the compiler or
17990     runtime environment. A theoretical limit can be queried by calling the
17991     @ref max_size function of a JSON object.
17992 
17993     #### Storage
17994 
17995     Objects are stored as pointers in a @ref basic_json type. That is, for any
17996     access to object values, a pointer of type `object_t*` must be
17997     dereferenced.
17998 
17999     @sa see @ref array_t -- type for an array value
18000 
18001     @since version 1.0.0
18002 
18003     @note The order name/value pairs are added to the object is *not*
18004     preserved by the library. Therefore, iterating an object may return
18005     name/value pairs in a different order than they were originally stored. In
18006     fact, keys will be traversed in alphabetical order as `std::map` with
18007     `std::less` is used by default. Please note this behavior conforms to [RFC
18008     8259](https://tools.ietf.org/html/rfc8259), because any order implements the
18009     specified "unordered" nature of JSON objects.
18010     */
18011     using object_t = ObjectType<StringType,
18012           basic_json,
18013           object_comparator_t,
18014           AllocatorType<std::pair<const StringType,
18015           basic_json>>>;
18016 
18017     /*!
18018     @brief a type for an array
18019 
18020     [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON arrays as follows:
18021     > An array is an ordered sequence of zero or more values.
18022 
18023     To store objects in C++, a type is defined by the template parameters
18024     explained below.
18025 
18026     @tparam ArrayType  container type to store arrays (e.g., `std::vector` or
18027     `std::list`)
18028     @tparam AllocatorType allocator to use for arrays (e.g., `std::allocator`)
18029 
18030     #### Default type
18031 
18032     With the default values for @a ArrayType (`std::vector`) and @a
18033     AllocatorType (`std::allocator`), the default value for @a array_t is:
18034 
18035     @code {.cpp}
18036     std::vector<
18037       basic_json, // value_type
18038       std::allocator<basic_json> // allocator_type
18039     >
18040     @endcode
18041 
18042     #### Limits
18043 
18044     [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
18045     > An implementation may set limits on the maximum depth of nesting.
18046 
18047     In this class, the array's limit of nesting is not explicitly constrained.
18048     However, a maximum depth of nesting may be introduced by the compiler or
18049     runtime environment. A theoretical limit can be queried by calling the
18050     @ref max_size function of a JSON array.
18051 
18052     #### Storage
18053 
18054     Arrays are stored as pointers in a @ref basic_json type. That is, for any
18055     access to array values, a pointer of type `array_t*` must be dereferenced.
18056 
18057     @sa see @ref object_t -- type for an object value
18058 
18059     @since version 1.0.0
18060     */
18061     using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
18062 
18063     /*!
18064     @brief a type for a string
18065 
18066     [RFC 8259](https://tools.ietf.org/html/rfc8259) describes JSON strings as follows:
18067     > A string is a sequence of zero or more Unicode characters.
18068 
18069     To store objects in C++, a type is defined by the template parameter
18070     described below. Unicode values are split by the JSON class into
18071     byte-sized characters during deserialization.
18072 
18073     @tparam StringType  the container to store strings (e.g., `std::string`).
18074     Note this container is used for keys/names in objects, see @ref object_t.
18075 
18076     #### Default type
18077 
18078     With the default values for @a StringType (`std::string`), the default
18079     value for @a string_t is:
18080 
18081     @code {.cpp}
18082     std::string
18083     @endcode
18084 
18085     #### Encoding
18086 
18087     Strings are stored in UTF-8 encoding. Therefore, functions like
18088     `std::string::size()` or `std::string::length()` return the number of
18089     bytes in the string rather than the number of characters or glyphs.
18090 
18091     #### String comparison
18092 
18093     [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
18094     > Software implementations are typically required to test names of object
18095     > members for equality. Implementations that transform the textual
18096     > representation into sequences of Unicode code units and then perform the
18097     > comparison numerically, code unit by code unit, are interoperable in the
18098     > sense that implementations will agree in all cases on equality or
18099     > inequality of two strings. For example, implementations that compare
18100     > strings with escaped characters unconverted may incorrectly find that
18101     > `"a\\b"` and `"a\u005Cb"` are not equal.
18102 
18103     This implementation is interoperable as it does compare strings code unit
18104     by code unit.
18105 
18106     #### Storage
18107 
18108     String values are stored as pointers in a @ref basic_json type. That is,
18109     for any access to string values, a pointer of type `string_t*` must be
18110     dereferenced.
18111 
18112     @since version 1.0.0
18113     */
18114     using string_t = StringType;
18115 
18116     /*!
18117     @brief a type for a boolean
18118 
18119     [RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a
18120     type which differentiates the two literals `true` and `false`.
18121 
18122     To store objects in C++, a type is defined by the template parameter @a
18123     BooleanType which chooses the type to use.
18124 
18125     #### Default type
18126 
18127     With the default values for @a BooleanType (`bool`), the default value for
18128     @a boolean_t is:
18129 
18130     @code {.cpp}
18131     bool
18132     @endcode
18133 
18134     #### Storage
18135 
18136     Boolean values are stored directly inside a @ref basic_json type.
18137 
18138     @since version 1.0.0
18139     */
18140     using boolean_t = BooleanType;
18141 
18142     /*!
18143     @brief a type for a number (integer)
18144 
18145     [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18146     > The representation of numbers is similar to that used in most
18147     > programming languages. A number is represented in base 10 using decimal
18148     > digits. It contains an integer component that may be prefixed with an
18149     > optional minus sign, which may be followed by a fraction part and/or an
18150     > exponent part. Leading zeros are not allowed. (...) Numeric values that
18151     > cannot be represented in the grammar below (such as Infinity and NaN)
18152     > are not permitted.
18153 
18154     This description includes both integer and floating-point numbers.
18155     However, C++ allows more precise storage if it is known whether the number
18156     is a signed integer, an unsigned integer or a floating-point number.
18157     Therefore, three different types, @ref number_integer_t, @ref
18158     number_unsigned_t and @ref number_float_t are used.
18159 
18160     To store integer numbers in C++, a type is defined by the template
18161     parameter @a NumberIntegerType which chooses the type to use.
18162 
18163     #### Default type
18164 
18165     With the default values for @a NumberIntegerType (`int64_t`), the default
18166     value for @a number_integer_t is:
18167 
18168     @code {.cpp}
18169     int64_t
18170     @endcode
18171 
18172     #### Default behavior
18173 
18174     - The restrictions about leading zeros is not enforced in C++. Instead,
18175       leading zeros in integer literals lead to an interpretation as octal
18176       number. Internally, the value will be stored as decimal number. For
18177       instance, the C++ integer literal `010` will be serialized to `8`.
18178       During deserialization, leading zeros yield an error.
18179     - Not-a-number (NaN) values will be serialized to `null`.
18180 
18181     #### Limits
18182 
18183     [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
18184     > An implementation may set limits on the range and precision of numbers.
18185 
18186     When the default type is used, the maximal integer number that can be
18187     stored is `9223372036854775807` (INT64_MAX) and the minimal integer number
18188     that can be stored is `-9223372036854775808` (INT64_MIN). Integer numbers
18189     that are out of range will yield over/underflow when used in a
18190     constructor. During deserialization, too large or small integer numbers
18191     will be automatically be stored as @ref number_unsigned_t or @ref
18192     number_float_t.
18193 
18194     [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
18195     > Note that when such software is used, numbers that are integers and are
18196     > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
18197     > that implementations will agree exactly on their numeric values.
18198 
18199     As this range is a subrange of the exactly supported range [INT64_MIN,
18200     INT64_MAX], this class's integer type is interoperable.
18201 
18202     #### Storage
18203 
18204     Integer number values are stored directly inside a @ref basic_json type.
18205 
18206     @sa see @ref number_float_t -- type for number values (floating-point)
18207 
18208     @sa see @ref number_unsigned_t -- type for number values (unsigned integer)
18209 
18210     @since version 1.0.0
18211     */
18212     using number_integer_t = NumberIntegerType;
18213 
18214     /*!
18215     @brief a type for a number (unsigned)
18216 
18217     [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18218     > The representation of numbers is similar to that used in most
18219     > programming languages. A number is represented in base 10 using decimal
18220     > digits. It contains an integer component that may be prefixed with an
18221     > optional minus sign, which may be followed by a fraction part and/or an
18222     > exponent part. Leading zeros are not allowed. (...) Numeric values that
18223     > cannot be represented in the grammar below (such as Infinity and NaN)
18224     > are not permitted.
18225 
18226     This description includes both integer and floating-point numbers.
18227     However, C++ allows more precise storage if it is known whether the number
18228     is a signed integer, an unsigned integer or a floating-point number.
18229     Therefore, three different types, @ref number_integer_t, @ref
18230     number_unsigned_t and @ref number_float_t are used.
18231 
18232     To store unsigned integer numbers in C++, a type is defined by the
18233     template parameter @a NumberUnsignedType which chooses the type to use.
18234 
18235     #### Default type
18236 
18237     With the default values for @a NumberUnsignedType (`uint64_t`), the
18238     default value for @a number_unsigned_t is:
18239 
18240     @code {.cpp}
18241     uint64_t
18242     @endcode
18243 
18244     #### Default behavior
18245 
18246     - The restrictions about leading zeros is not enforced in C++. Instead,
18247       leading zeros in integer literals lead to an interpretation as octal
18248       number. Internally, the value will be stored as decimal number. For
18249       instance, the C++ integer literal `010` will be serialized to `8`.
18250       During deserialization, leading zeros yield an error.
18251     - Not-a-number (NaN) values will be serialized to `null`.
18252 
18253     #### Limits
18254 
18255     [RFC 8259](https://tools.ietf.org/html/rfc8259) specifies:
18256     > An implementation may set limits on the range and precision of numbers.
18257 
18258     When the default type is used, the maximal integer number that can be
18259     stored is `18446744073709551615` (UINT64_MAX) and the minimal integer
18260     number that can be stored is `0`. Integer numbers that are out of range
18261     will yield over/underflow when used in a constructor. During
18262     deserialization, too large or small integer numbers will be automatically
18263     be stored as @ref number_integer_t or @ref number_float_t.
18264 
18265     [RFC 8259](https://tools.ietf.org/html/rfc8259) further states:
18266     > Note that when such software is used, numbers that are integers and are
18267     > in the range \f$[-2^{53}+1, 2^{53}-1]\f$ are interoperable in the sense
18268     > that implementations will agree exactly on their numeric values.
18269 
18270     As this range is a subrange (when considered in conjunction with the
18271     number_integer_t type) of the exactly supported range [0, UINT64_MAX],
18272     this class's integer type is interoperable.
18273 
18274     #### Storage
18275 
18276     Integer number values are stored directly inside a @ref basic_json type.
18277 
18278     @sa see @ref number_float_t -- type for number values (floating-point)
18279     @sa see @ref number_integer_t -- type for number values (integer)
18280 
18281     @since version 2.0.0
18282     */
18283     using number_unsigned_t = NumberUnsignedType;
18284 
18285     /*!
18286     @brief a type for a number (floating-point)
18287 
18288     [RFC 8259](https://tools.ietf.org/html/rfc8259) describes numbers as follows:
18289     > The representation of numbers is similar to that used in most
18290     > programming languages. A number is represented in base 10 using decimal
18291     > digits. It contains an integer component that may be prefixed with an
18292     > optional minus sign, which may be followed by a fraction part and/or an
18293     > exponent part. Leading zeros are not allowed. (...) Numeric values that
18294     > cannot be represented in the grammar below (such as Infinity and NaN)
18295     > are not permitted.
18296 
18297     This description includes both integer and floating-point numbers.
18298     However, C++ allows more precise storage if it is known whether the number
18299     is a signed integer, an unsigned integer or a floating-point number.
18300     Therefore, three different types, @ref number_integer_t, @ref
18301     number_unsigned_t and @ref number_float_t are used.
18302 
18303     To store floating-point numbers in C++, a type is defined by the template
18304     parameter @a NumberFloatType which chooses the type to use.
18305 
18306     #### Default type
18307 
18308     With the default values for @a NumberFloatType (`double`), the default
18309     value for @a number_float_t is:
18310 
18311     @code {.cpp}
18312     double
18313     @endcode
18314 
18315     #### Default behavior
18316 
18317     - The restrictions about leading zeros is not enforced in C++. Instead,
18318       leading zeros in floating-point literals will be ignored. Internally,
18319       the value will be stored as decimal number. For instance, the C++
18320       floating-point literal `01.2` will be serialized to `1.2`. During
18321       deserialization, leading zeros yield an error.
18322     - Not-a-number (NaN) values will be serialized to `null`.
18323 
18324     #### Limits
18325 
18326     [RFC 8259](https://tools.ietf.org/html/rfc8259) states:
18327     > This specification allows implementations to set limits on the range and
18328     > precision of numbers accepted. Since software that implements IEEE
18329     > 754-2008 binary64 (double precision) numbers is generally available and
18330     > widely used, good interoperability can be achieved by implementations
18331     > that expect no more precision or range than these provide, in the sense
18332     > that implementations will approximate JSON numbers within the expected
18333     > precision.
18334 
18335     This implementation does exactly follow this approach, as it uses double
18336     precision floating-point numbers. Note values smaller than
18337     `-1.79769313486232e+308` and values greater than `1.79769313486232e+308`
18338     will be stored as NaN internally and be serialized to `null`.
18339 
18340     #### Storage
18341 
18342     Floating-point number values are stored directly inside a @ref basic_json
18343     type.
18344 
18345     @sa see @ref number_integer_t -- type for number values (integer)
18346 
18347     @sa see @ref number_unsigned_t -- type for number values (unsigned integer)
18348 
18349     @since version 1.0.0
18350     */
18351     using number_float_t = NumberFloatType;
18352 
18353     /*!
18354     @brief a type for a packed binary type
18355 
18356     This type is a type designed to carry binary data that appears in various
18357     serialized formats, such as CBOR's Major Type 2, MessagePack's bin, and
18358     BSON's generic binary subtype. This type is NOT a part of standard JSON and
18359     exists solely for compatibility with these binary types. As such, it is
18360     simply defined as an ordered sequence of zero or more byte values.
18361 
18362     Additionally, as an implementation detail, the subtype of the binary data is
18363     carried around as a `std::uint8_t`, which is compatible with both of the
18364     binary data formats that use binary subtyping, (though the specific
18365     numbering is incompatible with each other, and it is up to the user to
18366     translate between them).
18367 
18368     [CBOR's RFC 7049](https://tools.ietf.org/html/rfc7049) describes this type
18369     as:
18370     > Major type 2: a byte string. The string's length in bytes is represented
18371     > following the rules for positive integers (major type 0).
18372 
18373     [MessagePack's documentation on the bin type
18374     family](https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family)
18375     describes this type as:
18376     > Bin format family stores an byte array in 2, 3, or 5 bytes of extra bytes
18377     > in addition to the size of the byte array.
18378 
18379     [BSON's specifications](http://bsonspec.org/spec.html) describe several
18380     binary types; however, this type is intended to represent the generic binary
18381     type which has the description:
18382     > Generic binary subtype - This is the most commonly used binary subtype and
18383     > should be the 'default' for drivers and tools.
18384 
18385     None of these impose any limitations on the internal representation other
18386     than the basic unit of storage be some type of array whose parts are
18387     decomposable into bytes.
18388 
18389     The default representation of this binary format is a
18390     `std::vector<std::uint8_t>`, which is a very common way to represent a byte
18391     array in modern C++.
18392 
18393     #### Default type
18394 
18395     The default values for @a BinaryType is `std::vector<std::uint8_t>`
18396 
18397     #### Storage
18398 
18399     Binary Arrays are stored as pointers in a @ref basic_json type. That is,
18400     for any access to array values, a pointer of the type `binary_t*` must be
18401     dereferenced.
18402 
18403     #### Notes on subtypes
18404 
18405     - CBOR
18406        - Binary values are represented as byte strings. Subtypes are serialized
18407          as tagged values.
18408     - MessagePack
18409        - If a subtype is given and the binary array contains exactly 1, 2, 4, 8,
18410          or 16 elements, the fixext family (fixext1, fixext2, fixext4, fixext8)
18411          is used. For other sizes, the ext family (ext8, ext16, ext32) is used.
18412          The subtype is then added as singed 8-bit integer.
18413        - If no subtype is given, the bin family (bin8, bin16, bin32) is used.
18414     - BSON
18415        - If a subtype is given, it is used and added as unsigned 8-bit integer.
18416        - If no subtype is given, the generic binary subtype 0x00 is used.
18417 
18418     @sa see @ref binary -- create a binary array
18419 
18420     @since version 3.8.0
18421     */
18422     using binary_t = nlohmann::byte_container_with_subtype<BinaryType>;
18423     /// @}
18424 
18425   private:
18426 
18427     /// helper for exception-safe object creation
18428     template<typename T, typename... Args>
18429     JSON_HEDLEY_RETURNS_NON_NULL
create(Args &&...args)18430     static T* create(Args&& ... args)
18431     {
18432         AllocatorType<T> alloc;
18433         using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18434 
18435         auto deleter = [&](T * obj)
18436         {
18437             AllocatorTraits::deallocate(alloc, obj, 1);
18438         };
18439         std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18440         AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18441         JSON_ASSERT(obj != nullptr);
18442         return obj.release();
18443     }
18444 
18445     ////////////////////////
18446     // JSON value storage //
18447     ////////////////////////
18448 
18449   JSON_PRIVATE_UNLESS_TESTED:
18450     /*!
18451     @brief a JSON value
18452 
18453     The actual storage for a JSON value of the @ref basic_json class. This
18454     union combines the different storage types for the JSON value types
18455     defined in @ref value_t.
18456 
18457     JSON type | value_t type    | used type
18458     --------- | --------------- | ------------------------
18459     object    | object          | pointer to @ref object_t
18460     array     | array           | pointer to @ref array_t
18461     string    | string          | pointer to @ref string_t
18462     boolean   | boolean         | @ref boolean_t
18463     number    | number_integer  | @ref number_integer_t
18464     number    | number_unsigned | @ref number_unsigned_t
18465     number    | number_float    | @ref number_float_t
18466     binary    | binary          | pointer to @ref binary_t
18467     null      | null            | *no value is stored*
18468 
18469     @note Variable-length types (objects, arrays, and strings) are stored as
18470     pointers. The size of the union should not exceed 64 bits if the default
18471     value types are used.
18472 
18473     @since version 1.0.0
18474     */
18475     union json_value
18476     {
18477         /// object (stored with pointer to save storage)
18478         object_t* object;
18479         /// array (stored with pointer to save storage)
18480         array_t* array;
18481         /// string (stored with pointer to save storage)
18482         string_t* string;
18483         /// binary (stored with pointer to save storage)
18484         binary_t* binary;
18485         /// boolean
18486         boolean_t boolean;
18487         /// number (integer)
18488         number_integer_t number_integer;
18489         /// number (unsigned integer)
18490         number_unsigned_t number_unsigned;
18491         /// number (floating-point)
18492         number_float_t number_float;
18493 
18494         /// default constructor (for null values)
18495         json_value() = default;
18496         /// constructor for booleans
json_value(boolean_t v)18497         json_value(boolean_t v) noexcept : boolean(v) {}
18498         /// constructor for numbers (integer)
json_value(number_integer_t v)18499         json_value(number_integer_t v) noexcept : number_integer(v) {}
18500         /// constructor for numbers (unsigned)
json_value(number_unsigned_t v)18501         json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
18502         /// constructor for numbers (floating-point)
json_value(number_float_t v)18503         json_value(number_float_t v) noexcept : number_float(v) {}
18504         /// constructor for empty values of a given type
json_value(value_t t)18505         json_value(value_t t)
18506         {
18507             switch (t)
18508             {
18509                 case value_t::object:
18510                 {
18511                     object = create<object_t>();
18512                     break;
18513                 }
18514 
18515                 case value_t::array:
18516                 {
18517                     array = create<array_t>();
18518                     break;
18519                 }
18520 
18521                 case value_t::string:
18522                 {
18523                     string = create<string_t>("");
18524                     break;
18525                 }
18526 
18527                 case value_t::binary:
18528                 {
18529                     binary = create<binary_t>();
18530                     break;
18531                 }
18532 
18533                 case value_t::boolean:
18534                 {
18535                     boolean = boolean_t(false);
18536                     break;
18537                 }
18538 
18539                 case value_t::number_integer:
18540                 {
18541                     number_integer = number_integer_t(0);
18542                     break;
18543                 }
18544 
18545                 case value_t::number_unsigned:
18546                 {
18547                     number_unsigned = number_unsigned_t(0);
18548                     break;
18549                 }
18550 
18551                 case value_t::number_float:
18552                 {
18553                     number_float = number_float_t(0.0);
18554                     break;
18555                 }
18556 
18557                 case value_t::null:
18558                 {
18559                     object = nullptr;  // silence warning, see #821
18560                     break;
18561                 }
18562 
18563                 case value_t::discarded:
18564                 default:
18565                 {
18566                     object = nullptr;  // silence warning, see #821
18567                     if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
18568                     {
18569                         JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.4", basic_json())); // LCOV_EXCL_LINE
18570                     }
18571                     break;
18572                 }
18573             }
18574         }
18575 
18576         /// constructor for strings
json_value(const string_t & value)18577         json_value(const string_t& value)
18578         {
18579             string = create<string_t>(value);
18580         }
18581 
18582         /// constructor for rvalue strings
json_value(string_t && value)18583         json_value(string_t&& value)
18584         {
18585             string = create<string_t>(std::move(value));
18586         }
18587 
18588         /// constructor for objects
json_value(const object_t & value)18589         json_value(const object_t& value)
18590         {
18591             object = create<object_t>(value);
18592         }
18593 
18594         /// constructor for rvalue objects
json_value(object_t && value)18595         json_value(object_t&& value)
18596         {
18597             object = create<object_t>(std::move(value));
18598         }
18599 
18600         /// constructor for arrays
json_value(const array_t & value)18601         json_value(const array_t& value)
18602         {
18603             array = create<array_t>(value);
18604         }
18605 
18606         /// constructor for rvalue arrays
json_value(array_t && value)18607         json_value(array_t&& value)
18608         {
18609             array = create<array_t>(std::move(value));
18610         }
18611 
18612         /// constructor for binary arrays
json_value(const typename binary_t::container_type & value)18613         json_value(const typename binary_t::container_type& value)
18614         {
18615             binary = create<binary_t>(value);
18616         }
18617 
18618         /// constructor for rvalue binary arrays
json_value(typename binary_t::container_type && value)18619         json_value(typename binary_t::container_type&& value)
18620         {
18621             binary = create<binary_t>(std::move(value));
18622         }
18623 
18624         /// constructor for binary arrays (internal type)
json_value(const binary_t & value)18625         json_value(const binary_t& value)
18626         {
18627             binary = create<binary_t>(value);
18628         }
18629 
18630         /// constructor for rvalue binary arrays (internal type)
json_value(binary_t && value)18631         json_value(binary_t&& value)
18632         {
18633             binary = create<binary_t>(std::move(value));
18634         }
18635 
destroy(value_t t)18636         void destroy(value_t t)
18637         {
18638             if (t == value_t::array || t == value_t::object)
18639             {
18640                 // flatten the current json_value to a heap-allocated stack
18641                 std::vector<basic_json> stack;
18642 
18643                 // move the top-level items to stack
18644                 if (t == value_t::array)
18645                 {
18646                     stack.reserve(array->size());
18647                     std::move(array->begin(), array->end(), std::back_inserter(stack));
18648                 }
18649                 else
18650                 {
18651                     stack.reserve(object->size());
18652                     for (auto&& it : *object)
18653                     {
18654                         stack.push_back(std::move(it.second));
18655                     }
18656                 }
18657 
18658                 while (!stack.empty())
18659                 {
18660                     // move the last item to local variable to be processed
18661                     basic_json current_item(std::move(stack.back()));
18662                     stack.pop_back();
18663 
18664                     // if current_item is array/object, move
18665                     // its children to the stack to be processed later
18666                     if (current_item.is_array())
18667                     {
18668                         std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
18669 
18670                         current_item.m_value.array->clear();
18671                     }
18672                     else if (current_item.is_object())
18673                     {
18674                         for (auto&& it : *current_item.m_value.object)
18675                         {
18676                             stack.push_back(std::move(it.second));
18677                         }
18678 
18679                         current_item.m_value.object->clear();
18680                     }
18681 
18682                     // it's now safe that current_item get destructed
18683                     // since it doesn't have any children
18684                 }
18685             }
18686 
18687             switch (t)
18688             {
18689                 case value_t::object:
18690                 {
18691                     AllocatorType<object_t> alloc;
18692                     std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18693                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18694                     break;
18695                 }
18696 
18697                 case value_t::array:
18698                 {
18699                     AllocatorType<array_t> alloc;
18700                     std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18701                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18702                     break;
18703                 }
18704 
18705                 case value_t::string:
18706                 {
18707                     AllocatorType<string_t> alloc;
18708                     std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18709                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18710                     break;
18711                 }
18712 
18713                 case value_t::binary:
18714                 {
18715                     AllocatorType<binary_t> alloc;
18716                     std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18717                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18718                     break;
18719                 }
18720 
18721                 case value_t::null:
18722                 case value_t::boolean:
18723                 case value_t::number_integer:
18724                 case value_t::number_unsigned:
18725                 case value_t::number_float:
18726                 case value_t::discarded:
18727                 default:
18728                 {
18729                     break;
18730                 }
18731             }
18732         }
18733     };
18734 
18735   private:
18736     /*!
18737     @brief checks the class invariants
18738 
18739     This function asserts the class invariants. It needs to be called at the
18740     end of every constructor to make sure that created objects respect the
18741     invariant. Furthermore, it has to be called each time the type of a JSON
18742     value is changed, because the invariant expresses a relationship between
18743     @a m_type and @a m_value.
18744 
18745     Furthermore, the parent relation is checked for arrays and objects: If
18746     @a check_parents true and the value is an array or object, then the
18747     container's elements must have the current value as parent.
18748 
18749     @param[in] check_parents  whether the parent relation should be checked.
18750                The value is true by default and should only be set to false
18751                during destruction of objects when the invariant does not
18752                need to hold.
18753     */
assert_invariant(bool check_parents=true) const18754     void assert_invariant(bool check_parents = true) const noexcept
18755     {
18756         JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18757         JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18758         JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18759         JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18760 
18761 #if JSON_DIAGNOSTICS
18762         JSON_TRY
18763         {
18764             // cppcheck-suppress assertWithSideEffect
18765             JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
18766             {
18767                 return j.m_parent == this;
18768             }));
18769         }
18770         JSON_CATCH(...) {} // LCOV_EXCL_LINE
18771 #endif
18772         static_cast<void>(check_parents);
18773     }
18774 
set_parents()18775     void set_parents()
18776     {
18777 #if JSON_DIAGNOSTICS
18778         switch (m_type)
18779         {
18780             case value_t::array:
18781             {
18782                 for (auto& element : *m_value.array)
18783                 {
18784                     element.m_parent = this;
18785                 }
18786                 break;
18787             }
18788 
18789             case value_t::object:
18790             {
18791                 for (auto& element : *m_value.object)
18792                 {
18793                     element.second.m_parent = this;
18794                 }
18795                 break;
18796             }
18797 
18798             case value_t::null:
18799             case value_t::string:
18800             case value_t::boolean:
18801             case value_t::number_integer:
18802             case value_t::number_unsigned:
18803             case value_t::number_float:
18804             case value_t::binary:
18805             case value_t::discarded:
18806             default:
18807                 break;
18808         }
18809 #endif
18810     }
18811 
set_parents(iterator it,typename iterator::difference_type count)18812     iterator set_parents(iterator it, typename iterator::difference_type count)
18813     {
18814 #if JSON_DIAGNOSTICS
18815         for (typename iterator::difference_type i = 0; i < count; ++i)
18816         {
18817             (it + i)->m_parent = this;
18818         }
18819 #else
18820         static_cast<void>(count);
18821 #endif
18822         return it;
18823     }
18824 
set_parent(reference j,std::size_t old_capacity=std::size_t (-1))18825     reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1))
18826     {
18827 #if JSON_DIAGNOSTICS
18828         if (old_capacity != std::size_t(-1))
18829         {
18830             // see https://github.com/nlohmann/json/issues/2838
18831             JSON_ASSERT(type() == value_t::array);
18832             if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
18833             {
18834                 // capacity has changed: update all parents
18835                 set_parents();
18836                 return j;
18837             }
18838         }
18839 
18840         // ordered_json uses a vector internally, so pointers could have
18841         // been invalidated; see https://github.com/nlohmann/json/issues/2962
18842 #ifdef JSON_HEDLEY_MSVC_VERSION
18843 #pragma warning(push )
18844 #pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
18845 #endif
18846         if (detail::is_ordered_map<object_t>::value)
18847         {
18848             set_parents();
18849             return j;
18850         }
18851 #ifdef JSON_HEDLEY_MSVC_VERSION
18852 #pragma warning( pop )
18853 #endif
18854 
18855         j.m_parent = this;
18856 #else
18857         static_cast<void>(j);
18858         static_cast<void>(old_capacity);
18859 #endif
18860         return j;
18861     }
18862 
18863   public:
18864     //////////////////////////
18865     // JSON parser callback //
18866     //////////////////////////
18867 
18868     /*!
18869     @brief parser event types
18870 
18871     The parser callback distinguishes the following events:
18872     - `object_start`: the parser read `{` and started to process a JSON object
18873     - `key`: the parser read a key of a value in an object
18874     - `object_end`: the parser read `}` and finished processing a JSON object
18875     - `array_start`: the parser read `[` and started to process a JSON array
18876     - `array_end`: the parser read `]` and finished processing a JSON array
18877     - `value`: the parser finished reading a JSON value
18878 
18879     @image html callback_events.png "Example when certain parse events are triggered"
18880 
18881     @sa see @ref parser_callback_t for more information and examples
18882     */
18883     using parse_event_t = detail::parse_event_t;
18884 
18885     /*!
18886     @brief per-element parser callback type
18887 
18888     With a parser callback function, the result of parsing a JSON text can be
18889     influenced. When passed to @ref parse, it is called on certain events
18890     (passed as @ref parse_event_t via parameter @a event) with a set recursion
18891     depth @a depth and context JSON value @a parsed. The return value of the
18892     callback function is a boolean indicating whether the element that emitted
18893     the callback shall be kept or not.
18894 
18895     We distinguish six scenarios (determined by the event type) in which the
18896     callback function can be called. The following table describes the values
18897     of the parameters @a depth, @a event, and @a parsed.
18898 
18899     parameter @a event | description | parameter @a depth | parameter @a parsed
18900     ------------------ | ----------- | ------------------ | -------------------
18901     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
18902     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
18903     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
18904     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
18905     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
18906     parse_event_t::value | the parser finished reading a JSON value | depth of the value | the parsed JSON value
18907 
18908     @image html callback_events.png "Example when certain parse events are triggered"
18909 
18910     Discarding a value (i.e., returning `false`) has different effects
18911     depending on the context in which function was called:
18912 
18913     - Discarded values in structured types are skipped. That is, the parser
18914       will behave as if the discarded value was never read.
18915     - In case a value outside a structured type is skipped, it is replaced
18916       with `null`. This case happens if the top-level element is skipped.
18917 
18918     @param[in] depth  the depth of the recursion during parsing
18919 
18920     @param[in] event  an event of type parse_event_t indicating the context in
18921     the callback function has been called
18922 
18923     @param[in,out] parsed  the current intermediate parse result; note that
18924     writing to this value has no effect for parse_event_t::key events
18925 
18926     @return Whether the JSON value which called the function during parsing
18927     should be kept (`true`) or not (`false`). In the latter case, it is either
18928     skipped completely or replaced by an empty discarded object.
18929 
18930     @sa see @ref parse for examples
18931 
18932     @since version 1.0.0
18933     */
18934     using parser_callback_t = detail::parser_callback_t<basic_json>;
18935 
18936     //////////////////
18937     // constructors //
18938     //////////////////
18939 
18940     /// @name constructors and destructors
18941     /// Constructors of class @ref basic_json, copy/move constructor, copy
18942     /// assignment, static functions creating objects, and the destructor.
18943     /// @{
18944 
18945     /*!
18946     @brief create an empty value with a given type
18947 
18948     Create an empty JSON value with a given type. The value will be default
18949     initialized with an empty value which depends on the type:
18950 
18951     Value type  | initial value
18952     ----------- | -------------
18953     null        | `null`
18954     boolean     | `false`
18955     string      | `""`
18956     number      | `0`
18957     object      | `{}`
18958     array       | `[]`
18959     binary      | empty array
18960 
18961     @param[in] v  the type of the value to create
18962 
18963     @complexity Constant.
18964 
18965     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
18966     changes to any JSON value.
18967 
18968     @liveexample{The following code shows the constructor for different @ref
18969     value_t values,basic_json__value_t}
18970 
18971     @sa see @ref clear() -- restores the postcondition of this constructor
18972 
18973     @since version 1.0.0
18974     */
basic_json(const value_t v)18975     basic_json(const value_t v)
18976         : m_type(v), m_value(v)
18977     {
18978         assert_invariant();
18979     }
18980 
18981     /*!
18982     @brief create a null object
18983 
18984     Create a `null` JSON value. It either takes a null pointer as parameter
18985     (explicitly creating `null`) or no parameter (implicitly creating `null`).
18986     The passed null pointer itself is not read -- it is only used to choose
18987     the right constructor.
18988 
18989     @complexity Constant.
18990 
18991     @exceptionsafety No-throw guarantee: this constructor never throws
18992     exceptions.
18993 
18994     @liveexample{The following code shows the constructor with and without a
18995     null pointer parameter.,basic_json__nullptr_t}
18996 
18997     @since version 1.0.0
18998     */
basic_json(std::nullptr_t=nullptr)18999     basic_json(std::nullptr_t = nullptr) noexcept
19000         : basic_json(value_t::null)
19001     {
19002         assert_invariant();
19003     }
19004 
19005     /*!
19006     @brief create a JSON value
19007 
19008     This is a "catch all" constructor for all compatible JSON types; that is,
19009     types for which a `to_json()` method exists. The constructor forwards the
19010     parameter @a val to that method (to `json_serializer<U>::to_json` method
19011     with `U = uncvref_t<CompatibleType>`, to be exact).
19012 
19013     Template type @a CompatibleType includes, but is not limited to, the
19014     following types:
19015     - **arrays**: @ref array_t and all kinds of compatible containers such as
19016       `std::vector`, `std::deque`, `std::list`, `std::forward_list`,
19017       `std::array`, `std::valarray`, `std::set`, `std::unordered_set`,
19018       `std::multiset`, and `std::unordered_multiset` with a `value_type` from
19019       which a @ref basic_json value can be constructed.
19020     - **objects**: @ref object_t and all kinds of compatible associative
19021       containers such as `std::map`, `std::unordered_map`, `std::multimap`,
19022       and `std::unordered_multimap` with a `key_type` compatible to
19023       @ref string_t and a `value_type` from which a @ref basic_json value can
19024       be constructed.
19025     - **strings**: @ref string_t, string literals, and all compatible string
19026       containers can be used.
19027     - **numbers**: @ref number_integer_t, @ref number_unsigned_t,
19028       @ref number_float_t, and all convertible number types such as `int`,
19029       `size_t`, `int64_t`, `float` or `double` can be used.
19030     - **boolean**: @ref boolean_t / `bool` can be used.
19031     - **binary**: @ref binary_t / `std::vector<std::uint8_t>` may be used,
19032       unfortunately because string literals cannot be distinguished from binary
19033       character arrays by the C++ type system, all types compatible with `const
19034       char*` will be directed to the string constructor instead.  This is both
19035       for backwards compatibility, and due to the fact that a binary type is not
19036       a standard JSON type.
19037 
19038     See the examples below.
19039 
19040     @tparam CompatibleType a type such that:
19041     - @a CompatibleType is not derived from `std::istream`,
19042     - @a CompatibleType is not @ref basic_json (to avoid hijacking copy/move
19043          constructors),
19044     - @a CompatibleType is not a different @ref basic_json type (i.e. with different template arguments)
19045     - @a CompatibleType is not a @ref basic_json nested type (e.g.,
19046          @ref json_pointer, @ref iterator, etc ...)
19047     - `json_serializer<U>` has a `to_json(basic_json_t&, CompatibleType&&)` method
19048 
19049     @tparam U = `uncvref_t<CompatibleType>`
19050 
19051     @param[in] val the value to be forwarded to the respective constructor
19052 
19053     @complexity Usually linear in the size of the passed @a val, also
19054                 depending on the implementation of the called `to_json()`
19055                 method.
19056 
19057     @exceptionsafety Depends on the called constructor. For types directly
19058     supported by the library (i.e., all types for which no `to_json()` function
19059     was provided), strong guarantee holds: if an exception is thrown, there are
19060     no changes to any JSON value.
19061 
19062     @liveexample{The following code shows the constructor with several
19063     compatible types.,basic_json__CompatibleType}
19064 
19065     @since version 2.1.0
19066     */
19067     template < typename CompatibleType,
19068                typename U = detail::uncvref_t<CompatibleType>,
19069                detail::enable_if_t <
19070                    !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
basic_json(CompatibleType && val)19071     basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
19072                 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
19073                                            std::forward<CompatibleType>(val))))
19074     {
19075         JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
19076         set_parents();
19077         assert_invariant();
19078     }
19079 
19080     /*!
19081     @brief create a JSON value from an existing one
19082 
19083     This is a constructor for existing @ref basic_json types.
19084     It does not hijack copy/move constructors, since the parameter has different
19085     template arguments than the current ones.
19086 
19087     The constructor tries to convert the internal @ref m_value of the parameter.
19088 
19089     @tparam BasicJsonType a type such that:
19090     - @a BasicJsonType is a @ref basic_json type.
19091     - @a BasicJsonType has different template arguments than @ref basic_json_t.
19092 
19093     @param[in] val the @ref basic_json value to be converted.
19094 
19095     @complexity Usually linear in the size of the passed @a val, also
19096                 depending on the implementation of the called `to_json()`
19097                 method.
19098 
19099     @exceptionsafety Depends on the called constructor. For types directly
19100     supported by the library (i.e., all types for which no `to_json()` function
19101     was provided), strong guarantee holds: if an exception is thrown, there are
19102     no changes to any JSON value.
19103 
19104     @since version 3.2.0
19105     */
19106     template < typename BasicJsonType,
19107                detail::enable_if_t <
19108                    detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
basic_json(const BasicJsonType & val)19109     basic_json(const BasicJsonType& val)
19110     {
19111         using other_boolean_t = typename BasicJsonType::boolean_t;
19112         using other_number_float_t = typename BasicJsonType::number_float_t;
19113         using other_number_integer_t = typename BasicJsonType::number_integer_t;
19114         using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
19115         using other_string_t = typename BasicJsonType::string_t;
19116         using other_object_t = typename BasicJsonType::object_t;
19117         using other_array_t = typename BasicJsonType::array_t;
19118         using other_binary_t = typename BasicJsonType::binary_t;
19119 
19120         switch (val.type())
19121         {
19122             case value_t::boolean:
19123                 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
19124                 break;
19125             case value_t::number_float:
19126                 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
19127                 break;
19128             case value_t::number_integer:
19129                 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
19130                 break;
19131             case value_t::number_unsigned:
19132                 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
19133                 break;
19134             case value_t::string:
19135                 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
19136                 break;
19137             case value_t::object:
19138                 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
19139                 break;
19140             case value_t::array:
19141                 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
19142                 break;
19143             case value_t::binary:
19144                 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
19145                 break;
19146             case value_t::null:
19147                 *this = nullptr;
19148                 break;
19149             case value_t::discarded:
19150                 m_type = value_t::discarded;
19151                 break;
19152             default:            // LCOV_EXCL_LINE
19153                 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19154         }
19155         set_parents();
19156         assert_invariant();
19157     }
19158 
19159     /*!
19160     @brief create a container (array or object) from an initializer list
19161 
19162     Creates a JSON value of type array or object from the passed initializer
19163     list @a init. In case @a type_deduction is `true` (default), the type of
19164     the JSON value to be created is deducted from the initializer list @a init
19165     according to the following rules:
19166 
19167     1. If the list is empty, an empty JSON object value `{}` is created.
19168     2. If the list consists of pairs whose first element is a string, a JSON
19169        object value is created where the first elements of the pairs are
19170        treated as keys and the second elements are as values.
19171     3. In all other cases, an array is created.
19172 
19173     The rules aim to create the best fit between a C++ initializer list and
19174     JSON values. The rationale is as follows:
19175 
19176     1. The empty initializer list is written as `{}` which is exactly an empty
19177        JSON object.
19178     2. C++ has no way of describing mapped types other than to list a list of
19179        pairs. As JSON requires that keys must be of type string, rule 2 is the
19180        weakest constraint one can pose on initializer lists to interpret them
19181        as an object.
19182     3. In all other cases, the initializer list could not be interpreted as
19183        JSON object type, so interpreting it as JSON array type is safe.
19184 
19185     With the rules described above, the following JSON values cannot be
19186     expressed by an initializer list:
19187 
19188     - the empty array (`[]`): use @ref array(initializer_list_t)
19189       with an empty initializer list in this case
19190     - arrays whose elements satisfy rule 2: use @ref
19191       array(initializer_list_t) with the same initializer list
19192       in this case
19193 
19194     @note When used without parentheses around an empty initializer list, @ref
19195     basic_json() is called instead of this function, yielding the JSON null
19196     value.
19197 
19198     @param[in] init  initializer list with JSON values
19199 
19200     @param[in] type_deduction internal parameter; when set to `true`, the type
19201     of the JSON value is deducted from the initializer list @a init; when set
19202     to `false`, the type provided via @a manual_type is forced. This mode is
19203     used by the functions @ref array(initializer_list_t) and
19204     @ref object(initializer_list_t).
19205 
19206     @param[in] manual_type internal parameter; when @a type_deduction is set
19207     to `false`, the created JSON value will use the provided type (only @ref
19208     value_t::array and @ref value_t::object are valid); when @a type_deduction
19209     is set to `true`, this parameter has no effect
19210 
19211     @throw type_error.301 if @a type_deduction is `false`, @a manual_type is
19212     `value_t::object`, but @a init contains an element which is not a pair
19213     whose first element is a string. In this case, the constructor could not
19214     create an object. If @a type_deduction would have be `true`, an array
19215     would have been created. See @ref object(initializer_list_t)
19216     for an example.
19217 
19218     @complexity Linear in the size of the initializer list @a init.
19219 
19220     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19221     changes to any JSON value.
19222 
19223     @liveexample{The example below shows how JSON values are created from
19224     initializer lists.,basic_json__list_init_t}
19225 
19226     @sa see @ref array(initializer_list_t) -- create a JSON array
19227     value from an initializer list
19228     @sa see @ref object(initializer_list_t) -- create a JSON object
19229     value from an initializer list
19230 
19231     @since version 1.0.0
19232     */
basic_json(initializer_list_t init,bool type_deduction=true,value_t manual_type=value_t::array)19233     basic_json(initializer_list_t init,
19234                bool type_deduction = true,
19235                value_t manual_type = value_t::array)
19236     {
19237         // check if each element is an array with two elements whose first
19238         // element is a string
19239         bool is_an_object = std::all_of(init.begin(), init.end(),
19240                                         [](const detail::json_ref<basic_json>& element_ref)
19241         {
19242             return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19243         });
19244 
19245         // adjust type if type deduction is not wanted
19246         if (!type_deduction)
19247         {
19248             // if array is wanted, do not create an object though possible
19249             if (manual_type == value_t::array)
19250             {
19251                 is_an_object = false;
19252             }
19253 
19254             // if object is wanted but impossible, throw an exception
19255             if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19256             {
19257                 JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
19258             }
19259         }
19260 
19261         if (is_an_object)
19262         {
19263             // the initializer list is a list of pairs -> create object
19264             m_type = value_t::object;
19265             m_value = value_t::object;
19266 
19267             for (auto& element_ref : init)
19268             {
19269                 auto element = element_ref.moved_or_copied();
19270                 m_value.object->emplace(
19271                     std::move(*((*element.m_value.array)[0].m_value.string)),
19272                     std::move((*element.m_value.array)[1]));
19273             }
19274         }
19275         else
19276         {
19277             // the initializer list describes an array -> create array
19278             m_type = value_t::array;
19279             m_value.array = create<array_t>(init.begin(), init.end());
19280         }
19281 
19282         set_parents();
19283         assert_invariant();
19284     }
19285 
19286     /*!
19287     @brief explicitly create a binary array (without subtype)
19288 
19289     Creates a JSON binary array value from a given binary container. Binary
19290     values are part of various binary formats, such as CBOR, MessagePack, and
19291     BSON. This constructor is used to create a value for serialization to those
19292     formats.
19293 
19294     @note Note, this function exists because of the difficulty in correctly
19295     specifying the correct template overload in the standard value ctor, as both
19296     JSON arrays and JSON binary arrays are backed with some form of a
19297     `std::vector`. Because JSON binary arrays are a non-standard extension it
19298     was decided that it would be best to prevent automatic initialization of a
19299     binary array type, for backwards compatibility and so it does not happen on
19300     accident.
19301 
19302     @param[in] init container containing bytes to use as binary type
19303 
19304     @return JSON binary array value
19305 
19306     @complexity Linear in the size of @a init.
19307 
19308     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19309     changes to any JSON value.
19310 
19311     @since version 3.8.0
19312     */
19313     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(const typename binary_t::container_type & init)19314     static basic_json binary(const typename binary_t::container_type& init)
19315     {
19316         auto res = basic_json();
19317         res.m_type = value_t::binary;
19318         res.m_value = init;
19319         return res;
19320     }
19321 
19322     /*!
19323     @brief explicitly create a binary array (with subtype)
19324 
19325     Creates a JSON binary array value from a given binary container. Binary
19326     values are part of various binary formats, such as CBOR, MessagePack, and
19327     BSON. This constructor is used to create a value for serialization to those
19328     formats.
19329 
19330     @note Note, this function exists because of the difficulty in correctly
19331     specifying the correct template overload in the standard value ctor, as both
19332     JSON arrays and JSON binary arrays are backed with some form of a
19333     `std::vector`. Because JSON binary arrays are a non-standard extension it
19334     was decided that it would be best to prevent automatic initialization of a
19335     binary array type, for backwards compatibility and so it does not happen on
19336     accident.
19337 
19338     @param[in] init container containing bytes to use as binary type
19339     @param[in] subtype subtype to use in MessagePack and BSON
19340 
19341     @return JSON binary array value
19342 
19343     @complexity Linear in the size of @a init.
19344 
19345     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19346     changes to any JSON value.
19347 
19348     @since version 3.8.0
19349     */
19350     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(const typename binary_t::container_type & init,typename binary_t::subtype_type subtype)19351     static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
19352     {
19353         auto res = basic_json();
19354         res.m_type = value_t::binary;
19355         res.m_value = binary_t(init, subtype);
19356         return res;
19357     }
19358 
19359     /// @copydoc binary(const typename binary_t::container_type&)
19360     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(typename binary_t::container_type && init)19361     static basic_json binary(typename binary_t::container_type&& init)
19362     {
19363         auto res = basic_json();
19364         res.m_type = value_t::binary;
19365         res.m_value = std::move(init);
19366         return res;
19367     }
19368 
19369     /// @copydoc binary(const typename binary_t::container_type&, typename binary_t::subtype_type)
19370     JSON_HEDLEY_WARN_UNUSED_RESULT
binary(typename binary_t::container_type && init,typename binary_t::subtype_type subtype)19371     static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
19372     {
19373         auto res = basic_json();
19374         res.m_type = value_t::binary;
19375         res.m_value = binary_t(std::move(init), subtype);
19376         return res;
19377     }
19378 
19379     /*!
19380     @brief explicitly create an array from an initializer list
19381 
19382     Creates a JSON array value from a given initializer list. That is, given a
19383     list of values `a, b, c`, creates the JSON value `[a, b, c]`. If the
19384     initializer list is empty, the empty array `[]` is created.
19385 
19386     @note This function is only needed to express two edge cases that cannot
19387     be realized with the initializer list constructor (@ref
19388     basic_json(initializer_list_t, bool, value_t)). These cases
19389     are:
19390     1. creating an array whose elements are all pairs whose first element is a
19391     string -- in this case, the initializer list constructor would create an
19392     object, taking the first elements as keys
19393     2. creating an empty array -- passing the empty initializer list to the
19394     initializer list constructor yields an empty object
19395 
19396     @param[in] init  initializer list with JSON values to create an array from
19397     (optional)
19398 
19399     @return JSON array value
19400 
19401     @complexity Linear in the size of @a init.
19402 
19403     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19404     changes to any JSON value.
19405 
19406     @liveexample{The following code shows an example for the `array`
19407     function.,array}
19408 
19409     @sa see @ref basic_json(initializer_list_t, bool, value_t) --
19410     create a JSON value from an initializer list
19411     @sa see @ref object(initializer_list_t) -- create a JSON object
19412     value from an initializer list
19413 
19414     @since version 1.0.0
19415     */
19416     JSON_HEDLEY_WARN_UNUSED_RESULT
array(initializer_list_t init={})19417     static basic_json array(initializer_list_t init = {})
19418     {
19419         return basic_json(init, false, value_t::array);
19420     }
19421 
19422     /*!
19423     @brief explicitly create an object from an initializer list
19424 
19425     Creates a JSON object value from a given initializer list. The initializer
19426     lists elements must be pairs, and their first elements must be strings. If
19427     the initializer list is empty, the empty object `{}` is created.
19428 
19429     @note This function is only added for symmetry reasons. In contrast to the
19430     related function @ref array(initializer_list_t), there are
19431     no cases which can only be expressed by this function. That is, any
19432     initializer list @a init can also be passed to the initializer list
19433     constructor @ref basic_json(initializer_list_t, bool, value_t).
19434 
19435     @param[in] init  initializer list to create an object from (optional)
19436 
19437     @return JSON object value
19438 
19439     @throw type_error.301 if @a init is not a list of pairs whose first
19440     elements are strings. In this case, no object can be created. When such a
19441     value is passed to @ref basic_json(initializer_list_t, bool, value_t),
19442     an array would have been created from the passed initializer list @a init.
19443     See example below.
19444 
19445     @complexity Linear in the size of @a init.
19446 
19447     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19448     changes to any JSON value.
19449 
19450     @liveexample{The following code shows an example for the `object`
19451     function.,object}
19452 
19453     @sa see @ref basic_json(initializer_list_t, bool, value_t) --
19454     create a JSON value from an initializer list
19455     @sa see @ref array(initializer_list_t) -- create a JSON array
19456     value from an initializer list
19457 
19458     @since version 1.0.0
19459     */
19460     JSON_HEDLEY_WARN_UNUSED_RESULT
object(initializer_list_t init={})19461     static basic_json object(initializer_list_t init = {})
19462     {
19463         return basic_json(init, false, value_t::object);
19464     }
19465 
19466     /*!
19467     @brief construct an array with count copies of given value
19468 
19469     Constructs a JSON array value by creating @a cnt copies of a passed value.
19470     In case @a cnt is `0`, an empty array is created.
19471 
19472     @param[in] cnt  the number of JSON copies of @a val to create
19473     @param[in] val  the JSON value to copy
19474 
19475     @post `std::distance(begin(),end()) == cnt` holds.
19476 
19477     @complexity Linear in @a cnt.
19478 
19479     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19480     changes to any JSON value.
19481 
19482     @liveexample{The following code shows examples for the @ref
19483     basic_json(size_type\, const basic_json&)
19484     constructor.,basic_json__size_type_basic_json}
19485 
19486     @since version 1.0.0
19487     */
basic_json(size_type cnt,const basic_json & val)19488     basic_json(size_type cnt, const basic_json& val)
19489         : m_type(value_t::array)
19490     {
19491         m_value.array = create<array_t>(cnt, val);
19492         set_parents();
19493         assert_invariant();
19494     }
19495 
19496     /*!
19497     @brief construct a JSON container given an iterator range
19498 
19499     Constructs the JSON value with the contents of the range `[first, last)`.
19500     The semantics depends on the different types a JSON value can have:
19501     - In case of a null type, invalid_iterator.206 is thrown.
19502     - In case of other primitive types (number, boolean, or string), @a first
19503       must be `begin()` and @a last must be `end()`. In this case, the value is
19504       copied. Otherwise, invalid_iterator.204 is thrown.
19505     - In case of structured types (array, object), the constructor behaves as
19506       similar versions for `std::vector` or `std::map`; that is, a JSON array
19507       or object is constructed from the values in the range.
19508 
19509     @tparam InputIT an input iterator type (@ref iterator or @ref
19510     const_iterator)
19511 
19512     @param[in] first begin of the range to copy from (included)
19513     @param[in] last end of the range to copy from (excluded)
19514 
19515     @pre Iterators @a first and @a last must be initialized. **This
19516          precondition is enforced with an assertion (see warning).** If
19517          assertions are switched off, a violation of this precondition yields
19518          undefined behavior.
19519 
19520     @pre Range `[first, last)` is valid. Usually, this precondition cannot be
19521          checked efficiently. Only certain edge cases are detected; see the
19522          description of the exceptions below. A violation of this precondition
19523          yields undefined behavior.
19524 
19525     @warning A precondition is enforced with a runtime assertion that will
19526              result in calling `std::abort` if this precondition is not met.
19527              Assertions can be disabled by defining `NDEBUG` at compile time.
19528              See https://en.cppreference.com/w/cpp/error/assert for more
19529              information.
19530 
19531     @throw invalid_iterator.201 if iterators @a first and @a last are not
19532     compatible (i.e., do not belong to the same JSON value). In this case,
19533     the range `[first, last)` is undefined.
19534     @throw invalid_iterator.204 if iterators @a first and @a last belong to a
19535     primitive type (number, boolean, or string), but @a first does not point
19536     to the first element any more. In this case, the range `[first, last)` is
19537     undefined. See example code below.
19538     @throw invalid_iterator.206 if iterators @a first and @a last belong to a
19539     null value. In this case, the range `[first, last)` is undefined.
19540 
19541     @complexity Linear in distance between @a first and @a last.
19542 
19543     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19544     changes to any JSON value.
19545 
19546     @liveexample{The example below shows several ways to create JSON values by
19547     specifying a subrange with iterators.,basic_json__InputIt_InputIt}
19548 
19549     @since version 1.0.0
19550     */
19551     template < class InputIT, typename std::enable_if <
19552                    std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19553                    std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
basic_json(InputIT first,InputIT last)19554     basic_json(InputIT first, InputIT last)
19555     {
19556         JSON_ASSERT(first.m_object != nullptr);
19557         JSON_ASSERT(last.m_object != nullptr);
19558 
19559         // make sure iterator fits the current value
19560         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19561         {
19562             JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
19563         }
19564 
19565         // copy type from first iterator
19566         m_type = first.m_object->m_type;
19567 
19568         // check if iterator range is complete for primitive values
19569         switch (m_type)
19570         {
19571             case value_t::boolean:
19572             case value_t::number_float:
19573             case value_t::number_integer:
19574             case value_t::number_unsigned:
19575             case value_t::string:
19576             {
19577                 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19578                                          || !last.m_it.primitive_iterator.is_end()))
19579                 {
19580                     JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
19581                 }
19582                 break;
19583             }
19584 
19585             case value_t::null:
19586             case value_t::object:
19587             case value_t::array:
19588             case value_t::binary:
19589             case value_t::discarded:
19590             default:
19591                 break;
19592         }
19593 
19594         switch (m_type)
19595         {
19596             case value_t::number_integer:
19597             {
19598                 m_value.number_integer = first.m_object->m_value.number_integer;
19599                 break;
19600             }
19601 
19602             case value_t::number_unsigned:
19603             {
19604                 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19605                 break;
19606             }
19607 
19608             case value_t::number_float:
19609             {
19610                 m_value.number_float = first.m_object->m_value.number_float;
19611                 break;
19612             }
19613 
19614             case value_t::boolean:
19615             {
19616                 m_value.boolean = first.m_object->m_value.boolean;
19617                 break;
19618             }
19619 
19620             case value_t::string:
19621             {
19622                 m_value = *first.m_object->m_value.string;
19623                 break;
19624             }
19625 
19626             case value_t::object:
19627             {
19628                 m_value.object = create<object_t>(first.m_it.object_iterator,
19629                                                   last.m_it.object_iterator);
19630                 break;
19631             }
19632 
19633             case value_t::array:
19634             {
19635                 m_value.array = create<array_t>(first.m_it.array_iterator,
19636                                                 last.m_it.array_iterator);
19637                 break;
19638             }
19639 
19640             case value_t::binary:
19641             {
19642                 m_value = *first.m_object->m_value.binary;
19643                 break;
19644             }
19645 
19646             case value_t::null:
19647             case value_t::discarded:
19648             default:
19649                 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
19650         }
19651 
19652         set_parents();
19653         assert_invariant();
19654     }
19655 
19656 
19657     ///////////////////////////////////////
19658     // other constructors and destructor //
19659     ///////////////////////////////////////
19660 
19661     template<typename JsonRef,
19662              detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
19663                                  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
basic_json(const JsonRef & ref)19664     basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19665 
19666     /*!
19667     @brief copy constructor
19668 
19669     Creates a copy of a given JSON value.
19670 
19671     @param[in] other  the JSON value to copy
19672 
19673     @post `*this == other`
19674 
19675     @complexity Linear in the size of @a other.
19676 
19677     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19678     changes to any JSON value.
19679 
19680     @requirement This function helps `basic_json` satisfying the
19681     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19682     requirements:
19683     - The complexity is linear.
19684     - As postcondition, it holds: `other == basic_json(other)`.
19685 
19686     @liveexample{The following code shows an example for the copy
19687     constructor.,basic_json__basic_json}
19688 
19689     @since version 1.0.0
19690     */
basic_json(const basic_json & other)19691     basic_json(const basic_json& other)
19692         : m_type(other.m_type)
19693     {
19694         // check of passed value is valid
19695         other.assert_invariant();
19696 
19697         switch (m_type)
19698         {
19699             case value_t::object:
19700             {
19701                 m_value = *other.m_value.object;
19702                 break;
19703             }
19704 
19705             case value_t::array:
19706             {
19707                 m_value = *other.m_value.array;
19708                 break;
19709             }
19710 
19711             case value_t::string:
19712             {
19713                 m_value = *other.m_value.string;
19714                 break;
19715             }
19716 
19717             case value_t::boolean:
19718             {
19719                 m_value = other.m_value.boolean;
19720                 break;
19721             }
19722 
19723             case value_t::number_integer:
19724             {
19725                 m_value = other.m_value.number_integer;
19726                 break;
19727             }
19728 
19729             case value_t::number_unsigned:
19730             {
19731                 m_value = other.m_value.number_unsigned;
19732                 break;
19733             }
19734 
19735             case value_t::number_float:
19736             {
19737                 m_value = other.m_value.number_float;
19738                 break;
19739             }
19740 
19741             case value_t::binary:
19742             {
19743                 m_value = *other.m_value.binary;
19744                 break;
19745             }
19746 
19747             case value_t::null:
19748             case value_t::discarded:
19749             default:
19750                 break;
19751         }
19752 
19753         set_parents();
19754         assert_invariant();
19755     }
19756 
19757     /*!
19758     @brief move constructor
19759 
19760     Move constructor. Constructs a JSON value with the contents of the given
19761     value @a other using move semantics. It "steals" the resources from @a
19762     other and leaves it as JSON null value.
19763 
19764     @param[in,out] other  value to move to this object
19765 
19766     @post `*this` has the same value as @a other before the call.
19767     @post @a other is a JSON null value.
19768 
19769     @complexity Constant.
19770 
19771     @exceptionsafety No-throw guarantee: this constructor never throws
19772     exceptions.
19773 
19774     @requirement This function helps `basic_json` satisfying the
19775     [MoveConstructible](https://en.cppreference.com/w/cpp/named_req/MoveConstructible)
19776     requirements.
19777 
19778     @liveexample{The code below shows the move constructor explicitly called
19779     via std::move.,basic_json__moveconstructor}
19780 
19781     @since version 1.0.0
19782     */
basic_json(basic_json && other)19783     basic_json(basic_json&& other) noexcept
19784         : m_type(std::move(other.m_type)),
19785           m_value(std::move(other.m_value))
19786     {
19787         // check that passed value is valid
19788         other.assert_invariant(false);
19789 
19790         // invalidate payload
19791         other.m_type = value_t::null;
19792         other.m_value = {};
19793 
19794         set_parents();
19795         assert_invariant();
19796     }
19797 
19798     /*!
19799     @brief copy assignment
19800 
19801     Copy assignment operator. Copies a JSON value via the "copy and swap"
19802     strategy: It is expressed in terms of the copy constructor, destructor,
19803     and the `swap()` member function.
19804 
19805     @param[in] other  value to copy from
19806 
19807     @complexity Linear.
19808 
19809     @requirement This function helps `basic_json` satisfying the
19810     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19811     requirements:
19812     - The complexity is linear.
19813 
19814     @liveexample{The code below shows and example for the copy assignment. It
19815     creates a copy of value `a` which is then swapped with `b`. Finally\, the
19816     copy of `a` (which is the null value after the swap) is
19817     destroyed.,basic_json__copyassignment}
19818 
19819     @since version 1.0.0
19820     */
operator =(basic_json other)19821     basic_json& operator=(basic_json other) noexcept (
19822         std::is_nothrow_move_constructible<value_t>::value&&
19823         std::is_nothrow_move_assignable<value_t>::value&&
19824         std::is_nothrow_move_constructible<json_value>::value&&
19825         std::is_nothrow_move_assignable<json_value>::value
19826     )
19827     {
19828         // check that passed value is valid
19829         other.assert_invariant();
19830 
19831         using std::swap;
19832         swap(m_type, other.m_type);
19833         swap(m_value, other.m_value);
19834 
19835         set_parents();
19836         assert_invariant();
19837         return *this;
19838     }
19839 
19840     /*!
19841     @brief destructor
19842 
19843     Destroys the JSON value and frees all allocated memory.
19844 
19845     @complexity Linear.
19846 
19847     @requirement This function helps `basic_json` satisfying the
19848     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
19849     requirements:
19850     - The complexity is linear.
19851     - All stored elements are destroyed and all memory is freed.
19852 
19853     @since version 1.0.0
19854     */
~basic_json()19855     ~basic_json() noexcept
19856     {
19857         assert_invariant(false);
19858         m_value.destroy(m_type);
19859     }
19860 
19861     /// @}
19862 
19863   public:
19864     ///////////////////////
19865     // object inspection //
19866     ///////////////////////
19867 
19868     /// @name object inspection
19869     /// Functions to inspect the type of a JSON value.
19870     /// @{
19871 
19872     /*!
19873     @brief serialization
19874 
19875     Serialization function for JSON values. The function tries to mimic
19876     Python's `json.dumps()` function, and currently supports its @a indent
19877     and @a ensure_ascii parameters.
19878 
19879     @param[in] indent If indent is nonnegative, then array elements and object
19880     members will be pretty-printed with that indent level. An indent level of
19881     `0` will only insert newlines. `-1` (the default) selects the most compact
19882     representation.
19883     @param[in] indent_char The character to use for indentation if @a indent is
19884     greater than `0`. The default is ` ` (space).
19885     @param[in] ensure_ascii If @a ensure_ascii is true, all non-ASCII characters
19886     in the output are escaped with `\uXXXX` sequences, and the result consists
19887     of ASCII characters only.
19888     @param[in] error_handler  how to react on decoding errors; there are three
19889     possible values: `strict` (throws and exception in case a decoding error
19890     occurs; default), `replace` (replace invalid UTF-8 sequences with U+FFFD),
19891     and `ignore` (ignore invalid UTF-8 sequences during serialization; all
19892     bytes are copied to the output unchanged).
19893 
19894     @return string containing the serialization of the JSON value
19895 
19896     @throw type_error.316 if a string stored inside the JSON value is not
19897                           UTF-8 encoded and @a error_handler is set to strict
19898 
19899     @note Binary values are serialized as object containing two keys:
19900       - "bytes": an array of bytes as integers
19901       - "subtype": the subtype as integer or "null" if the binary has no subtype
19902 
19903     @complexity Linear.
19904 
19905     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
19906     changes in the JSON value.
19907 
19908     @liveexample{The following example shows the effect of different @a indent\,
19909     @a indent_char\, and @a ensure_ascii parameters to the result of the
19910     serialization.,dump}
19911 
19912     @see https://docs.python.org/2/library/json.html#json.dump
19913 
19914     @since version 1.0.0; indentation character @a indent_char, option
19915            @a ensure_ascii and exceptions added in version 3.0.0; error
19916            handlers added in version 3.4.0; serialization of binary values added
19917            in version 3.8.0.
19918     */
dump(const int indent=-1,const char indent_char=' ',const bool ensure_ascii=false,const error_handler_t error_handler=error_handler_t::strict) const19919     string_t dump(const int indent = -1,
19920                   const char indent_char = ' ',
19921                   const bool ensure_ascii = false,
19922                   const error_handler_t error_handler = error_handler_t::strict) const
19923     {
19924         string_t result;
19925         serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19926 
19927         if (indent >= 0)
19928         {
19929             s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19930         }
19931         else
19932         {
19933             s.dump(*this, false, ensure_ascii, 0);
19934         }
19935 
19936         return result;
19937     }
19938 
19939     /*!
19940     @brief return the type of the JSON value (explicit)
19941 
19942     Return the type of the JSON value as a value from the @ref value_t
19943     enumeration.
19944 
19945     @return the type of the JSON value
19946             Value type                | return value
19947             ------------------------- | -------------------------
19948             null                      | value_t::null
19949             boolean                   | value_t::boolean
19950             string                    | value_t::string
19951             number (integer)          | value_t::number_integer
19952             number (unsigned integer) | value_t::number_unsigned
19953             number (floating-point)   | value_t::number_float
19954             object                    | value_t::object
19955             array                     | value_t::array
19956             binary                    | value_t::binary
19957             discarded                 | value_t::discarded
19958 
19959     @complexity Constant.
19960 
19961     @exceptionsafety No-throw guarantee: this member function never throws
19962     exceptions.
19963 
19964     @liveexample{The following code exemplifies `type()` for all JSON
19965     types.,type}
19966 
19967     @sa see @ref operator value_t() -- return the type of the JSON value (implicit)
19968     @sa see @ref type_name() -- return the type as string
19969 
19970     @since version 1.0.0
19971     */
type() const19972     constexpr value_t type() const noexcept
19973     {
19974         return m_type;
19975     }
19976 
19977     /*!
19978     @brief return whether type is primitive
19979 
19980     This function returns true if and only if the JSON type is primitive
19981     (string, number, boolean, or null).
19982 
19983     @return `true` if type is primitive (string, number, boolean, or null),
19984     `false` otherwise.
19985 
19986     @complexity Constant.
19987 
19988     @exceptionsafety No-throw guarantee: this member function never throws
19989     exceptions.
19990 
19991     @liveexample{The following code exemplifies `is_primitive()` for all JSON
19992     types.,is_primitive}
19993 
19994     @sa see @ref is_structured() -- returns whether JSON value is structured
19995     @sa see @ref is_null() -- returns whether JSON value is `null`
19996     @sa see @ref is_string() -- returns whether JSON value is a string
19997     @sa see @ref is_boolean() -- returns whether JSON value is a boolean
19998     @sa see @ref is_number() -- returns whether JSON value is a number
19999     @sa see @ref is_binary() -- returns whether JSON value is a binary array
20000 
20001     @since version 1.0.0
20002     */
is_primitive() const20003     constexpr bool is_primitive() const noexcept
20004     {
20005         return is_null() || is_string() || is_boolean() || is_number() || is_binary();
20006     }
20007 
20008     /*!
20009     @brief return whether type is structured
20010 
20011     This function returns true if and only if the JSON type is structured
20012     (array or object).
20013 
20014     @return `true` if type is structured (array or object), `false` otherwise.
20015 
20016     @complexity Constant.
20017 
20018     @exceptionsafety No-throw guarantee: this member function never throws
20019     exceptions.
20020 
20021     @liveexample{The following code exemplifies `is_structured()` for all JSON
20022     types.,is_structured}
20023 
20024     @sa see @ref is_primitive() -- returns whether value is primitive
20025     @sa see @ref is_array() -- returns whether value is an array
20026     @sa see @ref is_object() -- returns whether value is an object
20027 
20028     @since version 1.0.0
20029     */
is_structured() const20030     constexpr bool is_structured() const noexcept
20031     {
20032         return is_array() || is_object();
20033     }
20034 
20035     /*!
20036     @brief return whether value is null
20037 
20038     This function returns true if and only if the JSON value is null.
20039 
20040     @return `true` if type is null, `false` otherwise.
20041 
20042     @complexity Constant.
20043 
20044     @exceptionsafety No-throw guarantee: this member function never throws
20045     exceptions.
20046 
20047     @liveexample{The following code exemplifies `is_null()` for all JSON
20048     types.,is_null}
20049 
20050     @since version 1.0.0
20051     */
is_null() const20052     constexpr bool is_null() const noexcept
20053     {
20054         return m_type == value_t::null;
20055     }
20056 
20057     /*!
20058     @brief return whether value is a boolean
20059 
20060     This function returns true if and only if the JSON value is a boolean.
20061 
20062     @return `true` if type is boolean, `false` otherwise.
20063 
20064     @complexity Constant.
20065 
20066     @exceptionsafety No-throw guarantee: this member function never throws
20067     exceptions.
20068 
20069     @liveexample{The following code exemplifies `is_boolean()` for all JSON
20070     types.,is_boolean}
20071 
20072     @since version 1.0.0
20073     */
is_boolean() const20074     constexpr bool is_boolean() const noexcept
20075     {
20076         return m_type == value_t::boolean;
20077     }
20078 
20079     /*!
20080     @brief return whether value is a number
20081 
20082     This function returns true if and only if the JSON value is a number. This
20083     includes both integer (signed and unsigned) and floating-point values.
20084 
20085     @return `true` if type is number (regardless whether integer, unsigned
20086     integer or floating-type), `false` otherwise.
20087 
20088     @complexity Constant.
20089 
20090     @exceptionsafety No-throw guarantee: this member function never throws
20091     exceptions.
20092 
20093     @liveexample{The following code exemplifies `is_number()` for all JSON
20094     types.,is_number}
20095 
20096     @sa see @ref is_number_integer() -- check if value is an integer or unsigned
20097     integer number
20098     @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20099     number
20100     @sa see @ref is_number_float() -- check if value is a floating-point number
20101 
20102     @since version 1.0.0
20103     */
is_number() const20104     constexpr bool is_number() const noexcept
20105     {
20106         return is_number_integer() || is_number_float();
20107     }
20108 
20109     /*!
20110     @brief return whether value is an integer number
20111 
20112     This function returns true if and only if the JSON value is a signed or
20113     unsigned integer number. This excludes floating-point values.
20114 
20115     @return `true` if type is an integer or unsigned integer number, `false`
20116     otherwise.
20117 
20118     @complexity Constant.
20119 
20120     @exceptionsafety No-throw guarantee: this member function never throws
20121     exceptions.
20122 
20123     @liveexample{The following code exemplifies `is_number_integer()` for all
20124     JSON types.,is_number_integer}
20125 
20126     @sa see @ref is_number() -- check if value is a number
20127     @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20128     number
20129     @sa see @ref is_number_float() -- check if value is a floating-point number
20130 
20131     @since version 1.0.0
20132     */
is_number_integer() const20133     constexpr bool is_number_integer() const noexcept
20134     {
20135         return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
20136     }
20137 
20138     /*!
20139     @brief return whether value is an unsigned integer number
20140 
20141     This function returns true if and only if the JSON value is an unsigned
20142     integer number. This excludes floating-point and signed integer values.
20143 
20144     @return `true` if type is an unsigned integer number, `false` otherwise.
20145 
20146     @complexity Constant.
20147 
20148     @exceptionsafety No-throw guarantee: this member function never throws
20149     exceptions.
20150 
20151     @liveexample{The following code exemplifies `is_number_unsigned()` for all
20152     JSON types.,is_number_unsigned}
20153 
20154     @sa see @ref is_number() -- check if value is a number
20155     @sa see @ref is_number_integer() -- check if value is an integer or unsigned
20156     integer number
20157     @sa see @ref is_number_float() -- check if value is a floating-point number
20158 
20159     @since version 2.0.0
20160     */
is_number_unsigned() const20161     constexpr bool is_number_unsigned() const noexcept
20162     {
20163         return m_type == value_t::number_unsigned;
20164     }
20165 
20166     /*!
20167     @brief return whether value is a floating-point number
20168 
20169     This function returns true if and only if the JSON value is a
20170     floating-point number. This excludes signed and unsigned integer values.
20171 
20172     @return `true` if type is a floating-point number, `false` otherwise.
20173 
20174     @complexity Constant.
20175 
20176     @exceptionsafety No-throw guarantee: this member function never throws
20177     exceptions.
20178 
20179     @liveexample{The following code exemplifies `is_number_float()` for all
20180     JSON types.,is_number_float}
20181 
20182     @sa see @ref is_number() -- check if value is number
20183     @sa see @ref is_number_integer() -- check if value is an integer number
20184     @sa see @ref is_number_unsigned() -- check if value is an unsigned integer
20185     number
20186 
20187     @since version 1.0.0
20188     */
is_number_float() const20189     constexpr bool is_number_float() const noexcept
20190     {
20191         return m_type == value_t::number_float;
20192     }
20193 
20194     /*!
20195     @brief return whether value is an object
20196 
20197     This function returns true if and only if the JSON value is an object.
20198 
20199     @return `true` if type is object, `false` otherwise.
20200 
20201     @complexity Constant.
20202 
20203     @exceptionsafety No-throw guarantee: this member function never throws
20204     exceptions.
20205 
20206     @liveexample{The following code exemplifies `is_object()` for all JSON
20207     types.,is_object}
20208 
20209     @since version 1.0.0
20210     */
is_object() const20211     constexpr bool is_object() const noexcept
20212     {
20213         return m_type == value_t::object;
20214     }
20215 
20216     /*!
20217     @brief return whether value is an array
20218 
20219     This function returns true if and only if the JSON value is an array.
20220 
20221     @return `true` if type is array, `false` otherwise.
20222 
20223     @complexity Constant.
20224 
20225     @exceptionsafety No-throw guarantee: this member function never throws
20226     exceptions.
20227 
20228     @liveexample{The following code exemplifies `is_array()` for all JSON
20229     types.,is_array}
20230 
20231     @since version 1.0.0
20232     */
is_array() const20233     constexpr bool is_array() const noexcept
20234     {
20235         return m_type == value_t::array;
20236     }
20237 
20238     /*!
20239     @brief return whether value is a string
20240 
20241     This function returns true if and only if the JSON value is a string.
20242 
20243     @return `true` if type is string, `false` otherwise.
20244 
20245     @complexity Constant.
20246 
20247     @exceptionsafety No-throw guarantee: this member function never throws
20248     exceptions.
20249 
20250     @liveexample{The following code exemplifies `is_string()` for all JSON
20251     types.,is_string}
20252 
20253     @since version 1.0.0
20254     */
is_string() const20255     constexpr bool is_string() const noexcept
20256     {
20257         return m_type == value_t::string;
20258     }
20259 
20260     /*!
20261     @brief return whether value is a binary array
20262 
20263     This function returns true if and only if the JSON value is a binary array.
20264 
20265     @return `true` if type is binary array, `false` otherwise.
20266 
20267     @complexity Constant.
20268 
20269     @exceptionsafety No-throw guarantee: this member function never throws
20270     exceptions.
20271 
20272     @liveexample{The following code exemplifies `is_binary()` for all JSON
20273     types.,is_binary}
20274 
20275     @since version 3.8.0
20276     */
is_binary() const20277     constexpr bool is_binary() const noexcept
20278     {
20279         return m_type == value_t::binary;
20280     }
20281 
20282     /*!
20283     @brief return whether value is discarded
20284 
20285     This function returns true if and only if the JSON value was discarded
20286     during parsing with a callback function (see @ref parser_callback_t).
20287 
20288     @note This function will always be `false` for JSON values after parsing.
20289     That is, discarded values can only occur during parsing, but will be
20290     removed when inside a structured value or replaced by null in other cases.
20291 
20292     @return `true` if type is discarded, `false` otherwise.
20293 
20294     @complexity Constant.
20295 
20296     @exceptionsafety No-throw guarantee: this member function never throws
20297     exceptions.
20298 
20299     @liveexample{The following code exemplifies `is_discarded()` for all JSON
20300     types.,is_discarded}
20301 
20302     @since version 1.0.0
20303     */
is_discarded() const20304     constexpr bool is_discarded() const noexcept
20305     {
20306         return m_type == value_t::discarded;
20307     }
20308 
20309     /*!
20310     @brief return the type of the JSON value (implicit)
20311 
20312     Implicitly return the type of the JSON value as a value from the @ref
20313     value_t enumeration.
20314 
20315     @return the type of the JSON value
20316 
20317     @complexity Constant.
20318 
20319     @exceptionsafety No-throw guarantee: this member function never throws
20320     exceptions.
20321 
20322     @liveexample{The following code exemplifies the @ref value_t operator for
20323     all JSON types.,operator__value_t}
20324 
20325     @sa see @ref type() -- return the type of the JSON value (explicit)
20326     @sa see @ref type_name() -- return the type as string
20327 
20328     @since version 1.0.0
20329     */
operator value_t() const20330     constexpr operator value_t() const noexcept
20331     {
20332         return m_type;
20333     }
20334 
20335     /// @}
20336 
20337   private:
20338     //////////////////
20339     // value access //
20340     //////////////////
20341 
20342     /// get a boolean (explicit)
get_impl(boolean_t *) const20343     boolean_t get_impl(boolean_t* /*unused*/) const
20344     {
20345         if (JSON_HEDLEY_LIKELY(is_boolean()))
20346         {
20347             return m_value.boolean;
20348         }
20349 
20350         JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
20351     }
20352 
20353     /// get a pointer to the value (object)
get_impl_ptr(object_t *)20354     object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20355     {
20356         return is_object() ? m_value.object : nullptr;
20357     }
20358 
20359     /// get a pointer to the value (object)
get_impl_ptr(const object_t *) const20360     constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20361     {
20362         return is_object() ? m_value.object : nullptr;
20363     }
20364 
20365     /// get a pointer to the value (array)
get_impl_ptr(array_t *)20366     array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20367     {
20368         return is_array() ? m_value.array : nullptr;
20369     }
20370 
20371     /// get a pointer to the value (array)
get_impl_ptr(const array_t *) const20372     constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20373     {
20374         return is_array() ? m_value.array : nullptr;
20375     }
20376 
20377     /// get a pointer to the value (string)
get_impl_ptr(string_t *)20378     string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20379     {
20380         return is_string() ? m_value.string : nullptr;
20381     }
20382 
20383     /// get a pointer to the value (string)
get_impl_ptr(const string_t *) const20384     constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20385     {
20386         return is_string() ? m_value.string : nullptr;
20387     }
20388 
20389     /// get a pointer to the value (boolean)
get_impl_ptr(boolean_t *)20390     boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20391     {
20392         return is_boolean() ? &m_value.boolean : nullptr;
20393     }
20394 
20395     /// get a pointer to the value (boolean)
get_impl_ptr(const boolean_t *) const20396     constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20397     {
20398         return is_boolean() ? &m_value.boolean : nullptr;
20399     }
20400 
20401     /// get a pointer to the value (integer number)
get_impl_ptr(number_integer_t *)20402     number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
20403     {
20404         return is_number_integer() ? &m_value.number_integer : nullptr;
20405     }
20406 
20407     /// get a pointer to the value (integer number)
get_impl_ptr(const number_integer_t *) const20408     constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20409     {
20410         return is_number_integer() ? &m_value.number_integer : nullptr;
20411     }
20412 
20413     /// get a pointer to the value (unsigned number)
get_impl_ptr(number_unsigned_t *)20414     number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
20415     {
20416         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20417     }
20418 
20419     /// get a pointer to the value (unsigned number)
get_impl_ptr(const number_unsigned_t *) const20420     constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20421     {
20422         return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20423     }
20424 
20425     /// get a pointer to the value (floating-point number)
get_impl_ptr(number_float_t *)20426     number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
20427     {
20428         return is_number_float() ? &m_value.number_float : nullptr;
20429     }
20430 
20431     /// get a pointer to the value (floating-point number)
get_impl_ptr(const number_float_t *) const20432     constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20433     {
20434         return is_number_float() ? &m_value.number_float : nullptr;
20435     }
20436 
20437     /// get a pointer to the value (binary)
get_impl_ptr(binary_t *)20438     binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20439     {
20440         return is_binary() ? m_value.binary : nullptr;
20441     }
20442 
20443     /// get a pointer to the value (binary)
get_impl_ptr(const binary_t *) const20444     constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20445     {
20446         return is_binary() ? m_value.binary : nullptr;
20447     }
20448 
20449     /*!
20450     @brief helper function to implement get_ref()
20451 
20452     This function helps to implement get_ref() without code duplication for
20453     const and non-const overloads
20454 
20455     @tparam ThisType will be deduced as `basic_json` or `const basic_json`
20456 
20457     @throw type_error.303 if ReferenceType does not match underlying value
20458     type of the current JSON
20459     */
20460     template<typename ReferenceType, typename ThisType>
get_ref_impl(ThisType & obj)20461     static ReferenceType get_ref_impl(ThisType& obj)
20462     {
20463         // delegate the call to get_ptr<>()
20464         auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20465 
20466         if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20467         {
20468             return *ptr;
20469         }
20470 
20471         JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
20472     }
20473 
20474   public:
20475     /// @name value access
20476     /// Direct access to the stored value of a JSON value.
20477     /// @{
20478 
20479     /*!
20480     @brief get a pointer value (implicit)
20481 
20482     Implicit pointer access to the internally stored JSON value. No copies are
20483     made.
20484 
20485     @warning Writing data to the pointee of the result yields an undefined
20486     state.
20487 
20488     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
20489     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
20490     @ref number_unsigned_t, or @ref number_float_t. Enforced by a static
20491     assertion.
20492 
20493     @return pointer to the internally stored JSON value if the requested
20494     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
20495 
20496     @complexity Constant.
20497 
20498     @liveexample{The example below shows how pointers to internal values of a
20499     JSON value can be requested. Note that no type conversions are made and a
20500     `nullptr` is returned if the value and the requested pointer type does not
20501     match.,get_ptr}
20502 
20503     @since version 1.0.0
20504     */
20505     template<typename PointerType, typename std::enable_if<
20506                  std::is_pointer<PointerType>::value, int>::type = 0>
get_ptr()20507     auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20508     {
20509         // delegate the call to get_impl_ptr<>()
20510         return get_impl_ptr(static_cast<PointerType>(nullptr));
20511     }
20512 
20513     /*!
20514     @brief get a pointer value (implicit)
20515     @copydoc get_ptr()
20516     */
20517     template < typename PointerType, typename std::enable_if <
20518                    std::is_pointer<PointerType>::value&&
20519                    std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
get_ptr() const20520     constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20521     {
20522         // delegate the call to get_impl_ptr<>() const
20523         return get_impl_ptr(static_cast<PointerType>(nullptr));
20524     }
20525 
20526   private:
20527     /*!
20528     @brief get a value (explicit)
20529 
20530     Explicit type conversion between the JSON value and a compatible value
20531     which is [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
20532     and [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
20533     The value is converted by calling the @ref json_serializer<ValueType>
20534     `from_json()` method.
20535 
20536     The function is equivalent to executing
20537     @code {.cpp}
20538     ValueType ret;
20539     JSONSerializer<ValueType>::from_json(*this, ret);
20540     return ret;
20541     @endcode
20542 
20543     This overloads is chosen if:
20544     - @a ValueType is not @ref basic_json,
20545     - @ref json_serializer<ValueType> has a `from_json()` method of the form
20546       `void from_json(const basic_json&, ValueType&)`, and
20547     - @ref json_serializer<ValueType> does not have a `from_json()` method of
20548       the form `ValueType from_json(const basic_json&)`
20549 
20550     @tparam ValueType the returned value type
20551 
20552     @return copy of the JSON value, converted to @a ValueType
20553 
20554     @throw what @ref json_serializer<ValueType> `from_json()` method throws
20555 
20556     @liveexample{The example below shows several conversions from JSON values
20557     to other types. There a few things to note: (1) Floating-point numbers can
20558     be converted to integers\, (2) A JSON array can be converted to a standard
20559     `std::vector<short>`\, (3) A JSON object can be converted to C++
20560     associative containers such as `std::unordered_map<std::string\,
20561     json>`.,get__ValueType_const}
20562 
20563     @since version 2.1.0
20564     */
20565     template < typename ValueType,
20566                detail::enable_if_t <
20567                    detail::is_default_constructible<ValueType>::value&&
20568                    detail::has_from_json<basic_json_t, ValueType>::value,
20569                    int > = 0 >
20570     ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20571                 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20572     {
20573         auto ret = ValueType();
20574         JSONSerializer<ValueType>::from_json(*this, ret);
20575         return ret;
20576     }
20577 
20578     /*!
20579     @brief get a value (explicit); special case
20580 
20581     Explicit type conversion between the JSON value and a compatible value
20582     which is **not** [CopyConstructible](https://en.cppreference.com/w/cpp/named_req/CopyConstructible)
20583     and **not** [DefaultConstructible](https://en.cppreference.com/w/cpp/named_req/DefaultConstructible).
20584     The value is converted by calling the @ref json_serializer<ValueType>
20585     `from_json()` method.
20586 
20587     The function is equivalent to executing
20588     @code {.cpp}
20589     return JSONSerializer<ValueType>::from_json(*this);
20590     @endcode
20591 
20592     This overloads is chosen if:
20593     - @a ValueType is not @ref basic_json and
20594     - @ref json_serializer<ValueType> has a `from_json()` method of the form
20595       `ValueType from_json(const basic_json&)`
20596 
20597     @note If @ref json_serializer<ValueType> has both overloads of
20598     `from_json()`, this one is chosen.
20599 
20600     @tparam ValueType the returned value type
20601 
20602     @return copy of the JSON value, converted to @a ValueType
20603 
20604     @throw what @ref json_serializer<ValueType> `from_json()` method throws
20605 
20606     @since version 2.1.0
20607     */
20608     template < typename ValueType,
20609                detail::enable_if_t <
20610                    detail::has_non_default_from_json<basic_json_t, ValueType>::value,
20611                    int > = 0 >
20612     ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20613                 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20614     {
20615         return JSONSerializer<ValueType>::from_json(*this);
20616     }
20617 
20618     /*!
20619     @brief get special-case overload
20620 
20621     This overloads converts the current @ref basic_json in a different
20622     @ref basic_json type
20623 
20624     @tparam BasicJsonType == @ref basic_json
20625 
20626     @return a copy of *this, converted into @a BasicJsonType
20627 
20628     @complexity Depending on the implementation of the called `from_json()`
20629                 method.
20630 
20631     @since version 3.2.0
20632     */
20633     template < typename BasicJsonType,
20634                detail::enable_if_t <
20635                    detail::is_basic_json<BasicJsonType>::value,
20636                    int > = 0 >
20637     BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20638     {
20639         return *this;
20640     }
20641 
20642     /*!
20643     @brief get special-case overload
20644 
20645     This overloads avoids a lot of template boilerplate, it can be seen as the
20646     identity method
20647 
20648     @tparam BasicJsonType == @ref basic_json
20649 
20650     @return a copy of *this
20651 
20652     @complexity Constant.
20653 
20654     @since version 2.1.0
20655     */
20656     template<typename BasicJsonType,
20657              detail::enable_if_t<
20658                  std::is_same<BasicJsonType, basic_json_t>::value,
20659                  int> = 0>
get_impl(detail::priority_tag<3>) const20660     basic_json get_impl(detail::priority_tag<3> /*unused*/) const
20661     {
20662         return *this;
20663     }
20664 
20665     /*!
20666     @brief get a pointer value (explicit)
20667     @copydoc get()
20668     */
20669     template<typename PointerType,
20670              detail::enable_if_t<
20671                  std::is_pointer<PointerType>::value,
20672                  int> = 0>
get_impl(detail::priority_tag<4>) const20673     constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20674     -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20675     {
20676         // delegate the call to get_ptr
20677         return get_ptr<PointerType>();
20678     }
20679 
20680   public:
20681     /*!
20682     @brief get a (pointer) value (explicit)
20683 
20684     Performs explicit type conversion between the JSON value and a compatible value if required.
20685 
20686     - If the requested type is a pointer to the internally stored JSON value that pointer is returned.
20687     No copies are made.
20688 
20689     - If the requested type is the current @ref basic_json, or a different @ref basic_json convertible
20690     from the current @ref basic_json.
20691 
20692     - Otherwise the value is converted by calling the @ref json_serializer<ValueType> `from_json()`
20693     method.
20694 
20695     @tparam ValueTypeCV the provided value type
20696     @tparam ValueType the returned value type
20697 
20698     @return copy of the JSON value, converted to @tparam ValueType if necessary
20699 
20700     @throw what @ref json_serializer<ValueType> `from_json()` method throws if conversion is required
20701 
20702     @since version 2.1.0
20703     */
20704     template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20705 #if defined(JSON_HAS_CPP_14)
20706     constexpr
20707 #endif
get() const20708     auto get() const noexcept(
20709     noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20710     -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20711     {
20712         // we cannot static_assert on ValueTypeCV being non-const, because
20713         // there is support for get<const basic_json_t>(), which is why we
20714         // still need the uncvref
20715         static_assert(!std::is_reference<ValueTypeCV>::value,
20716                       "get() cannot be used with reference types, you might want to use get_ref()");
20717         return get_impl<ValueType>(detail::priority_tag<4> {});
20718     }
20719 
20720     /*!
20721     @brief get a pointer value (explicit)
20722 
20723     Explicit pointer access to the internally stored JSON value. No copies are
20724     made.
20725 
20726     @warning The pointer becomes invalid if the underlying JSON object
20727     changes.
20728 
20729     @tparam PointerType pointer type; must be a pointer to @ref array_t, @ref
20730     object_t, @ref string_t, @ref boolean_t, @ref number_integer_t,
20731     @ref number_unsigned_t, or @ref number_float_t.
20732 
20733     @return pointer to the internally stored JSON value if the requested
20734     pointer type @a PointerType fits to the JSON value; `nullptr` otherwise
20735 
20736     @complexity Constant.
20737 
20738     @liveexample{The example below shows how pointers to internal values of a
20739     JSON value can be requested. Note that no type conversions are made and a
20740     `nullptr` is returned if the value and the requested pointer type does not
20741     match.,get__PointerType}
20742 
20743     @sa see @ref get_ptr() for explicit pointer-member access
20744 
20745     @since version 1.0.0
20746     */
20747     template<typename PointerType, typename std::enable_if<
20748                  std::is_pointer<PointerType>::value, int>::type = 0>
get()20749     auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20750     {
20751         // delegate the call to get_ptr
20752         return get_ptr<PointerType>();
20753     }
20754 
20755     /*!
20756     @brief get a value (explicit)
20757 
20758     Explicit type conversion between the JSON value and a compatible value.
20759     The value is filled into the input parameter by calling the @ref json_serializer<ValueType>
20760     `from_json()` method.
20761 
20762     The function is equivalent to executing
20763     @code {.cpp}
20764     ValueType v;
20765     JSONSerializer<ValueType>::from_json(*this, v);
20766     @endcode
20767 
20768     This overloads is chosen if:
20769     - @a ValueType is not @ref basic_json,
20770     - @ref json_serializer<ValueType> has a `from_json()` method of the form
20771       `void from_json(const basic_json&, ValueType&)`, and
20772 
20773     @tparam ValueType the input parameter type.
20774 
20775     @return the input parameter, allowing chaining calls.
20776 
20777     @throw what @ref json_serializer<ValueType> `from_json()` method throws
20778 
20779     @liveexample{The example below shows several conversions from JSON values
20780     to other types. There a few things to note: (1) Floating-point numbers can
20781     be converted to integers\, (2) A JSON array can be converted to a standard
20782     `std::vector<short>`\, (3) A JSON object can be converted to C++
20783     associative containers such as `std::unordered_map<std::string\,
20784     json>`.,get_to}
20785 
20786     @since version 3.3.0
20787     */
20788     template < typename ValueType,
20789                detail::enable_if_t <
20790                    !detail::is_basic_json<ValueType>::value&&
20791                    detail::has_from_json<basic_json_t, ValueType>::value,
20792                    int > = 0 >
20793     ValueType & get_to(ValueType& v) const noexcept(noexcept(
20794                 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20795     {
20796         JSONSerializer<ValueType>::from_json(*this, v);
20797         return v;
20798     }
20799 
20800     // specialization to allow to call get_to with a basic_json value
20801     // see https://github.com/nlohmann/json/issues/2175
20802     template<typename ValueType,
20803              detail::enable_if_t <
20804                  detail::is_basic_json<ValueType>::value,
20805                  int> = 0>
20806     ValueType & get_to(ValueType& v) const
20807     {
20808         v = *this;
20809         return v;
20810     }
20811 
20812     template <
20813         typename T, std::size_t N,
20814         typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20815         detail::enable_if_t <
20816             detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
20817     Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20818     noexcept(noexcept(JSONSerializer<Array>::from_json(
20819                           std::declval<const basic_json_t&>(), v)))
20820     {
20821         JSONSerializer<Array>::from_json(*this, v);
20822         return v;
20823     }
20824 
20825     /*!
20826     @brief get a reference value (implicit)
20827 
20828     Implicit reference access to the internally stored JSON value. No copies
20829     are made.
20830 
20831     @warning Writing data to the referee of the result yields an undefined
20832     state.
20833 
20834     @tparam ReferenceType reference type; must be a reference to @ref array_t,
20835     @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or
20836     @ref number_float_t. Enforced by static assertion.
20837 
20838     @return reference to the internally stored JSON value if the requested
20839     reference type @a ReferenceType fits to the JSON value; throws
20840     type_error.303 otherwise
20841 
20842     @throw type_error.303 in case passed type @a ReferenceType is incompatible
20843     with the stored JSON value; see example below
20844 
20845     @complexity Constant.
20846 
20847     @liveexample{The example shows several calls to `get_ref()`.,get_ref}
20848 
20849     @since version 1.1.0
20850     */
20851     template<typename ReferenceType, typename std::enable_if<
20852                  std::is_reference<ReferenceType>::value, int>::type = 0>
20853     ReferenceType get_ref()
20854     {
20855         // delegate call to get_ref_impl
20856         return get_ref_impl<ReferenceType>(*this);
20857     }
20858 
20859     /*!
20860     @brief get a reference value (implicit)
20861     @copydoc get_ref()
20862     */
20863     template < typename ReferenceType, typename std::enable_if <
20864                    std::is_reference<ReferenceType>::value&&
20865                    std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
20866     ReferenceType get_ref() const
20867     {
20868         // delegate call to get_ref_impl
20869         return get_ref_impl<ReferenceType>(*this);
20870     }
20871 
20872     /*!
20873     @brief get a value (implicit)
20874 
20875     Implicit type conversion between the JSON value and a compatible value.
20876     The call is realized by calling @ref get() const.
20877 
20878     @tparam ValueType non-pointer type compatible to the JSON value, for
20879     instance `int` for JSON integer numbers, `bool` for JSON booleans, or
20880     `std::vector` types for JSON arrays. The character type of @ref string_t
20881     as well as an initializer list of this type is excluded to avoid
20882     ambiguities as these types implicitly convert to `std::string`.
20883 
20884     @return copy of the JSON value, converted to type @a ValueType
20885 
20886     @throw type_error.302 in case passed type @a ValueType is incompatible
20887     to the JSON value type (e.g., the JSON value is of type boolean, but a
20888     string is requested); see example below
20889 
20890     @complexity Linear in the size of the JSON value.
20891 
20892     @liveexample{The example below shows several conversions from JSON values
20893     to other types. There a few things to note: (1) Floating-point numbers can
20894     be converted to integers\, (2) A JSON array can be converted to a standard
20895     `std::vector<short>`\, (3) A JSON object can be converted to C++
20896     associative containers such as `std::unordered_map<std::string\,
20897     json>`.,operator__ValueType}
20898 
20899     @since version 1.0.0
20900     */
20901     template < typename ValueType, typename std::enable_if <
20902                    detail::conjunction <
20903                        detail::negation<std::is_pointer<ValueType>>,
20904                        detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
20905                                         detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
20906                                         detail::negation<detail::is_basic_json<ValueType>>,
20907                                         detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,
20908 
20909 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20910                                                 detail::negation<std::is_same<ValueType, std::string_view>>,
20911 #endif
20912                                                 detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>
20913                                                 >::value, int >::type = 0 >
operator ValueType() const20914                                         JSON_EXPLICIT operator ValueType() const
20915     {
20916         // delegate the call to get<>() const
20917         return get<ValueType>();
20918     }
20919 
20920     /*!
20921     @return reference to the binary value
20922 
20923     @throw type_error.302 if the value is not binary
20924 
20925     @sa see @ref is_binary() to check if the value is binary
20926 
20927     @since version 3.8.0
20928     */
get_binary()20929     binary_t& get_binary()
20930     {
20931         if (!is_binary())
20932         {
20933             JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20934         }
20935 
20936         return *get_ptr<binary_t*>();
20937     }
20938 
20939     /// @copydoc get_binary()
get_binary() const20940     const binary_t& get_binary() const
20941     {
20942         if (!is_binary())
20943         {
20944             JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20945         }
20946 
20947         return *get_ptr<const binary_t*>();
20948     }
20949 
20950     /// @}
20951 
20952 
20953     ////////////////////
20954     // element access //
20955     ////////////////////
20956 
20957     /// @name element access
20958     /// Access to the JSON value.
20959     /// @{
20960 
20961     /*!
20962     @brief access specified array element with bounds checking
20963 
20964     Returns a reference to the element at specified location @a idx, with
20965     bounds checking.
20966 
20967     @param[in] idx  index of the element to access
20968 
20969     @return reference to the element at index @a idx
20970 
20971     @throw type_error.304 if the JSON value is not an array; in this case,
20972     calling `at` with an index makes no sense. See example below.
20973     @throw out_of_range.401 if the index @a idx is out of range of the array;
20974     that is, `idx >= size()`. See example below.
20975 
20976     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
20977     changes in the JSON value.
20978 
20979     @complexity Constant.
20980 
20981     @since version 1.0.0
20982 
20983     @liveexample{The example below shows how array elements can be read and
20984     written using `at()`. It also demonstrates the different exceptions that
20985     can be thrown.,at__size_type}
20986     */
at(size_type idx)20987     reference at(size_type idx)
20988     {
20989         // at only works for arrays
20990         if (JSON_HEDLEY_LIKELY(is_array()))
20991         {
20992             JSON_TRY
20993             {
20994                 return set_parent(m_value.array->at(idx));
20995             }
20996             JSON_CATCH (std::out_of_range&)
20997             {
20998                 // create better exception explanation
20999                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21000             }
21001         }
21002         else
21003         {
21004             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21005         }
21006     }
21007 
21008     /*!
21009     @brief access specified array element with bounds checking
21010 
21011     Returns a const reference to the element at specified location @a idx,
21012     with bounds checking.
21013 
21014     @param[in] idx  index of the element to access
21015 
21016     @return const reference to the element at index @a idx
21017 
21018     @throw type_error.304 if the JSON value is not an array; in this case,
21019     calling `at` with an index makes no sense. See example below.
21020     @throw out_of_range.401 if the index @a idx is out of range of the array;
21021     that is, `idx >= size()`. See example below.
21022 
21023     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21024     changes in the JSON value.
21025 
21026     @complexity Constant.
21027 
21028     @since version 1.0.0
21029 
21030     @liveexample{The example below shows how array elements can be read using
21031     `at()`. It also demonstrates the different exceptions that can be thrown.,
21032     at__size_type_const}
21033     */
at(size_type idx) const21034     const_reference at(size_type idx) const
21035     {
21036         // at only works for arrays
21037         if (JSON_HEDLEY_LIKELY(is_array()))
21038         {
21039             JSON_TRY
21040             {
21041                 return m_value.array->at(idx);
21042             }
21043             JSON_CATCH (std::out_of_range&)
21044             {
21045                 // create better exception explanation
21046                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21047             }
21048         }
21049         else
21050         {
21051             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21052         }
21053     }
21054 
21055     /*!
21056     @brief access specified object element with bounds checking
21057 
21058     Returns a reference to the element at with specified key @a key, with
21059     bounds checking.
21060 
21061     @param[in] key  key of the element to access
21062 
21063     @return reference to the element at key @a key
21064 
21065     @throw type_error.304 if the JSON value is not an object; in this case,
21066     calling `at` with a key makes no sense. See example below.
21067     @throw out_of_range.403 if the key @a key is is not stored in the object;
21068     that is, `find(key) == end()`. See example below.
21069 
21070     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21071     changes in the JSON value.
21072 
21073     @complexity Logarithmic in the size of the container.
21074 
21075     @sa see @ref operator[](const typename object_t::key_type&) for unchecked
21076     access by reference
21077     @sa see @ref value() for access by value with a default value
21078 
21079     @since version 1.0.0
21080 
21081     @liveexample{The example below shows how object elements can be read and
21082     written using `at()`. It also demonstrates the different exceptions that
21083     can be thrown.,at__object_t_key_type}
21084     */
at(const typename object_t::key_type & key)21085     reference at(const typename object_t::key_type& key)
21086     {
21087         // at only works for objects
21088         if (JSON_HEDLEY_LIKELY(is_object()))
21089         {
21090             JSON_TRY
21091             {
21092                 return set_parent(m_value.object->at(key));
21093             }
21094             JSON_CATCH (std::out_of_range&)
21095             {
21096                 // create better exception explanation
21097                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21098             }
21099         }
21100         else
21101         {
21102             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21103         }
21104     }
21105 
21106     /*!
21107     @brief access specified object element with bounds checking
21108 
21109     Returns a const reference to the element at with specified key @a key,
21110     with bounds checking.
21111 
21112     @param[in] key  key of the element to access
21113 
21114     @return const reference to the element at key @a key
21115 
21116     @throw type_error.304 if the JSON value is not an object; in this case,
21117     calling `at` with a key makes no sense. See example below.
21118     @throw out_of_range.403 if the key @a key is is not stored in the object;
21119     that is, `find(key) == end()`. See example below.
21120 
21121     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
21122     changes in the JSON value.
21123 
21124     @complexity Logarithmic in the size of the container.
21125 
21126     @sa see @ref operator[](const typename object_t::key_type&) for unchecked
21127     access by reference
21128     @sa see @ref value() for access by value with a default value
21129 
21130     @since version 1.0.0
21131 
21132     @liveexample{The example below shows how object elements can be read using
21133     `at()`. It also demonstrates the different exceptions that can be thrown.,
21134     at__object_t_key_type_const}
21135     */
at(const typename object_t::key_type & key) const21136     const_reference at(const typename object_t::key_type& key) const
21137     {
21138         // at only works for objects
21139         if (JSON_HEDLEY_LIKELY(is_object()))
21140         {
21141             JSON_TRY
21142             {
21143                 return m_value.object->at(key);
21144             }
21145             JSON_CATCH (std::out_of_range&)
21146             {
21147                 // create better exception explanation
21148                 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21149             }
21150         }
21151         else
21152         {
21153             JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21154         }
21155     }
21156 
21157     /*!
21158     @brief access specified array element
21159 
21160     Returns a reference to the element at specified location @a idx.
21161 
21162     @note If @a idx is beyond the range of the array (i.e., `idx >= size()`),
21163     then the array is silently filled up with `null` values to make `idx` a
21164     valid reference to the last stored element.
21165 
21166     @param[in] idx  index of the element to access
21167 
21168     @return reference to the element at index @a idx
21169 
21170     @throw type_error.305 if the JSON value is not an array or null; in that
21171     cases, using the [] operator with an index makes no sense.
21172 
21173     @complexity Constant if @a idx is in the range of the array. Otherwise
21174     linear in `idx - size()`.
21175 
21176     @liveexample{The example below shows how array elements can be read and
21177     written using `[]` operator. Note the addition of `null`
21178     values.,operatorarray__size_type}
21179 
21180     @since version 1.0.0
21181     */
operator [](size_type idx)21182     reference operator[](size_type idx)
21183     {
21184         // implicitly convert null value to an empty array
21185         if (is_null())
21186         {
21187             m_type = value_t::array;
21188             m_value.array = create<array_t>();
21189             assert_invariant();
21190         }
21191 
21192         // operator[] only works for arrays
21193         if (JSON_HEDLEY_LIKELY(is_array()))
21194         {
21195             // fill up array with null values if given idx is outside range
21196             if (idx >= m_value.array->size())
21197             {
21198 #if JSON_DIAGNOSTICS
21199                 // remember array size & capacity before resizing
21200                 const auto old_size = m_value.array->size();
21201                 const auto old_capacity = m_value.array->capacity();
21202 #endif
21203                 m_value.array->resize(idx + 1);
21204 
21205 #if JSON_DIAGNOSTICS
21206                 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
21207                 {
21208                     // capacity has changed: update all parents
21209                     set_parents();
21210                 }
21211                 else
21212                 {
21213                     // set parent for values added above
21214                     set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
21215                 }
21216 #endif
21217                 assert_invariant();
21218             }
21219 
21220             return m_value.array->operator[](idx);
21221         }
21222 
21223         JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21224     }
21225 
21226     /*!
21227     @brief access specified array element
21228 
21229     Returns a const reference to the element at specified location @a idx.
21230 
21231     @param[in] idx  index of the element to access
21232 
21233     @return const reference to the element at index @a idx
21234 
21235     @throw type_error.305 if the JSON value is not an array; in that case,
21236     using the [] operator with an index makes no sense.
21237 
21238     @complexity Constant.
21239 
21240     @liveexample{The example below shows how array elements can be read using
21241     the `[]` operator.,operatorarray__size_type_const}
21242 
21243     @since version 1.0.0
21244     */
operator [](size_type idx) const21245     const_reference operator[](size_type idx) const
21246     {
21247         // const operator[] only works for arrays
21248         if (JSON_HEDLEY_LIKELY(is_array()))
21249         {
21250             return m_value.array->operator[](idx);
21251         }
21252 
21253         JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21254     }
21255 
21256     /*!
21257     @brief access specified object element
21258 
21259     Returns a reference to the element at with specified key @a key.
21260 
21261     @note If @a key is not found in the object, then it is silently added to
21262     the object and filled with a `null` value to make `key` a valid reference.
21263     In case the value was `null` before, it is converted to an object.
21264 
21265     @param[in] key  key of the element to access
21266 
21267     @return reference to the element at key @a key
21268 
21269     @throw type_error.305 if the JSON value is not an object or null; in that
21270     cases, using the [] operator with a key makes no sense.
21271 
21272     @complexity Logarithmic in the size of the container.
21273 
21274     @liveexample{The example below shows how object elements can be read and
21275     written using the `[]` operator.,operatorarray__key_type}
21276 
21277     @sa see @ref at(const typename object_t::key_type&) for access by reference
21278     with range checking
21279     @sa see @ref value() for access by value with a default value
21280 
21281     @since version 1.0.0
21282     */
operator [](const typename object_t::key_type & key)21283     reference operator[](const typename object_t::key_type& key)
21284     {
21285         // implicitly convert null value to an empty object
21286         if (is_null())
21287         {
21288             m_type = value_t::object;
21289             m_value.object = create<object_t>();
21290             assert_invariant();
21291         }
21292 
21293         // operator[] only works for objects
21294         if (JSON_HEDLEY_LIKELY(is_object()))
21295         {
21296             return set_parent(m_value.object->operator[](key));
21297         }
21298 
21299         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21300     }
21301 
21302     /*!
21303     @brief read-only access specified object element
21304 
21305     Returns a const reference to the element at with specified key @a key. No
21306     bounds checking is performed.
21307 
21308     @warning If the element with key @a key does not exist, the behavior is
21309     undefined.
21310 
21311     @param[in] key  key of the element to access
21312 
21313     @return const reference to the element at key @a key
21314 
21315     @pre The element with key @a key must exist. **This precondition is
21316          enforced with an assertion.**
21317 
21318     @throw type_error.305 if the JSON value is not an object; in that case,
21319     using the [] operator with a key makes no sense.
21320 
21321     @complexity Logarithmic in the size of the container.
21322 
21323     @liveexample{The example below shows how object elements can be read using
21324     the `[]` operator.,operatorarray__key_type_const}
21325 
21326     @sa see @ref at(const typename object_t::key_type&) for access by reference
21327     with range checking
21328     @sa see @ref value() for access by value with a default value
21329 
21330     @since version 1.0.0
21331     */
operator [](const typename object_t::key_type & key) const21332     const_reference operator[](const typename object_t::key_type& key) const
21333     {
21334         // const operator[] only works for objects
21335         if (JSON_HEDLEY_LIKELY(is_object()))
21336         {
21337             JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21338             return m_value.object->find(key)->second;
21339         }
21340 
21341         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21342     }
21343 
21344     /*!
21345     @brief access specified object element
21346 
21347     Returns a reference to the element at with specified key @a key.
21348 
21349     @note If @a key is not found in the object, then it is silently added to
21350     the object and filled with a `null` value to make `key` a valid reference.
21351     In case the value was `null` before, it is converted to an object.
21352 
21353     @param[in] key  key of the element to access
21354 
21355     @return reference to the element at key @a key
21356 
21357     @throw type_error.305 if the JSON value is not an object or null; in that
21358     cases, using the [] operator with a key makes no sense.
21359 
21360     @complexity Logarithmic in the size of the container.
21361 
21362     @liveexample{The example below shows how object elements can be read and
21363     written using the `[]` operator.,operatorarray__key_type}
21364 
21365     @sa see @ref at(const typename object_t::key_type&) for access by reference
21366     with range checking
21367     @sa see @ref value() for access by value with a default value
21368 
21369     @since version 1.1.0
21370     */
21371     template<typename T>
21372     JSON_HEDLEY_NON_NULL(2)
operator [](T * key)21373     reference operator[](T* key)
21374     {
21375         // implicitly convert null to object
21376         if (is_null())
21377         {
21378             m_type = value_t::object;
21379             m_value = value_t::object;
21380             assert_invariant();
21381         }
21382 
21383         // at only works for objects
21384         if (JSON_HEDLEY_LIKELY(is_object()))
21385         {
21386             return set_parent(m_value.object->operator[](key));
21387         }
21388 
21389         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21390     }
21391 
21392     /*!
21393     @brief read-only access specified object element
21394 
21395     Returns a const reference to the element at with specified key @a key. No
21396     bounds checking is performed.
21397 
21398     @warning If the element with key @a key does not exist, the behavior is
21399     undefined.
21400 
21401     @param[in] key  key of the element to access
21402 
21403     @return const reference to the element at key @a key
21404 
21405     @pre The element with key @a key must exist. **This precondition is
21406          enforced with an assertion.**
21407 
21408     @throw type_error.305 if the JSON value is not an object; in that case,
21409     using the [] operator with a key makes no sense.
21410 
21411     @complexity Logarithmic in the size of the container.
21412 
21413     @liveexample{The example below shows how object elements can be read using
21414     the `[]` operator.,operatorarray__key_type_const}
21415 
21416     @sa see @ref at(const typename object_t::key_type&) for access by reference
21417     with range checking
21418     @sa see @ref value() for access by value with a default value
21419 
21420     @since version 1.1.0
21421     */
21422     template<typename T>
21423     JSON_HEDLEY_NON_NULL(2)
operator [](T * key) const21424     const_reference operator[](T* key) const
21425     {
21426         // at only works for objects
21427         if (JSON_HEDLEY_LIKELY(is_object()))
21428         {
21429             JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21430             return m_value.object->find(key)->second;
21431         }
21432 
21433         JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21434     }
21435 
21436     /*!
21437     @brief access specified object element with default value
21438 
21439     Returns either a copy of an object's element at the specified key @a key
21440     or a given default value if no element with key @a key exists.
21441 
21442     The function is basically equivalent to executing
21443     @code {.cpp}
21444     try {
21445         return at(key);
21446     } catch(out_of_range) {
21447         return default_value;
21448     }
21449     @endcode
21450 
21451     @note Unlike @ref at(const typename object_t::key_type&), this function
21452     does not throw if the given key @a key was not found.
21453 
21454     @note Unlike @ref operator[](const typename object_t::key_type& key), this
21455     function does not implicitly add an element to the position defined by @a
21456     key. This function is furthermore also applicable to const objects.
21457 
21458     @param[in] key  key of the element to access
21459     @param[in] default_value  the value to return if @a key is not found
21460 
21461     @tparam ValueType type compatible to JSON values, for instance `int` for
21462     JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
21463     JSON arrays. Note the type of the expected value at @a key and the default
21464     value @a default_value must be compatible.
21465 
21466     @return copy of the element at key @a key or @a default_value if @a key
21467     is not found
21468 
21469     @throw type_error.302 if @a default_value does not match the type of the
21470     value at @a key
21471     @throw type_error.306 if the JSON value is not an object; in that case,
21472     using `value()` with a key makes no sense.
21473 
21474     @complexity Logarithmic in the size of the container.
21475 
21476     @liveexample{The example below shows how object elements can be queried
21477     with a default value.,basic_json__value}
21478 
21479     @sa see @ref at(const typename object_t::key_type&) for access by reference
21480     with range checking
21481     @sa see @ref operator[](const typename object_t::key_type&) for unchecked
21482     access by reference
21483 
21484     @since version 1.0.0
21485     */
21486     // using std::is_convertible in a std::enable_if will fail when using explicit conversions
21487     template < class ValueType, typename std::enable_if <
21488                    detail::is_getable<basic_json_t, ValueType>::value
21489                    && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
21490     ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21491     {
21492         // at only works for objects
21493         if (JSON_HEDLEY_LIKELY(is_object()))
21494         {
21495             // if key is found, return value and given default value otherwise
21496             const auto it = find(key);
21497             if (it != end())
21498             {
21499                 return it->template get<ValueType>();
21500             }
21501 
21502             return default_value;
21503         }
21504 
21505         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21506     }
21507 
21508     /*!
21509     @brief overload for a default value of type const char*
21510     @copydoc basic_json::value(const typename object_t::key_type&, const ValueType&) const
21511     */
value(const typename object_t::key_type & key,const char * default_value) const21512     string_t value(const typename object_t::key_type& key, const char* default_value) const
21513     {
21514         return value(key, string_t(default_value));
21515     }
21516 
21517     /*!
21518     @brief access specified object element via JSON Pointer with default value
21519 
21520     Returns either a copy of an object's element at the specified key @a key
21521     or a given default value if no element with key @a key exists.
21522 
21523     The function is basically equivalent to executing
21524     @code {.cpp}
21525     try {
21526         return at(ptr);
21527     } catch(out_of_range) {
21528         return default_value;
21529     }
21530     @endcode
21531 
21532     @note Unlike @ref at(const json_pointer&), this function does not throw
21533     if the given key @a key was not found.
21534 
21535     @param[in] ptr  a JSON pointer to the element to access
21536     @param[in] default_value  the value to return if @a ptr found no value
21537 
21538     @tparam ValueType type compatible to JSON values, for instance `int` for
21539     JSON integer numbers, `bool` for JSON booleans, or `std::vector` types for
21540     JSON arrays. Note the type of the expected value at @a key and the default
21541     value @a default_value must be compatible.
21542 
21543     @return copy of the element at key @a key or @a default_value if @a key
21544     is not found
21545 
21546     @throw type_error.302 if @a default_value does not match the type of the
21547     value at @a ptr
21548     @throw type_error.306 if the JSON value is not an object; in that case,
21549     using `value()` with a key makes no sense.
21550 
21551     @complexity Logarithmic in the size of the container.
21552 
21553     @liveexample{The example below shows how object elements can be queried
21554     with a default value.,basic_json__value_ptr}
21555 
21556     @sa see @ref operator[](const json_pointer&) for unchecked access by reference
21557 
21558     @since version 2.0.2
21559     */
21560     template<class ValueType, typename std::enable_if<
21561                  detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
21562     ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21563     {
21564         // at only works for objects
21565         if (JSON_HEDLEY_LIKELY(is_object()))
21566         {
21567             // if pointer resolves a value, return it or use default value
21568             JSON_TRY
21569             {
21570                 return ptr.get_checked(this).template get<ValueType>();
21571             }
21572             JSON_INTERNAL_CATCH (out_of_range&)
21573             {
21574                 return default_value;
21575             }
21576         }
21577 
21578         JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21579     }
21580 
21581     /*!
21582     @brief overload for a default value of type const char*
21583     @copydoc basic_json::value(const json_pointer&, ValueType) const
21584     */
21585     JSON_HEDLEY_NON_NULL(3)
value(const json_pointer & ptr,const char * default_value) const21586     string_t value(const json_pointer& ptr, const char* default_value) const
21587     {
21588         return value(ptr, string_t(default_value));
21589     }
21590 
21591     /*!
21592     @brief access the first element
21593 
21594     Returns a reference to the first element in the container. For a JSON
21595     container `c`, the expression `c.front()` is equivalent to `*c.begin()`.
21596 
21597     @return In case of a structured type (array or object), a reference to the
21598     first element is returned. In case of number, string, boolean, or binary
21599     values, a reference to the value is returned.
21600 
21601     @complexity Constant.
21602 
21603     @pre The JSON value must not be `null` (would throw `std::out_of_range`)
21604     or an empty array or object (undefined behavior, **guarded by
21605     assertions**).
21606     @post The JSON value remains unchanged.
21607 
21608     @throw invalid_iterator.214 when called on `null` value
21609 
21610     @liveexample{The following code shows an example for `front()`.,front}
21611 
21612     @sa see @ref back() -- access the last element
21613 
21614     @since version 1.0.0
21615     */
front()21616     reference front()
21617     {
21618         return *begin();
21619     }
21620 
21621     /*!
21622     @copydoc basic_json::front()
21623     */
front() const21624     const_reference front() const
21625     {
21626         return *cbegin();
21627     }
21628 
21629     /*!
21630     @brief access the last element
21631 
21632     Returns a reference to the last element in the container. For a JSON
21633     container `c`, the expression `c.back()` is equivalent to
21634     @code {.cpp}
21635     auto tmp = c.end();
21636     --tmp;
21637     return *tmp;
21638     @endcode
21639 
21640     @return In case of a structured type (array or object), a reference to the
21641     last element is returned. In case of number, string, boolean, or binary
21642     values, a reference to the value is returned.
21643 
21644     @complexity Constant.
21645 
21646     @pre The JSON value must not be `null` (would throw `std::out_of_range`)
21647     or an empty array or object (undefined behavior, **guarded by
21648     assertions**).
21649     @post The JSON value remains unchanged.
21650 
21651     @throw invalid_iterator.214 when called on a `null` value. See example
21652     below.
21653 
21654     @liveexample{The following code shows an example for `back()`.,back}
21655 
21656     @sa see @ref front() -- access the first element
21657 
21658     @since version 1.0.0
21659     */
back()21660     reference back()
21661     {
21662         auto tmp = end();
21663         --tmp;
21664         return *tmp;
21665     }
21666 
21667     /*!
21668     @copydoc basic_json::back()
21669     */
back() const21670     const_reference back() const
21671     {
21672         auto tmp = cend();
21673         --tmp;
21674         return *tmp;
21675     }
21676 
21677     /*!
21678     @brief remove element given an iterator
21679 
21680     Removes the element specified by iterator @a pos. The iterator @a pos must
21681     be valid and dereferenceable. Thus the `end()` iterator (which is valid,
21682     but is not dereferenceable) cannot be used as a value for @a pos.
21683 
21684     If called on a primitive type other than `null`, the resulting JSON value
21685     will be `null`.
21686 
21687     @param[in] pos iterator to the element to remove
21688     @return Iterator following the last removed element. If the iterator @a
21689     pos refers to the last element, the `end()` iterator is returned.
21690 
21691     @tparam IteratorType an @ref iterator or @ref const_iterator
21692 
21693     @post Invalidates iterators and references at or after the point of the
21694     erase, including the `end()` iterator.
21695 
21696     @throw type_error.307 if called on a `null` value; example: `"cannot use
21697     erase() with null"`
21698     @throw invalid_iterator.202 if called on an iterator which does not belong
21699     to the current JSON value; example: `"iterator does not fit current
21700     value"`
21701     @throw invalid_iterator.205 if called on a primitive type with invalid
21702     iterator (i.e., any iterator which is not `begin()`); example: `"iterator
21703     out of range"`
21704 
21705     @complexity The complexity depends on the type:
21706     - objects: amortized constant
21707     - arrays: linear in distance between @a pos and the end of the container
21708     - strings and binary: linear in the length of the member
21709     - other types: constant
21710 
21711     @liveexample{The example shows the result of `erase()` for different JSON
21712     types.,erase__IteratorType}
21713 
21714     @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21715     the given range
21716     @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21717     from an object at the given key
21718     @sa see @ref erase(const size_type) -- removes the element from an array at
21719     the given index
21720 
21721     @since version 1.0.0
21722     */
21723     template < class IteratorType, typename std::enable_if <
21724                    std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21725                    std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21726                = 0 >
21727     IteratorType erase(IteratorType pos)
21728     {
21729         // make sure iterator fits the current value
21730         if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21731         {
21732             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
21733         }
21734 
21735         IteratorType result = end();
21736 
21737         switch (m_type)
21738         {
21739             case value_t::boolean:
21740             case value_t::number_float:
21741             case value_t::number_integer:
21742             case value_t::number_unsigned:
21743             case value_t::string:
21744             case value_t::binary:
21745             {
21746                 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21747                 {
21748                     JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
21749                 }
21750 
21751                 if (is_string())
21752                 {
21753                     AllocatorType<string_t> alloc;
21754                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21755                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21756                     m_value.string = nullptr;
21757                 }
21758                 else if (is_binary())
21759                 {
21760                     AllocatorType<binary_t> alloc;
21761                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21762                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21763                     m_value.binary = nullptr;
21764                 }
21765 
21766                 m_type = value_t::null;
21767                 assert_invariant();
21768                 break;
21769             }
21770 
21771             case value_t::object:
21772             {
21773                 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21774                 break;
21775             }
21776 
21777             case value_t::array:
21778             {
21779                 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21780                 break;
21781             }
21782 
21783             case value_t::null:
21784             case value_t::discarded:
21785             default:
21786                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21787         }
21788 
21789         return result;
21790     }
21791 
21792     /*!
21793     @brief remove elements given an iterator range
21794 
21795     Removes the element specified by the range `[first; last)`. The iterator
21796     @a first does not need to be dereferenceable if `first == last`: erasing
21797     an empty range is a no-op.
21798 
21799     If called on a primitive type other than `null`, the resulting JSON value
21800     will be `null`.
21801 
21802     @param[in] first iterator to the beginning of the range to remove
21803     @param[in] last iterator past the end of the range to remove
21804     @return Iterator following the last removed element. If the iterator @a
21805     second refers to the last element, the `end()` iterator is returned.
21806 
21807     @tparam IteratorType an @ref iterator or @ref const_iterator
21808 
21809     @post Invalidates iterators and references at or after the point of the
21810     erase, including the `end()` iterator.
21811 
21812     @throw type_error.307 if called on a `null` value; example: `"cannot use
21813     erase() with null"`
21814     @throw invalid_iterator.203 if called on iterators which does not belong
21815     to the current JSON value; example: `"iterators do not fit current value"`
21816     @throw invalid_iterator.204 if called on a primitive type with invalid
21817     iterators (i.e., if `first != begin()` and `last != end()`); example:
21818     `"iterators out of range"`
21819 
21820     @complexity The complexity depends on the type:
21821     - objects: `log(size()) + std::distance(first, last)`
21822     - arrays: linear in the distance between @a first and @a last, plus linear
21823       in the distance between @a last and end of the container
21824     - strings and binary: linear in the length of the member
21825     - other types: constant
21826 
21827     @liveexample{The example shows the result of `erase()` for different JSON
21828     types.,erase__IteratorType_IteratorType}
21829 
21830     @sa see @ref erase(IteratorType) -- removes the element at a given position
21831     @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21832     from an object at the given key
21833     @sa see @ref erase(const size_type) -- removes the element from an array at
21834     the given index
21835 
21836     @since version 1.0.0
21837     */
21838     template < class IteratorType, typename std::enable_if <
21839                    std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21840                    std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21841                = 0 >
21842     IteratorType erase(IteratorType first, IteratorType last)
21843     {
21844         // make sure iterator fits the current value
21845         if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21846         {
21847             JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
21848         }
21849 
21850         IteratorType result = end();
21851 
21852         switch (m_type)
21853         {
21854             case value_t::boolean:
21855             case value_t::number_float:
21856             case value_t::number_integer:
21857             case value_t::number_unsigned:
21858             case value_t::string:
21859             case value_t::binary:
21860             {
21861                 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21862                                        || !last.m_it.primitive_iterator.is_end()))
21863                 {
21864                     JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
21865                 }
21866 
21867                 if (is_string())
21868                 {
21869                     AllocatorType<string_t> alloc;
21870                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21871                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21872                     m_value.string = nullptr;
21873                 }
21874                 else if (is_binary())
21875                 {
21876                     AllocatorType<binary_t> alloc;
21877                     std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21878                     std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21879                     m_value.binary = nullptr;
21880                 }
21881 
21882                 m_type = value_t::null;
21883                 assert_invariant();
21884                 break;
21885             }
21886 
21887             case value_t::object:
21888             {
21889                 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21890                                               last.m_it.object_iterator);
21891                 break;
21892             }
21893 
21894             case value_t::array:
21895             {
21896                 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21897                                              last.m_it.array_iterator);
21898                 break;
21899             }
21900 
21901             case value_t::null:
21902             case value_t::discarded:
21903             default:
21904                 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21905         }
21906 
21907         return result;
21908     }
21909 
21910     /*!
21911     @brief remove element from a JSON object given a key
21912 
21913     Removes elements from a JSON object with the key value @a key.
21914 
21915     @param[in] key value of the elements to remove
21916 
21917     @return Number of elements removed. If @a ObjectType is the default
21918     `std::map` type, the return value will always be `0` (@a key was not
21919     found) or `1` (@a key was found).
21920 
21921     @post References and iterators to the erased elements are invalidated.
21922     Other references and iterators are not affected.
21923 
21924     @throw type_error.307 when called on a type other than JSON object;
21925     example: `"cannot use erase() with null"`
21926 
21927     @complexity `log(size()) + count(key)`
21928 
21929     @liveexample{The example shows the effect of `erase()`.,erase__key_type}
21930 
21931     @sa see @ref erase(IteratorType) -- removes the element at a given position
21932     @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21933     the given range
21934     @sa see @ref erase(const size_type) -- removes the element from an array at
21935     the given index
21936 
21937     @since version 1.0.0
21938     */
erase(const typename object_t::key_type & key)21939     size_type erase(const typename object_t::key_type& key)
21940     {
21941         // this erase only works for objects
21942         if (JSON_HEDLEY_LIKELY(is_object()))
21943         {
21944             return m_value.object->erase(key);
21945         }
21946 
21947         JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21948     }
21949 
21950     /*!
21951     @brief remove element from a JSON array given an index
21952 
21953     Removes element from a JSON array at the index @a idx.
21954 
21955     @param[in] idx index of the element to remove
21956 
21957     @throw type_error.307 when called on a type other than JSON object;
21958     example: `"cannot use erase() with null"`
21959     @throw out_of_range.401 when `idx >= size()`; example: `"array index 17
21960     is out of range"`
21961 
21962     @complexity Linear in distance between @a idx and the end of the container.
21963 
21964     @liveexample{The example shows the effect of `erase()`.,erase__size_type}
21965 
21966     @sa see @ref erase(IteratorType) -- removes the element at a given position
21967     @sa see @ref erase(IteratorType, IteratorType) -- removes the elements in
21968     the given range
21969     @sa see @ref erase(const typename object_t::key_type&) -- removes the element
21970     from an object at the given key
21971 
21972     @since version 1.0.0
21973     */
erase(const size_type idx)21974     void erase(const size_type idx)
21975     {
21976         // this erase only works for arrays
21977         if (JSON_HEDLEY_LIKELY(is_array()))
21978         {
21979             if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21980             {
21981                 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21982             }
21983 
21984             m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21985         }
21986         else
21987         {
21988             JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21989         }
21990     }
21991 
21992     /// @}
21993 
21994 
21995     ////////////
21996     // lookup //
21997     ////////////
21998 
21999     /// @name lookup
22000     /// @{
22001 
22002     /*!
22003     @brief find an element in a JSON object
22004 
22005     Finds an element in a JSON object with key equivalent to @a key. If the
22006     element is not found or the JSON value is not an object, end() is
22007     returned.
22008 
22009     @note This method always returns @ref end() when executed on a JSON type
22010           that is not an object.
22011 
22012     @param[in] key key value of the element to search for.
22013 
22014     @return Iterator to an element with key equivalent to @a key. If no such
22015     element is found or the JSON value is not an object, past-the-end (see
22016     @ref end()) iterator is returned.
22017 
22018     @complexity Logarithmic in the size of the JSON object.
22019 
22020     @liveexample{The example shows how `find()` is used.,find__key_type}
22021 
22022     @sa see @ref contains(KeyT&&) const -- checks whether a key exists
22023 
22024     @since version 1.0.0
22025     */
22026     template<typename KeyT>
find(KeyT && key)22027     iterator find(KeyT&& key)
22028     {
22029         auto result = end();
22030 
22031         if (is_object())
22032         {
22033             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
22034         }
22035 
22036         return result;
22037     }
22038 
22039     /*!
22040     @brief find an element in a JSON object
22041     @copydoc find(KeyT&&)
22042     */
22043     template<typename KeyT>
find(KeyT && key) const22044     const_iterator find(KeyT&& key) const
22045     {
22046         auto result = cend();
22047 
22048         if (is_object())
22049         {
22050             result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
22051         }
22052 
22053         return result;
22054     }
22055 
22056     /*!
22057     @brief returns the number of occurrences of a key in a JSON object
22058 
22059     Returns the number of elements with key @a key. If ObjectType is the
22060     default `std::map` type, the return value will always be `0` (@a key was
22061     not found) or `1` (@a key was found).
22062 
22063     @note This method always returns `0` when executed on a JSON type that is
22064           not an object.
22065 
22066     @param[in] key key value of the element to count
22067 
22068     @return Number of elements with key @a key. If the JSON value is not an
22069     object, the return value will be `0`.
22070 
22071     @complexity Logarithmic in the size of the JSON object.
22072 
22073     @liveexample{The example shows how `count()` is used.,count}
22074 
22075     @since version 1.0.0
22076     */
22077     template<typename KeyT>
count(KeyT && key) const22078     size_type count(KeyT&& key) const
22079     {
22080         // return 0 for all nonobject types
22081         return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
22082     }
22083 
22084     /*!
22085     @brief check the existence of an element in a JSON object
22086 
22087     Check whether an element exists in a JSON object with key equivalent to
22088     @a key. If the element is not found or the JSON value is not an object,
22089     false is returned.
22090 
22091     @note This method always returns false when executed on a JSON type
22092           that is not an object.
22093 
22094     @param[in] key key value to check its existence.
22095 
22096     @return true if an element with specified @a key exists. If no such
22097     element with such key is found or the JSON value is not an object,
22098     false is returned.
22099 
22100     @complexity Logarithmic in the size of the JSON object.
22101 
22102     @liveexample{The following code shows an example for `contains()`.,contains}
22103 
22104     @sa see @ref find(KeyT&&) -- returns an iterator to an object element
22105     @sa see @ref contains(const json_pointer&) const -- checks the existence for a JSON pointer
22106 
22107     @since version 3.6.0
22108     */
22109     template < typename KeyT, typename std::enable_if <
22110                    !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
contains(KeyT && key) const22111     bool contains(KeyT && key) const
22112     {
22113         return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
22114     }
22115 
22116     /*!
22117     @brief check the existence of an element in a JSON object given a JSON pointer
22118 
22119     Check whether the given JSON pointer @a ptr can be resolved in the current
22120     JSON value.
22121 
22122     @note This method can be executed on any JSON value type.
22123 
22124     @param[in] ptr JSON pointer to check its existence.
22125 
22126     @return true if the JSON pointer can be resolved to a stored value, false
22127     otherwise.
22128 
22129     @post If `j.contains(ptr)` returns true, it is safe to call `j[ptr]`.
22130 
22131     @throw parse_error.106   if an array index begins with '0'
22132     @throw parse_error.109   if an array index was not a number
22133 
22134     @complexity Logarithmic in the size of the JSON object.
22135 
22136     @liveexample{The following code shows an example for `contains()`.,contains_json_pointer}
22137 
22138     @sa see @ref contains(KeyT &&) const -- checks the existence of a key
22139 
22140     @since version 3.7.0
22141     */
contains(const json_pointer & ptr) const22142     bool contains(const json_pointer& ptr) const
22143     {
22144         return ptr.contains(this);
22145     }
22146 
22147     /// @}
22148 
22149 
22150     ///////////////
22151     // iterators //
22152     ///////////////
22153 
22154     /// @name iterators
22155     /// @{
22156 
22157     /*!
22158     @brief returns an iterator to the first element
22159 
22160     Returns an iterator to the first element.
22161 
22162     @image html range-begin-end.svg "Illustration from cppreference.com"
22163 
22164     @return iterator to the first element
22165 
22166     @complexity Constant.
22167 
22168     @requirement This function helps `basic_json` satisfying the
22169     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22170     requirements:
22171     - The complexity is constant.
22172 
22173     @liveexample{The following code shows an example for `begin()`.,begin}
22174 
22175     @sa see @ref cbegin() -- returns a const iterator to the beginning
22176     @sa see @ref end() -- returns an iterator to the end
22177     @sa see @ref cend() -- returns a const iterator to the end
22178 
22179     @since version 1.0.0
22180     */
begin()22181     iterator begin() noexcept
22182     {
22183         iterator result(this);
22184         result.set_begin();
22185         return result;
22186     }
22187 
22188     /*!
22189     @copydoc basic_json::cbegin()
22190     */
begin() const22191     const_iterator begin() const noexcept
22192     {
22193         return cbegin();
22194     }
22195 
22196     /*!
22197     @brief returns a const iterator to the first element
22198 
22199     Returns a const iterator to the first element.
22200 
22201     @image html range-begin-end.svg "Illustration from cppreference.com"
22202 
22203     @return const iterator to the first element
22204 
22205     @complexity Constant.
22206 
22207     @requirement This function helps `basic_json` satisfying the
22208     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22209     requirements:
22210     - The complexity is constant.
22211     - Has the semantics of `const_cast<const basic_json&>(*this).begin()`.
22212 
22213     @liveexample{The following code shows an example for `cbegin()`.,cbegin}
22214 
22215     @sa see @ref begin() -- returns an iterator to the beginning
22216     @sa see @ref end() -- returns an iterator to the end
22217     @sa see @ref cend() -- returns a const iterator to the end
22218 
22219     @since version 1.0.0
22220     */
cbegin() const22221     const_iterator cbegin() const noexcept
22222     {
22223         const_iterator result(this);
22224         result.set_begin();
22225         return result;
22226     }
22227 
22228     /*!
22229     @brief returns an iterator to one past the last element
22230 
22231     Returns an iterator to one past the last element.
22232 
22233     @image html range-begin-end.svg "Illustration from cppreference.com"
22234 
22235     @return iterator one past the last element
22236 
22237     @complexity Constant.
22238 
22239     @requirement This function helps `basic_json` satisfying the
22240     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22241     requirements:
22242     - The complexity is constant.
22243 
22244     @liveexample{The following code shows an example for `end()`.,end}
22245 
22246     @sa see @ref cend() -- returns a const iterator to the end
22247     @sa see @ref begin() -- returns an iterator to the beginning
22248     @sa see @ref cbegin() -- returns a const iterator to the beginning
22249 
22250     @since version 1.0.0
22251     */
end()22252     iterator end() noexcept
22253     {
22254         iterator result(this);
22255         result.set_end();
22256         return result;
22257     }
22258 
22259     /*!
22260     @copydoc basic_json::cend()
22261     */
end() const22262     const_iterator end() const noexcept
22263     {
22264         return cend();
22265     }
22266 
22267     /*!
22268     @brief returns a const iterator to one past the last element
22269 
22270     Returns a const iterator to one past the last element.
22271 
22272     @image html range-begin-end.svg "Illustration from cppreference.com"
22273 
22274     @return const iterator one past the last element
22275 
22276     @complexity Constant.
22277 
22278     @requirement This function helps `basic_json` satisfying the
22279     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22280     requirements:
22281     - The complexity is constant.
22282     - Has the semantics of `const_cast<const basic_json&>(*this).end()`.
22283 
22284     @liveexample{The following code shows an example for `cend()`.,cend}
22285 
22286     @sa see @ref end() -- returns an iterator to the end
22287     @sa see @ref begin() -- returns an iterator to the beginning
22288     @sa see @ref cbegin() -- returns a const iterator to the beginning
22289 
22290     @since version 1.0.0
22291     */
cend() const22292     const_iterator cend() const noexcept
22293     {
22294         const_iterator result(this);
22295         result.set_end();
22296         return result;
22297     }
22298 
22299     /*!
22300     @brief returns an iterator to the reverse-beginning
22301 
22302     Returns an iterator to the reverse-beginning; that is, the last element.
22303 
22304     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22305 
22306     @complexity Constant.
22307 
22308     @requirement This function helps `basic_json` satisfying the
22309     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22310     requirements:
22311     - The complexity is constant.
22312     - Has the semantics of `reverse_iterator(end())`.
22313 
22314     @liveexample{The following code shows an example for `rbegin()`.,rbegin}
22315 
22316     @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22317     @sa see @ref rend() -- returns a reverse iterator to the end
22318     @sa see @ref crend() -- returns a const reverse iterator to the end
22319 
22320     @since version 1.0.0
22321     */
rbegin()22322     reverse_iterator rbegin() noexcept
22323     {
22324         return reverse_iterator(end());
22325     }
22326 
22327     /*!
22328     @copydoc basic_json::crbegin()
22329     */
rbegin() const22330     const_reverse_iterator rbegin() const noexcept
22331     {
22332         return crbegin();
22333     }
22334 
22335     /*!
22336     @brief returns an iterator to the reverse-end
22337 
22338     Returns an iterator to the reverse-end; that is, one before the first
22339     element.
22340 
22341     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22342 
22343     @complexity Constant.
22344 
22345     @requirement This function helps `basic_json` satisfying the
22346     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22347     requirements:
22348     - The complexity is constant.
22349     - Has the semantics of `reverse_iterator(begin())`.
22350 
22351     @liveexample{The following code shows an example for `rend()`.,rend}
22352 
22353     @sa see @ref crend() -- returns a const reverse iterator to the end
22354     @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22355     @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22356 
22357     @since version 1.0.0
22358     */
rend()22359     reverse_iterator rend() noexcept
22360     {
22361         return reverse_iterator(begin());
22362     }
22363 
22364     /*!
22365     @copydoc basic_json::crend()
22366     */
rend() const22367     const_reverse_iterator rend() const noexcept
22368     {
22369         return crend();
22370     }
22371 
22372     /*!
22373     @brief returns a const reverse iterator to the last element
22374 
22375     Returns a const iterator to the reverse-beginning; that is, the last
22376     element.
22377 
22378     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22379 
22380     @complexity Constant.
22381 
22382     @requirement This function helps `basic_json` satisfying the
22383     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22384     requirements:
22385     - The complexity is constant.
22386     - Has the semantics of `const_cast<const basic_json&>(*this).rbegin()`.
22387 
22388     @liveexample{The following code shows an example for `crbegin()`.,crbegin}
22389 
22390     @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22391     @sa see @ref rend() -- returns a reverse iterator to the end
22392     @sa see @ref crend() -- returns a const reverse iterator to the end
22393 
22394     @since version 1.0.0
22395     */
crbegin() const22396     const_reverse_iterator crbegin() const noexcept
22397     {
22398         return const_reverse_iterator(cend());
22399     }
22400 
22401     /*!
22402     @brief returns a const reverse iterator to one before the first
22403 
22404     Returns a const reverse iterator to the reverse-end; that is, one before
22405     the first element.
22406 
22407     @image html range-rbegin-rend.svg "Illustration from cppreference.com"
22408 
22409     @complexity Constant.
22410 
22411     @requirement This function helps `basic_json` satisfying the
22412     [ReversibleContainer](https://en.cppreference.com/w/cpp/named_req/ReversibleContainer)
22413     requirements:
22414     - The complexity is constant.
22415     - Has the semantics of `const_cast<const basic_json&>(*this).rend()`.
22416 
22417     @liveexample{The following code shows an example for `crend()`.,crend}
22418 
22419     @sa see @ref rend() -- returns a reverse iterator to the end
22420     @sa see @ref rbegin() -- returns a reverse iterator to the beginning
22421     @sa see @ref crbegin() -- returns a const reverse iterator to the beginning
22422 
22423     @since version 1.0.0
22424     */
crend() const22425     const_reverse_iterator crend() const noexcept
22426     {
22427         return const_reverse_iterator(cbegin());
22428     }
22429 
22430   public:
22431     /*!
22432     @brief wrapper to access iterator member functions in range-based for
22433 
22434     This function allows to access @ref iterator::key() and @ref
22435     iterator::value() during range-based for loops. In these loops, a
22436     reference to the JSON values is returned, so there is no access to the
22437     underlying iterator.
22438 
22439     For loop without iterator_wrapper:
22440 
22441     @code{cpp}
22442     for (auto it = j_object.begin(); it != j_object.end(); ++it)
22443     {
22444         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22445     }
22446     @endcode
22447 
22448     Range-based for loop without iterator proxy:
22449 
22450     @code{cpp}
22451     for (auto it : j_object)
22452     {
22453         // "it" is of type json::reference and has no key() member
22454         std::cout << "value: " << it << '\n';
22455     }
22456     @endcode
22457 
22458     Range-based for loop with iterator proxy:
22459 
22460     @code{cpp}
22461     for (auto it : json::iterator_wrapper(j_object))
22462     {
22463         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22464     }
22465     @endcode
22466 
22467     @note When iterating over an array, `key()` will return the index of the
22468           element as string (see example).
22469 
22470     @param[in] ref  reference to a JSON value
22471     @return iteration proxy object wrapping @a ref with an interface to use in
22472             range-based for loops
22473 
22474     @liveexample{The following code shows how the wrapper is used,iterator_wrapper}
22475 
22476     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
22477     changes in the JSON value.
22478 
22479     @complexity Constant.
22480 
22481     @note The name of this function is not yet final and may change in the
22482     future.
22483 
22484     @deprecated This stream operator is deprecated and will be removed in
22485                 future 4.0.0 of the library. Please use @ref items() instead;
22486                 that is, replace `json::iterator_wrapper(j)` with `j.items()`.
22487     */
items()22488     JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22489     static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22490     {
22491         return ref.items();
22492     }
22493 
22494     /*!
22495     @copydoc iterator_wrapper(reference)
22496     */
items()22497     JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22498     static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22499     {
22500         return ref.items();
22501     }
22502 
22503     /*!
22504     @brief helper to access iterator member functions in range-based for
22505 
22506     This function allows to access @ref iterator::key() and @ref
22507     iterator::value() during range-based for loops. In these loops, a
22508     reference to the JSON values is returned, so there is no access to the
22509     underlying iterator.
22510 
22511     For loop without `items()` function:
22512 
22513     @code{cpp}
22514     for (auto it = j_object.begin(); it != j_object.end(); ++it)
22515     {
22516         std::cout << "key: " << it.key() << ", value:" << it.value() << '\n';
22517     }
22518     @endcode
22519 
22520     Range-based for loop without `items()` function:
22521 
22522     @code{cpp}
22523     for (auto it : j_object)
22524     {
22525         // "it" is of type json::reference and has no key() member
22526         std::cout << "value: " << it << '\n';
22527     }
22528     @endcode
22529 
22530     Range-based for loop with `items()` function:
22531 
22532     @code{cpp}
22533     for (auto& el : j_object.items())
22534     {
22535         std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
22536     }
22537     @endcode
22538 
22539     The `items()` function also allows to use
22540     [structured bindings](https://en.cppreference.com/w/cpp/language/structured_binding)
22541     (C++17):
22542 
22543     @code{cpp}
22544     for (auto& [key, val] : j_object.items())
22545     {
22546         std::cout << "key: " << key << ", value:" << val << '\n';
22547     }
22548     @endcode
22549 
22550     @note When iterating over an array, `key()` will return the index of the
22551           element as string (see example). For primitive types (e.g., numbers),
22552           `key()` returns an empty string.
22553 
22554     @warning Using `items()` on temporary objects is dangerous. Make sure the
22555              object's lifetime exeeds the iteration. See
22556              <https://github.com/nlohmann/json/issues/2040> for more
22557              information.
22558 
22559     @return iteration proxy object wrapping @a ref with an interface to use in
22560             range-based for loops
22561 
22562     @liveexample{The following code shows how the function is used.,items}
22563 
22564     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
22565     changes in the JSON value.
22566 
22567     @complexity Constant.
22568 
22569     @since version 3.1.0, structured bindings support since 3.5.0.
22570     */
items()22571     iteration_proxy<iterator> items() noexcept
22572     {
22573         return iteration_proxy<iterator>(*this);
22574     }
22575 
22576     /*!
22577     @copydoc items()
22578     */
items() const22579     iteration_proxy<const_iterator> items() const noexcept
22580     {
22581         return iteration_proxy<const_iterator>(*this);
22582     }
22583 
22584     /// @}
22585 
22586 
22587     //////////////
22588     // capacity //
22589     //////////////
22590 
22591     /// @name capacity
22592     /// @{
22593 
22594     /*!
22595     @brief checks whether the container is empty.
22596 
22597     Checks if a JSON value has no elements (i.e. whether its @ref size is `0`).
22598 
22599     @return The return value depends on the different types and is
22600             defined as follows:
22601             Value type  | return value
22602             ----------- | -------------
22603             null        | `true`
22604             boolean     | `false`
22605             string      | `false`
22606             number      | `false`
22607             binary      | `false`
22608             object      | result of function `object_t::empty()`
22609             array       | result of function `array_t::empty()`
22610 
22611     @liveexample{The following code uses `empty()` to check if a JSON
22612     object contains any elements.,empty}
22613 
22614     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22615     the Container concept; that is, their `empty()` functions have constant
22616     complexity.
22617 
22618     @iterators No changes.
22619 
22620     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22621 
22622     @note This function does not return whether a string stored as JSON value
22623     is empty - it returns whether the JSON container itself is empty which is
22624     false in the case of a string.
22625 
22626     @requirement This function helps `basic_json` satisfying the
22627     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22628     requirements:
22629     - The complexity is constant.
22630     - Has the semantics of `begin() == end()`.
22631 
22632     @sa see @ref size() -- returns the number of elements
22633 
22634     @since version 1.0.0
22635     */
empty() const22636     bool empty() const noexcept
22637     {
22638         switch (m_type)
22639         {
22640             case value_t::null:
22641             {
22642                 // null values are empty
22643                 return true;
22644             }
22645 
22646             case value_t::array:
22647             {
22648                 // delegate call to array_t::empty()
22649                 return m_value.array->empty();
22650             }
22651 
22652             case value_t::object:
22653             {
22654                 // delegate call to object_t::empty()
22655                 return m_value.object->empty();
22656             }
22657 
22658             case value_t::string:
22659             case value_t::boolean:
22660             case value_t::number_integer:
22661             case value_t::number_unsigned:
22662             case value_t::number_float:
22663             case value_t::binary:
22664             case value_t::discarded:
22665             default:
22666             {
22667                 // all other types are nonempty
22668                 return false;
22669             }
22670         }
22671     }
22672 
22673     /*!
22674     @brief returns the number of elements
22675 
22676     Returns the number of elements in a JSON value.
22677 
22678     @return The return value depends on the different types and is
22679             defined as follows:
22680             Value type  | return value
22681             ----------- | -------------
22682             null        | `0`
22683             boolean     | `1`
22684             string      | `1`
22685             number      | `1`
22686             binary      | `1`
22687             object      | result of function object_t::size()
22688             array       | result of function array_t::size()
22689 
22690     @liveexample{The following code calls `size()` on the different value
22691     types.,size}
22692 
22693     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22694     the Container concept; that is, their size() functions have constant
22695     complexity.
22696 
22697     @iterators No changes.
22698 
22699     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22700 
22701     @note This function does not return the length of a string stored as JSON
22702     value - it returns the number of elements in the JSON value which is 1 in
22703     the case of a string.
22704 
22705     @requirement This function helps `basic_json` satisfying the
22706     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22707     requirements:
22708     - The complexity is constant.
22709     - Has the semantics of `std::distance(begin(), end())`.
22710 
22711     @sa see @ref empty() -- checks whether the container is empty
22712     @sa see @ref max_size() -- returns the maximal number of elements
22713 
22714     @since version 1.0.0
22715     */
size() const22716     size_type size() const noexcept
22717     {
22718         switch (m_type)
22719         {
22720             case value_t::null:
22721             {
22722                 // null values are empty
22723                 return 0;
22724             }
22725 
22726             case value_t::array:
22727             {
22728                 // delegate call to array_t::size()
22729                 return m_value.array->size();
22730             }
22731 
22732             case value_t::object:
22733             {
22734                 // delegate call to object_t::size()
22735                 return m_value.object->size();
22736             }
22737 
22738             case value_t::string:
22739             case value_t::boolean:
22740             case value_t::number_integer:
22741             case value_t::number_unsigned:
22742             case value_t::number_float:
22743             case value_t::binary:
22744             case value_t::discarded:
22745             default:
22746             {
22747                 // all other types have size 1
22748                 return 1;
22749             }
22750         }
22751     }
22752 
22753     /*!
22754     @brief returns the maximum possible number of elements
22755 
22756     Returns the maximum number of elements a JSON value is able to hold due to
22757     system or library implementation limitations, i.e. `std::distance(begin(),
22758     end())` for the JSON value.
22759 
22760     @return The return value depends on the different types and is
22761             defined as follows:
22762             Value type  | return value
22763             ----------- | -------------
22764             null        | `0` (same as `size()`)
22765             boolean     | `1` (same as `size()`)
22766             string      | `1` (same as `size()`)
22767             number      | `1` (same as `size()`)
22768             binary      | `1` (same as `size()`)
22769             object      | result of function `object_t::max_size()`
22770             array       | result of function `array_t::max_size()`
22771 
22772     @liveexample{The following code calls `max_size()` on the different value
22773     types. Note the output is implementation specific.,max_size}
22774 
22775     @complexity Constant, as long as @ref array_t and @ref object_t satisfy
22776     the Container concept; that is, their `max_size()` functions have constant
22777     complexity.
22778 
22779     @iterators No changes.
22780 
22781     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22782 
22783     @requirement This function helps `basic_json` satisfying the
22784     [Container](https://en.cppreference.com/w/cpp/named_req/Container)
22785     requirements:
22786     - The complexity is constant.
22787     - Has the semantics of returning `b.size()` where `b` is the largest
22788       possible JSON value.
22789 
22790     @sa see @ref size() -- returns the number of elements
22791 
22792     @since version 1.0.0
22793     */
max_size() const22794     size_type max_size() const noexcept
22795     {
22796         switch (m_type)
22797         {
22798             case value_t::array:
22799             {
22800                 // delegate call to array_t::max_size()
22801                 return m_value.array->max_size();
22802             }
22803 
22804             case value_t::object:
22805             {
22806                 // delegate call to object_t::max_size()
22807                 return m_value.object->max_size();
22808             }
22809 
22810             case value_t::null:
22811             case value_t::string:
22812             case value_t::boolean:
22813             case value_t::number_integer:
22814             case value_t::number_unsigned:
22815             case value_t::number_float:
22816             case value_t::binary:
22817             case value_t::discarded:
22818             default:
22819             {
22820                 // all other types have max_size() == size()
22821                 return size();
22822             }
22823         }
22824     }
22825 
22826     /// @}
22827 
22828 
22829     ///////////////
22830     // modifiers //
22831     ///////////////
22832 
22833     /// @name modifiers
22834     /// @{
22835 
22836     /*!
22837     @brief clears the contents
22838 
22839     Clears the content of a JSON value and resets it to the default value as
22840     if @ref basic_json(value_t) would have been called with the current value
22841     type from @ref type():
22842 
22843     Value type  | initial value
22844     ----------- | -------------
22845     null        | `null`
22846     boolean     | `false`
22847     string      | `""`
22848     number      | `0`
22849     binary      | An empty byte vector
22850     object      | `{}`
22851     array       | `[]`
22852 
22853     @post Has the same effect as calling
22854     @code {.cpp}
22855     *this = basic_json(type());
22856     @endcode
22857 
22858     @liveexample{The example below shows the effect of `clear()` to different
22859     JSON types.,clear}
22860 
22861     @complexity Linear in the size of the JSON value.
22862 
22863     @iterators All iterators, pointers and references related to this container
22864                are invalidated.
22865 
22866     @exceptionsafety No-throw guarantee: this function never throws exceptions.
22867 
22868     @sa see @ref basic_json(value_t) -- constructor that creates an object with the
22869         same value than calling `clear()`
22870 
22871     @since version 1.0.0
22872     */
clear()22873     void clear() noexcept
22874     {
22875         switch (m_type)
22876         {
22877             case value_t::number_integer:
22878             {
22879                 m_value.number_integer = 0;
22880                 break;
22881             }
22882 
22883             case value_t::number_unsigned:
22884             {
22885                 m_value.number_unsigned = 0;
22886                 break;
22887             }
22888 
22889             case value_t::number_float:
22890             {
22891                 m_value.number_float = 0.0;
22892                 break;
22893             }
22894 
22895             case value_t::boolean:
22896             {
22897                 m_value.boolean = false;
22898                 break;
22899             }
22900 
22901             case value_t::string:
22902             {
22903                 m_value.string->clear();
22904                 break;
22905             }
22906 
22907             case value_t::binary:
22908             {
22909                 m_value.binary->clear();
22910                 break;
22911             }
22912 
22913             case value_t::array:
22914             {
22915                 m_value.array->clear();
22916                 break;
22917             }
22918 
22919             case value_t::object:
22920             {
22921                 m_value.object->clear();
22922                 break;
22923             }
22924 
22925             case value_t::null:
22926             case value_t::discarded:
22927             default:
22928                 break;
22929         }
22930     }
22931 
22932     /*!
22933     @brief add an object to an array
22934 
22935     Appends the given element @a val to the end of the JSON value. If the
22936     function is called on a JSON null value, an empty array is created before
22937     appending @a val.
22938 
22939     @param[in] val the value to add to the JSON array
22940 
22941     @throw type_error.308 when called on a type other than JSON array or
22942     null; example: `"cannot use push_back() with number"`
22943 
22944     @complexity Amortized constant.
22945 
22946     @liveexample{The example shows how `push_back()` and `+=` can be used to
22947     add elements to a JSON array. Note how the `null` value was silently
22948     converted to a JSON array.,push_back}
22949 
22950     @since version 1.0.0
22951     */
push_back(basic_json && val)22952     void push_back(basic_json&& val)
22953     {
22954         // push_back only works for null objects or arrays
22955         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22956         {
22957             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22958         }
22959 
22960         // transform null object into an array
22961         if (is_null())
22962         {
22963             m_type = value_t::array;
22964             m_value = value_t::array;
22965             assert_invariant();
22966         }
22967 
22968         // add element to array (move semantics)
22969         const auto old_capacity = m_value.array->capacity();
22970         m_value.array->push_back(std::move(val));
22971         set_parent(m_value.array->back(), old_capacity);
22972         // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
22973     }
22974 
22975     /*!
22976     @brief add an object to an array
22977     @copydoc push_back(basic_json&&)
22978     */
operator +=(basic_json && val)22979     reference operator+=(basic_json&& val)
22980     {
22981         push_back(std::move(val));
22982         return *this;
22983     }
22984 
22985     /*!
22986     @brief add an object to an array
22987     @copydoc push_back(basic_json&&)
22988     */
push_back(const basic_json & val)22989     void push_back(const basic_json& val)
22990     {
22991         // push_back only works for null objects or arrays
22992         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22993         {
22994             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22995         }
22996 
22997         // transform null object into an array
22998         if (is_null())
22999         {
23000             m_type = value_t::array;
23001             m_value = value_t::array;
23002             assert_invariant();
23003         }
23004 
23005         // add element to array
23006         const auto old_capacity = m_value.array->capacity();
23007         m_value.array->push_back(val);
23008         set_parent(m_value.array->back(), old_capacity);
23009     }
23010 
23011     /*!
23012     @brief add an object to an array
23013     @copydoc push_back(basic_json&&)
23014     */
operator +=(const basic_json & val)23015     reference operator+=(const basic_json& val)
23016     {
23017         push_back(val);
23018         return *this;
23019     }
23020 
23021     /*!
23022     @brief add an object to an object
23023 
23024     Inserts the given element @a val to the JSON object. If the function is
23025     called on a JSON null value, an empty object is created before inserting
23026     @a val.
23027 
23028     @param[in] val the value to add to the JSON object
23029 
23030     @throw type_error.308 when called on a type other than JSON object or
23031     null; example: `"cannot use push_back() with number"`
23032 
23033     @complexity Logarithmic in the size of the container, O(log(`size()`)).
23034 
23035     @liveexample{The example shows how `push_back()` and `+=` can be used to
23036     add elements to a JSON object. Note how the `null` value was silently
23037     converted to a JSON object.,push_back__object_t__value}
23038 
23039     @since version 1.0.0
23040     */
push_back(const typename object_t::value_type & val)23041     void push_back(const typename object_t::value_type& val)
23042     {
23043         // push_back only works for null objects or objects
23044         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23045         {
23046             JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
23047         }
23048 
23049         // transform null object into an object
23050         if (is_null())
23051         {
23052             m_type = value_t::object;
23053             m_value = value_t::object;
23054             assert_invariant();
23055         }
23056 
23057         // add element to object
23058         auto res = m_value.object->insert(val);
23059         set_parent(res.first->second);
23060     }
23061 
23062     /*!
23063     @brief add an object to an object
23064     @copydoc push_back(const typename object_t::value_type&)
23065     */
operator +=(const typename object_t::value_type & val)23066     reference operator+=(const typename object_t::value_type& val)
23067     {
23068         push_back(val);
23069         return *this;
23070     }
23071 
23072     /*!
23073     @brief add an object to an object
23074 
23075     This function allows to use `push_back` with an initializer list. In case
23076 
23077     1. the current value is an object,
23078     2. the initializer list @a init contains only two elements, and
23079     3. the first element of @a init is a string,
23080 
23081     @a init is converted into an object element and added using
23082     @ref push_back(const typename object_t::value_type&). Otherwise, @a init
23083     is converted to a JSON value and added using @ref push_back(basic_json&&).
23084 
23085     @param[in] init  an initializer list
23086 
23087     @complexity Linear in the size of the initializer list @a init.
23088 
23089     @note This function is required to resolve an ambiguous overload error,
23090           because pairs like `{"key", "value"}` can be both interpreted as
23091           `object_t::value_type` or `std::initializer_list<basic_json>`, see
23092           https://github.com/nlohmann/json/issues/235 for more information.
23093 
23094     @liveexample{The example shows how initializer lists are treated as
23095     objects when possible.,push_back__initializer_list}
23096     */
push_back(initializer_list_t init)23097     void push_back(initializer_list_t init)
23098     {
23099         if (is_object() && init.size() == 2 && (*init.begin())->is_string())
23100         {
23101             basic_json&& key = init.begin()->moved_or_copied();
23102             push_back(typename object_t::value_type(
23103                           std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
23104         }
23105         else
23106         {
23107             push_back(basic_json(init));
23108         }
23109     }
23110 
23111     /*!
23112     @brief add an object to an object
23113     @copydoc push_back(initializer_list_t)
23114     */
operator +=(initializer_list_t init)23115     reference operator+=(initializer_list_t init)
23116     {
23117         push_back(init);
23118         return *this;
23119     }
23120 
23121     /*!
23122     @brief add an object to an array
23123 
23124     Creates a JSON value from the passed parameters @a args to the end of the
23125     JSON value. If the function is called on a JSON null value, an empty array
23126     is created before appending the value created from @a args.
23127 
23128     @param[in] args arguments to forward to a constructor of @ref basic_json
23129     @tparam Args compatible types to create a @ref basic_json object
23130 
23131     @return reference to the inserted element
23132 
23133     @throw type_error.311 when called on a type other than JSON array or
23134     null; example: `"cannot use emplace_back() with number"`
23135 
23136     @complexity Amortized constant.
23137 
23138     @liveexample{The example shows how `push_back()` can be used to add
23139     elements to a JSON array. Note how the `null` value was silently converted
23140     to a JSON array.,emplace_back}
23141 
23142     @since version 2.0.8, returns reference since 3.7.0
23143     */
23144     template<class... Args>
emplace_back(Args &&...args)23145     reference emplace_back(Args&& ... args)
23146     {
23147         // emplace_back only works for null objects or arrays
23148         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23149         {
23150             JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
23151         }
23152 
23153         // transform null object into an array
23154         if (is_null())
23155         {
23156             m_type = value_t::array;
23157             m_value = value_t::array;
23158             assert_invariant();
23159         }
23160 
23161         // add element to array (perfect forwarding)
23162         const auto old_capacity = m_value.array->capacity();
23163         m_value.array->emplace_back(std::forward<Args>(args)...);
23164         return set_parent(m_value.array->back(), old_capacity);
23165     }
23166 
23167     /*!
23168     @brief add an object to an object if key does not exist
23169 
23170     Inserts a new element into a JSON object constructed in-place with the
23171     given @a args if there is no element with the key in the container. If the
23172     function is called on a JSON null value, an empty object is created before
23173     appending the value created from @a args.
23174 
23175     @param[in] args arguments to forward to a constructor of @ref basic_json
23176     @tparam Args compatible types to create a @ref basic_json object
23177 
23178     @return a pair consisting of an iterator to the inserted element, or the
23179             already-existing element if no insertion happened, and a bool
23180             denoting whether the insertion took place.
23181 
23182     @throw type_error.311 when called on a type other than JSON object or
23183     null; example: `"cannot use emplace() with number"`
23184 
23185     @complexity Logarithmic in the size of the container, O(log(`size()`)).
23186 
23187     @liveexample{The example shows how `emplace()` can be used to add elements
23188     to a JSON object. Note how the `null` value was silently converted to a
23189     JSON object. Further note how no value is added if there was already one
23190     value stored with the same key.,emplace}
23191 
23192     @since version 2.0.8
23193     */
23194     template<class... Args>
emplace(Args &&...args)23195     std::pair<iterator, bool> emplace(Args&& ... args)
23196     {
23197         // emplace only works for null objects or arrays
23198         if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23199         {
23200             JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
23201         }
23202 
23203         // transform null object into an object
23204         if (is_null())
23205         {
23206             m_type = value_t::object;
23207             m_value = value_t::object;
23208             assert_invariant();
23209         }
23210 
23211         // add element to array (perfect forwarding)
23212         auto res = m_value.object->emplace(std::forward<Args>(args)...);
23213         set_parent(res.first->second);
23214 
23215         // create result iterator and set iterator to the result of emplace
23216         auto it = begin();
23217         it.m_it.object_iterator = res.first;
23218 
23219         // return pair of iterator and boolean
23220         return {it, res.second};
23221     }
23222 
23223     /// Helper for insertion of an iterator
23224     /// @note: This uses std::distance to support GCC 4.8,
23225     ///        see https://github.com/nlohmann/json/pull/1257
23226     template<typename... Args>
insert_iterator(const_iterator pos,Args &&...args)23227     iterator insert_iterator(const_iterator pos, Args&& ... args)
23228     {
23229         iterator result(this);
23230         JSON_ASSERT(m_value.array != nullptr);
23231 
23232         auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
23233         m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
23234         result.m_it.array_iterator = m_value.array->begin() + insert_pos;
23235 
23236         // This could have been written as:
23237         // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
23238         // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
23239 
23240         set_parents();
23241         return result;
23242     }
23243 
23244     /*!
23245     @brief inserts element
23246 
23247     Inserts element @a val before iterator @a pos.
23248 
23249     @param[in] pos iterator before which the content will be inserted; may be
23250     the end() iterator
23251     @param[in] val element to insert
23252     @return iterator pointing to the inserted @a val.
23253 
23254     @throw type_error.309 if called on JSON values other than arrays;
23255     example: `"cannot use insert() with string"`
23256     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23257     example: `"iterator does not fit current value"`
23258 
23259     @complexity Constant plus linear in the distance between @a pos and end of
23260     the container.
23261 
23262     @liveexample{The example shows how `insert()` is used.,insert}
23263 
23264     @since version 1.0.0
23265     */
insert(const_iterator pos,const basic_json & val)23266     iterator insert(const_iterator pos, const basic_json& val)
23267     {
23268         // insert only works for arrays
23269         if (JSON_HEDLEY_LIKELY(is_array()))
23270         {
23271             // check if iterator pos fits to this JSON value
23272             if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23273             {
23274                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23275             }
23276 
23277             // insert to array and return iterator
23278             return insert_iterator(pos, val);
23279         }
23280 
23281         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23282     }
23283 
23284     /*!
23285     @brief inserts element
23286     @copydoc insert(const_iterator, const basic_json&)
23287     */
insert(const_iterator pos,basic_json && val)23288     iterator insert(const_iterator pos, basic_json&& val)
23289     {
23290         return insert(pos, val);
23291     }
23292 
23293     /*!
23294     @brief inserts elements
23295 
23296     Inserts @a cnt copies of @a val before iterator @a pos.
23297 
23298     @param[in] pos iterator before which the content will be inserted; may be
23299     the end() iterator
23300     @param[in] cnt number of copies of @a val to insert
23301     @param[in] val element to insert
23302     @return iterator pointing to the first element inserted, or @a pos if
23303     `cnt==0`
23304 
23305     @throw type_error.309 if called on JSON values other than arrays; example:
23306     `"cannot use insert() with string"`
23307     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23308     example: `"iterator does not fit current value"`
23309 
23310     @complexity Linear in @a cnt plus linear in the distance between @a pos
23311     and end of the container.
23312 
23313     @liveexample{The example shows how `insert()` is used.,insert__count}
23314 
23315     @since version 1.0.0
23316     */
insert(const_iterator pos,size_type cnt,const basic_json & val)23317     iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
23318     {
23319         // insert only works for arrays
23320         if (JSON_HEDLEY_LIKELY(is_array()))
23321         {
23322             // check if iterator pos fits to this JSON value
23323             if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23324             {
23325                 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23326             }
23327 
23328             // insert to array and return iterator
23329             return insert_iterator(pos, cnt, val);
23330         }
23331 
23332         JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23333     }
23334 
23335     /*!
23336     @brief inserts elements
23337 
23338     Inserts elements from range `[first, last)` before iterator @a pos.
23339 
23340     @param[in] pos iterator before which the content will be inserted; may be
23341     the end() iterator
23342     @param[in] first begin of the range of elements to insert
23343     @param[in] last end of the range of elements to insert
23344 
23345     @throw type_error.309 if called on JSON values other than arrays; example:
23346     `"cannot use insert() with string"`
23347     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23348     example: `"iterator does not fit current value"`
23349     @throw invalid_iterator.210 if @a first and @a last do not belong to the
23350     same JSON value; example: `"iterators do not fit"`
23351     @throw invalid_iterator.211 if @a first or @a last are iterators into
23352     container for which insert is called; example: `"passed iterators may not
23353     belong to container"`
23354 
23355     @return iterator pointing to the first element inserted, or @a pos if
23356     `first==last`
23357 
23358     @complexity Linear in `std::distance(first, last)` plus linear in the
23359     distance between @a pos and end of the container.
23360 
23361     @liveexample{The example shows how `insert()` is used.,insert__range}
23362 
23363     @since version 1.0.0
23364     */
insert(const_iterator pos,const_iterator first,const_iterator last)23365     iterator insert(const_iterator pos, const_iterator first, const_iterator last)
23366     {
23367         // insert only works for arrays
23368         if (JSON_HEDLEY_UNLIKELY(!is_array()))
23369         {
23370             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23371         }
23372 
23373         // check if iterator pos fits to this JSON value
23374         if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23375         {
23376             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23377         }
23378 
23379         // check if range iterators belong to the same JSON object
23380         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23381         {
23382             JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23383         }
23384 
23385         if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
23386         {
23387             JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
23388         }
23389 
23390         // insert to array and return iterator
23391         return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
23392     }
23393 
23394     /*!
23395     @brief inserts elements
23396 
23397     Inserts elements from initializer list @a ilist before iterator @a pos.
23398 
23399     @param[in] pos iterator before which the content will be inserted; may be
23400     the end() iterator
23401     @param[in] ilist initializer list to insert the values from
23402 
23403     @throw type_error.309 if called on JSON values other than arrays; example:
23404     `"cannot use insert() with string"`
23405     @throw invalid_iterator.202 if @a pos is not an iterator of *this;
23406     example: `"iterator does not fit current value"`
23407 
23408     @return iterator pointing to the first element inserted, or @a pos if
23409     `ilist` is empty
23410 
23411     @complexity Linear in `ilist.size()` plus linear in the distance between
23412     @a pos and end of the container.
23413 
23414     @liveexample{The example shows how `insert()` is used.,insert__ilist}
23415 
23416     @since version 1.0.0
23417     */
insert(const_iterator pos,initializer_list_t ilist)23418     iterator insert(const_iterator pos, initializer_list_t ilist)
23419     {
23420         // insert only works for arrays
23421         if (JSON_HEDLEY_UNLIKELY(!is_array()))
23422         {
23423             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23424         }
23425 
23426         // check if iterator pos fits to this JSON value
23427         if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23428         {
23429             JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23430         }
23431 
23432         // insert to array and return iterator
23433         return insert_iterator(pos, ilist.begin(), ilist.end());
23434     }
23435 
23436     /*!
23437     @brief inserts elements
23438 
23439     Inserts elements from range `[first, last)`.
23440 
23441     @param[in] first begin of the range of elements to insert
23442     @param[in] last end of the range of elements to insert
23443 
23444     @throw type_error.309 if called on JSON values other than objects; example:
23445     `"cannot use insert() with string"`
23446     @throw invalid_iterator.202 if iterator @a first or @a last does does not
23447     point to an object; example: `"iterators first and last must point to
23448     objects"`
23449     @throw invalid_iterator.210 if @a first and @a last do not belong to the
23450     same JSON value; example: `"iterators do not fit"`
23451 
23452     @complexity Logarithmic: `O(N*log(size() + N))`, where `N` is the number
23453     of elements to insert.
23454 
23455     @liveexample{The example shows how `insert()` is used.,insert__range_object}
23456 
23457     @since version 3.0.0
23458     */
insert(const_iterator first,const_iterator last)23459     void insert(const_iterator first, const_iterator last)
23460     {
23461         // insert only works for objects
23462         if (JSON_HEDLEY_UNLIKELY(!is_object()))
23463         {
23464             JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23465         }
23466 
23467         // check if range iterators belong to the same JSON object
23468         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23469         {
23470             JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23471         }
23472 
23473         // passed iterators must belong to objects
23474         if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23475         {
23476             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23477         }
23478 
23479         m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
23480     }
23481 
23482     /*!
23483     @brief updates a JSON object from another object, overwriting existing keys
23484 
23485     Inserts all values from JSON object @a j and overwrites existing keys.
23486 
23487     @param[in] j  JSON object to read values from
23488 
23489     @throw type_error.312 if called on JSON values other than objects; example:
23490     `"cannot use update() with string"`
23491 
23492     @complexity O(N*log(size() + N)), where N is the number of elements to
23493                 insert.
23494 
23495     @liveexample{The example shows how `update()` is used.,update}
23496 
23497     @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
23498 
23499     @since version 3.0.0
23500     */
update(const_reference j)23501     void update(const_reference j)
23502     {
23503         // implicitly convert null value to an empty object
23504         if (is_null())
23505         {
23506             m_type = value_t::object;
23507             m_value.object = create<object_t>();
23508             assert_invariant();
23509         }
23510 
23511         if (JSON_HEDLEY_UNLIKELY(!is_object()))
23512         {
23513             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23514         }
23515         if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
23516         {
23517             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
23518         }
23519 
23520         for (auto it = j.cbegin(); it != j.cend(); ++it)
23521         {
23522             m_value.object->operator[](it.key()) = it.value();
23523 #if JSON_DIAGNOSTICS
23524             m_value.object->operator[](it.key()).m_parent = this;
23525 #endif
23526         }
23527     }
23528 
23529     /*!
23530     @brief updates a JSON object from another object, overwriting existing keys
23531 
23532     Inserts all values from from range `[first, last)` and overwrites existing
23533     keys.
23534 
23535     @param[in] first begin of the range of elements to insert
23536     @param[in] last end of the range of elements to insert
23537 
23538     @throw type_error.312 if called on JSON values other than objects; example:
23539     `"cannot use update() with string"`
23540     @throw invalid_iterator.202 if iterator @a first or @a last does does not
23541     point to an object; example: `"iterators first and last must point to
23542     objects"`
23543     @throw invalid_iterator.210 if @a first and @a last do not belong to the
23544     same JSON value; example: `"iterators do not fit"`
23545 
23546     @complexity O(N*log(size() + N)), where N is the number of elements to
23547                 insert.
23548 
23549     @liveexample{The example shows how `update()` is used__range.,update}
23550 
23551     @sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
23552 
23553     @since version 3.0.0
23554     */
update(const_iterator first,const_iterator last)23555     void update(const_iterator first, const_iterator last)
23556     {
23557         // implicitly convert null value to an empty object
23558         if (is_null())
23559         {
23560             m_type = value_t::object;
23561             m_value.object = create<object_t>();
23562             assert_invariant();
23563         }
23564 
23565         if (JSON_HEDLEY_UNLIKELY(!is_object()))
23566         {
23567             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23568         }
23569 
23570         // check if range iterators belong to the same JSON object
23571         if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23572         {
23573             JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23574         }
23575 
23576         // passed iterators must belong to objects
23577         if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
23578                                  || !last.m_object->is_object()))
23579         {
23580             JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23581         }
23582 
23583         for (auto it = first; it != last; ++it)
23584         {
23585             m_value.object->operator[](it.key()) = it.value();
23586 #if JSON_DIAGNOSTICS
23587             m_value.object->operator[](it.key()).m_parent = this;
23588 #endif
23589         }
23590     }
23591 
23592     /*!
23593     @brief exchanges the values
23594 
23595     Exchanges the contents of the JSON value with those of @a other. Does not
23596     invoke any move, copy, or swap operations on individual elements. All
23597     iterators and references remain valid. The past-the-end iterator is
23598     invalidated.
23599 
23600     @param[in,out] other JSON value to exchange the contents with
23601 
23602     @complexity Constant.
23603 
23604     @liveexample{The example below shows how JSON values can be swapped with
23605     `swap()`.,swap__reference}
23606 
23607     @since version 1.0.0
23608     */
swap(reference other)23609     void swap(reference other) noexcept (
23610         std::is_nothrow_move_constructible<value_t>::value&&
23611         std::is_nothrow_move_assignable<value_t>::value&&
23612         std::is_nothrow_move_constructible<json_value>::value&&
23613         std::is_nothrow_move_assignable<json_value>::value
23614     )
23615     {
23616         std::swap(m_type, other.m_type);
23617         std::swap(m_value, other.m_value);
23618 
23619         set_parents();
23620         other.set_parents();
23621         assert_invariant();
23622     }
23623 
23624     /*!
23625     @brief exchanges the values
23626 
23627     Exchanges the contents of the JSON value from @a left with those of @a right. Does not
23628     invoke any move, copy, or swap operations on individual elements. All
23629     iterators and references remain valid. The past-the-end iterator is
23630     invalidated. implemented as a friend function callable via ADL.
23631 
23632     @param[in,out] left JSON value to exchange the contents with
23633     @param[in,out] right JSON value to exchange the contents with
23634 
23635     @complexity Constant.
23636 
23637     @liveexample{The example below shows how JSON values can be swapped with
23638     `swap()`.,swap__reference}
23639 
23640     @since version 1.0.0
23641     */
swap(reference left,reference right)23642     friend void swap(reference left, reference right) noexcept (
23643         std::is_nothrow_move_constructible<value_t>::value&&
23644         std::is_nothrow_move_assignable<value_t>::value&&
23645         std::is_nothrow_move_constructible<json_value>::value&&
23646         std::is_nothrow_move_assignable<json_value>::value
23647     )
23648     {
23649         left.swap(right);
23650     }
23651 
23652     /*!
23653     @brief exchanges the values
23654 
23655     Exchanges the contents of a JSON array with those of @a other. Does not
23656     invoke any move, copy, or swap operations on individual elements. All
23657     iterators and references remain valid. The past-the-end iterator is
23658     invalidated.
23659 
23660     @param[in,out] other array to exchange the contents with
23661 
23662     @throw type_error.310 when JSON value is not an array; example: `"cannot
23663     use swap() with string"`
23664 
23665     @complexity Constant.
23666 
23667     @liveexample{The example below shows how arrays can be swapped with
23668     `swap()`.,swap__array_t}
23669 
23670     @since version 1.0.0
23671     */
swap(array_t & other)23672     void swap(array_t& other) // NOLINT(bugprone-exception-escape)
23673     {
23674         // swap only works for arrays
23675         if (JSON_HEDLEY_LIKELY(is_array()))
23676         {
23677             std::swap(*(m_value.array), other);
23678         }
23679         else
23680         {
23681             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23682         }
23683     }
23684 
23685     /*!
23686     @brief exchanges the values
23687 
23688     Exchanges the contents of a JSON object with those of @a other. Does not
23689     invoke any move, copy, or swap operations on individual elements. All
23690     iterators and references remain valid. The past-the-end iterator is
23691     invalidated.
23692 
23693     @param[in,out] other object to exchange the contents with
23694 
23695     @throw type_error.310 when JSON value is not an object; example:
23696     `"cannot use swap() with string"`
23697 
23698     @complexity Constant.
23699 
23700     @liveexample{The example below shows how objects can be swapped with
23701     `swap()`.,swap__object_t}
23702 
23703     @since version 1.0.0
23704     */
swap(object_t & other)23705     void swap(object_t& other) // NOLINT(bugprone-exception-escape)
23706     {
23707         // swap only works for objects
23708         if (JSON_HEDLEY_LIKELY(is_object()))
23709         {
23710             std::swap(*(m_value.object), other);
23711         }
23712         else
23713         {
23714             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23715         }
23716     }
23717 
23718     /*!
23719     @brief exchanges the values
23720 
23721     Exchanges the contents of a JSON string with those of @a other. Does not
23722     invoke any move, copy, or swap operations on individual elements. All
23723     iterators and references remain valid. The past-the-end iterator is
23724     invalidated.
23725 
23726     @param[in,out] other string to exchange the contents with
23727 
23728     @throw type_error.310 when JSON value is not a string; example: `"cannot
23729     use swap() with boolean"`
23730 
23731     @complexity Constant.
23732 
23733     @liveexample{The example below shows how strings can be swapped with
23734     `swap()`.,swap__string_t}
23735 
23736     @since version 1.0.0
23737     */
swap(string_t & other)23738     void swap(string_t& other) // NOLINT(bugprone-exception-escape)
23739     {
23740         // swap only works for strings
23741         if (JSON_HEDLEY_LIKELY(is_string()))
23742         {
23743             std::swap(*(m_value.string), other);
23744         }
23745         else
23746         {
23747             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23748         }
23749     }
23750 
23751     /*!
23752     @brief exchanges the values
23753 
23754     Exchanges the contents of a JSON string with those of @a other. Does not
23755     invoke any move, copy, or swap operations on individual elements. All
23756     iterators and references remain valid. The past-the-end iterator is
23757     invalidated.
23758 
23759     @param[in,out] other binary to exchange the contents with
23760 
23761     @throw type_error.310 when JSON value is not a string; example: `"cannot
23762     use swap() with boolean"`
23763 
23764     @complexity Constant.
23765 
23766     @liveexample{The example below shows how strings can be swapped with
23767     `swap()`.,swap__binary_t}
23768 
23769     @since version 3.8.0
23770     */
swap(binary_t & other)23771     void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
23772     {
23773         // swap only works for strings
23774         if (JSON_HEDLEY_LIKELY(is_binary()))
23775         {
23776             std::swap(*(m_value.binary), other);
23777         }
23778         else
23779         {
23780             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23781         }
23782     }
23783 
23784     /// @copydoc swap(binary_t&)
swap(typename binary_t::container_type & other)23785     void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
23786     {
23787         // swap only works for strings
23788         if (JSON_HEDLEY_LIKELY(is_binary()))
23789         {
23790             std::swap(*(m_value.binary), other);
23791         }
23792         else
23793         {
23794             JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23795         }
23796     }
23797 
23798     /// @}
23799 
23800   public:
23801     //////////////////////////////////////////
23802     // lexicographical comparison operators //
23803     //////////////////////////////////////////
23804 
23805     /// @name lexicographical comparison operators
23806     /// @{
23807 
23808     /*!
23809     @brief comparison: equal
23810 
23811     Compares two JSON values for equality according to the following rules:
23812     - Two JSON values are equal if (1) they are from the same type and (2)
23813       their stored values are the same according to their respective
23814       `operator==`.
23815     - Integer and floating-point numbers are automatically converted before
23816       comparison. Note that two NaN values are always treated as unequal.
23817     - Two JSON null values are equal.
23818 
23819     @note Floating-point inside JSON values numbers are compared with
23820     `json::number_float_t::operator==` which is `double::operator==` by
23821     default. To compare floating-point while respecting an epsilon, an alternative
23822     [comparison function](https://github.com/mariokonrad/marnav/blob/master/include/marnav/math/floatingpoint.hpp#L34-#L39)
23823     could be used, for instance
23824     @code {.cpp}
23825     template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, T>::type>
23826     inline bool is_same(T a, T b, T epsilon = std::numeric_limits<T>::epsilon()) noexcept
23827     {
23828         return std::abs(a - b) <= epsilon;
23829     }
23830     @endcode
23831     Or you can self-defined operator equal function like this:
23832     @code {.cpp}
23833     bool my_equal(const_reference lhs, const_reference rhs) {
23834     const auto lhs_type lhs.type();
23835     const auto rhs_type rhs.type();
23836     if (lhs_type == rhs_type) {
23837         switch(lhs_type)
23838             // self_defined case
23839             case value_t::number_float:
23840                 return std::abs(lhs - rhs) <= std::numeric_limits<float>::epsilon();
23841             // other cases remain the same with the original
23842             ...
23843     }
23844     ...
23845     }
23846     @endcode
23847 
23848     @note NaN values never compare equal to themselves or to other NaN values.
23849 
23850     @param[in] lhs  first JSON value to consider
23851     @param[in] rhs  second JSON value to consider
23852     @return whether the values @a lhs and @a rhs are equal
23853 
23854     @exceptionsafety No-throw guarantee: this function never throws exceptions.
23855 
23856     @complexity Linear.
23857 
23858     @liveexample{The example demonstrates comparing several JSON
23859     types.,operator__equal}
23860 
23861     @since version 1.0.0
23862     */
operator ==(const_reference lhs,const_reference rhs)23863     friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23864     {
23865 #ifdef __GNUC__
23866 #pragma GCC diagnostic push
23867 #pragma GCC diagnostic ignored "-Wfloat-equal"
23868 #endif
23869         const auto lhs_type = lhs.type();
23870         const auto rhs_type = rhs.type();
23871 
23872         if (lhs_type == rhs_type)
23873         {
23874             switch (lhs_type)
23875             {
23876                 case value_t::array:
23877                     return *lhs.m_value.array == *rhs.m_value.array;
23878 
23879                 case value_t::object:
23880                     return *lhs.m_value.object == *rhs.m_value.object;
23881 
23882                 case value_t::null:
23883                     return true;
23884 
23885                 case value_t::string:
23886                     return *lhs.m_value.string == *rhs.m_value.string;
23887 
23888                 case value_t::boolean:
23889                     return lhs.m_value.boolean == rhs.m_value.boolean;
23890 
23891                 case value_t::number_integer:
23892                     return lhs.m_value.number_integer == rhs.m_value.number_integer;
23893 
23894                 case value_t::number_unsigned:
23895                     return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
23896 
23897                 case value_t::number_float:
23898                     return lhs.m_value.number_float == rhs.m_value.number_float;
23899 
23900                 case value_t::binary:
23901                     return *lhs.m_value.binary == *rhs.m_value.binary;
23902 
23903                 case value_t::discarded:
23904                 default:
23905                     return false;
23906             }
23907         }
23908         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23909         {
23910             return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
23911         }
23912         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23913         {
23914             return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
23915         }
23916         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23917         {
23918             return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
23919         }
23920         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23921         {
23922             return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
23923         }
23924         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23925         {
23926             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
23927         }
23928         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23929         {
23930             return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23931         }
23932 
23933         return false;
23934 #ifdef __GNUC__
23935 #pragma GCC diagnostic pop
23936 #endif
23937     }
23938 
23939     /*!
23940     @brief comparison: equal
23941     @copydoc operator==(const_reference, const_reference)
23942     */
23943     template<typename ScalarType, typename std::enable_if<
23944                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(const_reference lhs,ScalarType rhs)23945     friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23946     {
23947         return lhs == basic_json(rhs);
23948     }
23949 
23950     /*!
23951     @brief comparison: equal
23952     @copydoc operator==(const_reference, const_reference)
23953     */
23954     template<typename ScalarType, typename std::enable_if<
23955                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator ==(ScalarType lhs,const_reference rhs)23956     friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23957     {
23958         return basic_json(lhs) == rhs;
23959     }
23960 
23961     /*!
23962     @brief comparison: not equal
23963 
23964     Compares two JSON values for inequality by calculating `not (lhs == rhs)`.
23965 
23966     @param[in] lhs  first JSON value to consider
23967     @param[in] rhs  second JSON value to consider
23968     @return whether the values @a lhs and @a rhs are not equal
23969 
23970     @complexity Linear.
23971 
23972     @exceptionsafety No-throw guarantee: this function never throws exceptions.
23973 
23974     @liveexample{The example demonstrates comparing several JSON
23975     types.,operator__notequal}
23976 
23977     @since version 1.0.0
23978     */
operator !=(const_reference lhs,const_reference rhs)23979     friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23980     {
23981         return !(lhs == rhs);
23982     }
23983 
23984     /*!
23985     @brief comparison: not equal
23986     @copydoc operator!=(const_reference, const_reference)
23987     */
23988     template<typename ScalarType, typename std::enable_if<
23989                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(const_reference lhs,ScalarType rhs)23990     friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23991     {
23992         return lhs != basic_json(rhs);
23993     }
23994 
23995     /*!
23996     @brief comparison: not equal
23997     @copydoc operator!=(const_reference, const_reference)
23998     */
23999     template<typename ScalarType, typename std::enable_if<
24000                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator !=(ScalarType lhs,const_reference rhs)24001     friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
24002     {
24003         return basic_json(lhs) != rhs;
24004     }
24005 
24006     /*!
24007     @brief comparison: less than
24008 
24009     Compares whether one JSON value @a lhs is less than another JSON value @a
24010     rhs according to the following rules:
24011     - If @a lhs and @a rhs have the same type, the values are compared using
24012       the default `<` operator.
24013     - Integer and floating-point numbers are automatically converted before
24014       comparison
24015     - In case @a lhs and @a rhs have different types, the values are ignored
24016       and the order of the types is considered, see
24017       @ref operator<(const value_t, const value_t).
24018 
24019     @param[in] lhs  first JSON value to consider
24020     @param[in] rhs  second JSON value to consider
24021     @return whether @a lhs is less than @a rhs
24022 
24023     @complexity Linear.
24024 
24025     @exceptionsafety No-throw guarantee: this function never throws exceptions.
24026 
24027     @liveexample{The example demonstrates comparing several JSON
24028     types.,operator__less}
24029 
24030     @since version 1.0.0
24031     */
operator <(const_reference lhs,const_reference rhs)24032     friend bool operator<(const_reference lhs, const_reference rhs) noexcept
24033     {
24034         const auto lhs_type = lhs.type();
24035         const auto rhs_type = rhs.type();
24036 
24037         if (lhs_type == rhs_type)
24038         {
24039             switch (lhs_type)
24040             {
24041                 case value_t::array:
24042                     // note parentheses are necessary, see
24043                     // https://github.com/nlohmann/json/issues/1530
24044                     return (*lhs.m_value.array) < (*rhs.m_value.array);
24045 
24046                 case value_t::object:
24047                     return (*lhs.m_value.object) < (*rhs.m_value.object);
24048 
24049                 case value_t::null:
24050                     return false;
24051 
24052                 case value_t::string:
24053                     return (*lhs.m_value.string) < (*rhs.m_value.string);
24054 
24055                 case value_t::boolean:
24056                     return (lhs.m_value.boolean) < (rhs.m_value.boolean);
24057 
24058                 case value_t::number_integer:
24059                     return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
24060 
24061                 case value_t::number_unsigned:
24062                     return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
24063 
24064                 case value_t::number_float:
24065                     return (lhs.m_value.number_float) < (rhs.m_value.number_float);
24066 
24067                 case value_t::binary:
24068                     return (*lhs.m_value.binary) < (*rhs.m_value.binary);
24069 
24070                 case value_t::discarded:
24071                 default:
24072                     return false;
24073             }
24074         }
24075         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
24076         {
24077             return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
24078         }
24079         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
24080         {
24081             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
24082         }
24083         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
24084         {
24085             return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
24086         }
24087         else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
24088         {
24089             return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
24090         }
24091         else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
24092         {
24093             return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
24094         }
24095         else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
24096         {
24097             return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
24098         }
24099 
24100         // We only reach this line if we cannot compare values. In that case,
24101         // we compare types. Note we have to call the operator explicitly,
24102         // because MSVC has problems otherwise.
24103         return operator<(lhs_type, rhs_type);
24104     }
24105 
24106     /*!
24107     @brief comparison: less than
24108     @copydoc operator<(const_reference, const_reference)
24109     */
24110     template<typename ScalarType, typename std::enable_if<
24111                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(const_reference lhs,ScalarType rhs)24112     friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
24113     {
24114         return lhs < basic_json(rhs);
24115     }
24116 
24117     /*!
24118     @brief comparison: less than
24119     @copydoc operator<(const_reference, const_reference)
24120     */
24121     template<typename ScalarType, typename std::enable_if<
24122                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <(ScalarType lhs,const_reference rhs)24123     friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
24124     {
24125         return basic_json(lhs) < rhs;
24126     }
24127 
24128     /*!
24129     @brief comparison: less than or equal
24130 
24131     Compares whether one JSON value @a lhs is less than or equal to another
24132     JSON value by calculating `not (rhs < lhs)`.
24133 
24134     @param[in] lhs  first JSON value to consider
24135     @param[in] rhs  second JSON value to consider
24136     @return whether @a lhs is less than or equal to @a rhs
24137 
24138     @complexity Linear.
24139 
24140     @exceptionsafety No-throw guarantee: this function never throws exceptions.
24141 
24142     @liveexample{The example demonstrates comparing several JSON
24143     types.,operator__greater}
24144 
24145     @since version 1.0.0
24146     */
operator <=(const_reference lhs,const_reference rhs)24147     friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
24148     {
24149         return !(rhs < lhs);
24150     }
24151 
24152     /*!
24153     @brief comparison: less than or equal
24154     @copydoc operator<=(const_reference, const_reference)
24155     */
24156     template<typename ScalarType, typename std::enable_if<
24157                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(const_reference lhs,ScalarType rhs)24158     friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
24159     {
24160         return lhs <= basic_json(rhs);
24161     }
24162 
24163     /*!
24164     @brief comparison: less than or equal
24165     @copydoc operator<=(const_reference, const_reference)
24166     */
24167     template<typename ScalarType, typename std::enable_if<
24168                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator <=(ScalarType lhs,const_reference rhs)24169     friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
24170     {
24171         return basic_json(lhs) <= rhs;
24172     }
24173 
24174     /*!
24175     @brief comparison: greater than
24176 
24177     Compares whether one JSON value @a lhs is greater than another
24178     JSON value by calculating `not (lhs <= rhs)`.
24179 
24180     @param[in] lhs  first JSON value to consider
24181     @param[in] rhs  second JSON value to consider
24182     @return whether @a lhs is greater than to @a rhs
24183 
24184     @complexity Linear.
24185 
24186     @exceptionsafety No-throw guarantee: this function never throws exceptions.
24187 
24188     @liveexample{The example demonstrates comparing several JSON
24189     types.,operator__lessequal}
24190 
24191     @since version 1.0.0
24192     */
operator >(const_reference lhs,const_reference rhs)24193     friend bool operator>(const_reference lhs, const_reference rhs) noexcept
24194     {
24195         return !(lhs <= rhs);
24196     }
24197 
24198     /*!
24199     @brief comparison: greater than
24200     @copydoc operator>(const_reference, const_reference)
24201     */
24202     template<typename ScalarType, typename std::enable_if<
24203                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(const_reference lhs,ScalarType rhs)24204     friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
24205     {
24206         return lhs > basic_json(rhs);
24207     }
24208 
24209     /*!
24210     @brief comparison: greater than
24211     @copydoc operator>(const_reference, const_reference)
24212     */
24213     template<typename ScalarType, typename std::enable_if<
24214                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >(ScalarType lhs,const_reference rhs)24215     friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
24216     {
24217         return basic_json(lhs) > rhs;
24218     }
24219 
24220     /*!
24221     @brief comparison: greater than or equal
24222 
24223     Compares whether one JSON value @a lhs is greater than or equal to another
24224     JSON value by calculating `not (lhs < rhs)`.
24225 
24226     @param[in] lhs  first JSON value to consider
24227     @param[in] rhs  second JSON value to consider
24228     @return whether @a lhs is greater than or equal to @a rhs
24229 
24230     @complexity Linear.
24231 
24232     @exceptionsafety No-throw guarantee: this function never throws exceptions.
24233 
24234     @liveexample{The example demonstrates comparing several JSON
24235     types.,operator__greaterequal}
24236 
24237     @since version 1.0.0
24238     */
operator >=(const_reference lhs,const_reference rhs)24239     friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
24240     {
24241         return !(lhs < rhs);
24242     }
24243 
24244     /*!
24245     @brief comparison: greater than or equal
24246     @copydoc operator>=(const_reference, const_reference)
24247     */
24248     template<typename ScalarType, typename std::enable_if<
24249                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(const_reference lhs,ScalarType rhs)24250     friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
24251     {
24252         return lhs >= basic_json(rhs);
24253     }
24254 
24255     /*!
24256     @brief comparison: greater than or equal
24257     @copydoc operator>=(const_reference, const_reference)
24258     */
24259     template<typename ScalarType, typename std::enable_if<
24260                  std::is_scalar<ScalarType>::value, int>::type = 0>
operator >=(ScalarType lhs,const_reference rhs)24261     friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
24262     {
24263         return basic_json(lhs) >= rhs;
24264     }
24265 
24266     /// @}
24267 
24268     ///////////////////
24269     // serialization //
24270     ///////////////////
24271 
24272     /// @name serialization
24273     /// @{
24274 #ifndef JSON_NO_IO
24275     /*!
24276     @brief serialize to stream
24277 
24278     Serialize the given JSON value @a j to the output stream @a o. The JSON
24279     value will be serialized using the @ref dump member function.
24280 
24281     - The indentation of the output can be controlled with the member variable
24282       `width` of the output stream @a o. For instance, using the manipulator
24283       `std::setw(4)` on @a o sets the indentation level to `4` and the
24284       serialization result is the same as calling `dump(4)`.
24285 
24286     - The indentation character can be controlled with the member variable
24287       `fill` of the output stream @a o. For instance, the manipulator
24288       `std::setfill('\\t')` sets indentation to use a tab character rather than
24289       the default space character.
24290 
24291     @param[in,out] o  stream to serialize to
24292     @param[in] j  JSON value to serialize
24293 
24294     @return the stream @a o
24295 
24296     @throw type_error.316 if a string stored inside the JSON value is not
24297                           UTF-8 encoded
24298 
24299     @complexity Linear.
24300 
24301     @liveexample{The example below shows the serialization with different
24302     parameters to `width` to adjust the indentation level.,operator_serialize}
24303 
24304     @since version 1.0.0; indentation character added in version 3.0.0
24305     */
operator <<(std::ostream & o,const basic_json & j)24306     friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
24307     {
24308         // read width member and use it as indentation parameter if nonzero
24309         const bool pretty_print = o.width() > 0;
24310         const auto indentation = pretty_print ? o.width() : 0;
24311 
24312         // reset width to 0 for subsequent calls to this stream
24313         o.width(0);
24314 
24315         // do the actual serialization
24316         serializer s(detail::output_adapter<char>(o), o.fill());
24317         s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
24318         return o;
24319     }
24320 
24321     /*!
24322     @brief serialize to stream
24323     @deprecated This stream operator is deprecated and will be removed in
24324                 future 4.0.0 of the library. Please use
24325                 @ref operator<<(std::ostream&, const basic_json&)
24326                 instead; that is, replace calls like `j >> o;` with `o << j;`.
24327     @since version 1.0.0; deprecated since version 3.0.0
24328     */
24329     JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
operator >>(const basic_json & j,std::ostream & o)24330     friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
24331     {
24332         return o << j;
24333     }
24334 #endif  // JSON_NO_IO
24335     /// @}
24336 
24337 
24338     /////////////////////
24339     // deserialization //
24340     /////////////////////
24341 
24342     /// @name deserialization
24343     /// @{
24344 
24345     /*!
24346     @brief deserialize from a compatible input
24347 
24348     @tparam InputType A compatible input, for instance
24349     - an std::istream object
24350     - a FILE pointer
24351     - a C-style array of characters
24352     - a pointer to a null-terminated string of single byte characters
24353     - an object obj for which begin(obj) and end(obj) produces a valid pair of
24354       iterators.
24355 
24356     @param[in] i  input to read from
24357     @param[in] cb  a parser callback function of type @ref parser_callback_t
24358     which is used to control the deserialization by filtering unwanted values
24359     (optional)
24360     @param[in] allow_exceptions  whether to throw exceptions in case of a
24361     parse error (optional, true by default)
24362     @param[in] ignore_comments  whether comments should be ignored and treated
24363     like whitespace (true) or yield a parse error (true); (optional, false by
24364     default)
24365 
24366     @return deserialized JSON value; in case of a parse error and
24367             @a allow_exceptions set to `false`, the return value will be
24368             value_t::discarded.
24369 
24370     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24371     of input; expected string literal""`
24372     @throw parse_error.102 if to_unicode fails or surrogate error
24373     @throw parse_error.103 if to_unicode fails
24374 
24375     @complexity Linear in the length of the input. The parser is a predictive
24376     LL(1) parser. The complexity can be higher if the parser callback function
24377     @a cb or reading from the input @a i has a super-linear complexity.
24378 
24379     @note A UTF-8 byte order mark is silently ignored.
24380 
24381     @liveexample{The example below demonstrates the `parse()` function reading
24382     from an array.,parse__array__parser_callback_t}
24383 
24384     @liveexample{The example below demonstrates the `parse()` function with
24385     and without callback function.,parse__string__parser_callback_t}
24386 
24387     @liveexample{The example below demonstrates the `parse()` function with
24388     and without callback function.,parse__istream__parser_callback_t}
24389 
24390     @liveexample{The example below demonstrates the `parse()` function reading
24391     from a contiguous container.,parse__contiguouscontainer__parser_callback_t}
24392 
24393     @since version 2.0.3 (contiguous containers); version 3.9.0 allowed to
24394     ignore comments.
24395     */
24396     template<typename InputType>
24397     JSON_HEDLEY_WARN_UNUSED_RESULT
parse(InputType && i,const parser_callback_t cb=nullptr,const bool allow_exceptions=true,const bool ignore_comments=false)24398     static basic_json parse(InputType&& i,
24399                             const parser_callback_t cb = nullptr,
24400                             const bool allow_exceptions = true,
24401                             const bool ignore_comments = false)
24402     {
24403         basic_json result;
24404         parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
24405         return result;
24406     }
24407 
24408     /*!
24409     @brief deserialize from a pair of character iterators
24410 
24411     The value_type of the iterator must be a integral type with size of 1, 2 or
24412     4 bytes, which will be interpreted respectively as UTF-8, UTF-16 and UTF-32.
24413 
24414     @param[in] first iterator to start of character range
24415     @param[in] last  iterator to end of character range
24416     @param[in] cb  a parser callback function of type @ref parser_callback_t
24417     which is used to control the deserialization by filtering unwanted values
24418     (optional)
24419     @param[in] allow_exceptions  whether to throw exceptions in case of a
24420     parse error (optional, true by default)
24421     @param[in] ignore_comments  whether comments should be ignored and treated
24422     like whitespace (true) or yield a parse error (true); (optional, false by
24423     default)
24424 
24425     @return deserialized JSON value; in case of a parse error and
24426             @a allow_exceptions set to `false`, the return value will be
24427             value_t::discarded.
24428 
24429     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24430     of input; expected string literal""`
24431     @throw parse_error.102 if to_unicode fails or surrogate error
24432     @throw parse_error.103 if to_unicode fails
24433     */
24434     template<typename IteratorType>
24435     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)24436     static basic_json parse(IteratorType first,
24437                             IteratorType last,
24438                             const parser_callback_t cb = nullptr,
24439                             const bool allow_exceptions = true,
24440                             const bool ignore_comments = false)
24441     {
24442         basic_json result;
24443         parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
24444         return result;
24445     }
24446 
24447     JSON_HEDLEY_WARN_UNUSED_RESULT
24448     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)24449     static basic_json parse(detail::span_input_adapter&& i,
24450                             const parser_callback_t cb = nullptr,
24451                             const bool allow_exceptions = true,
24452                             const bool ignore_comments = false)
24453     {
24454         basic_json result;
24455         parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
24456         return result;
24457     }
24458 
24459     /*!
24460     @brief check if the input is valid JSON
24461 
24462     Unlike the @ref parse(InputType&&, const parser_callback_t,const bool)
24463     function, this function neither throws an exception in case of invalid JSON
24464     input (i.e., a parse error) nor creates diagnostic information.
24465 
24466     @tparam InputType A compatible input, for instance
24467     - an std::istream object
24468     - a FILE pointer
24469     - a C-style array of characters
24470     - a pointer to a null-terminated string of single byte characters
24471     - an object obj for which begin(obj) and end(obj) produces a valid pair of
24472       iterators.
24473 
24474     @param[in] i input to read from
24475     @param[in] ignore_comments  whether comments should be ignored and treated
24476     like whitespace (true) or yield a parse error (true); (optional, false by
24477     default)
24478 
24479     @return Whether the input read from @a i is valid JSON.
24480 
24481     @complexity Linear in the length of the input. The parser is a predictive
24482     LL(1) parser.
24483 
24484     @note A UTF-8 byte order mark is silently ignored.
24485 
24486     @liveexample{The example below demonstrates the `accept()` function reading
24487     from a string.,accept__string}
24488     */
24489     template<typename InputType>
accept(InputType && i,const bool ignore_comments=false)24490     static bool accept(InputType&& i,
24491                        const bool ignore_comments = false)
24492     {
24493         return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
24494     }
24495 
24496     template<typename IteratorType>
accept(IteratorType first,IteratorType last,const bool ignore_comments=false)24497     static bool accept(IteratorType first, IteratorType last,
24498                        const bool ignore_comments = false)
24499     {
24500         return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
24501     }
24502 
24503     JSON_HEDLEY_WARN_UNUSED_RESULT
24504     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
accept(detail::span_input_adapter && i,const bool ignore_comments=false)24505     static bool accept(detail::span_input_adapter&& i,
24506                        const bool ignore_comments = false)
24507     {
24508         return parser(i.get(), nullptr, false, ignore_comments).accept(true);
24509     }
24510 
24511     /*!
24512     @brief generate SAX events
24513 
24514     The SAX event lister must follow the interface of @ref json_sax.
24515 
24516     This function reads from a compatible input. Examples are:
24517     - an std::istream object
24518     - a FILE pointer
24519     - a C-style array of characters
24520     - a pointer to a null-terminated string of single byte characters
24521     - an object obj for which begin(obj) and end(obj) produces a valid pair of
24522       iterators.
24523 
24524     @param[in] i  input to read from
24525     @param[in,out] sax  SAX event listener
24526     @param[in] format  the format to parse (JSON, CBOR, MessagePack, or UBJSON)
24527     @param[in] strict  whether the input has to be consumed completely
24528     @param[in] ignore_comments  whether comments should be ignored and treated
24529     like whitespace (true) or yield a parse error (true); (optional, false by
24530     default); only applies to the JSON file format.
24531 
24532     @return return value of the last processed SAX event
24533 
24534     @throw parse_error.101 if a parse error occurs; example: `""unexpected end
24535     of input; expected string literal""`
24536     @throw parse_error.102 if to_unicode fails or surrogate error
24537     @throw parse_error.103 if to_unicode fails
24538 
24539     @complexity Linear in the length of the input. The parser is a predictive
24540     LL(1) parser. The complexity can be higher if the SAX consumer @a sax has
24541     a super-linear complexity.
24542 
24543     @note A UTF-8 byte order mark is silently ignored.
24544 
24545     @liveexample{The example below demonstrates the `sax_parse()` function
24546     reading from string and processing the events with a user-defined SAX
24547     event consumer.,sax_parse}
24548 
24549     @since version 3.2.0
24550     */
24551     template <typename InputType, typename SAX>
24552     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)24553     static bool sax_parse(InputType&& i, SAX* sax,
24554                           input_format_t format = input_format_t::json,
24555                           const bool strict = true,
24556                           const bool ignore_comments = false)
24557     {
24558         auto ia = detail::input_adapter(std::forward<InputType>(i));
24559         return format == input_format_t::json
24560                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24561                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24562     }
24563 
24564     template<class IteratorType, class SAX>
24565     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)24566     static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
24567                           input_format_t format = input_format_t::json,
24568                           const bool strict = true,
24569                           const bool ignore_comments = false)
24570     {
24571         auto ia = detail::input_adapter(std::move(first), std::move(last));
24572         return format == input_format_t::json
24573                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24574                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24575     }
24576 
24577     template <typename SAX>
24578     JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
24579     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)24580     static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
24581                           input_format_t format = input_format_t::json,
24582                           const bool strict = true,
24583                           const bool ignore_comments = false)
24584     {
24585         auto ia = i.get();
24586         return format == input_format_t::json
24587                // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24588                ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24589                // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24590                : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24591     }
24592 #ifndef JSON_NO_IO
24593     /*!
24594     @brief deserialize from stream
24595     @deprecated This stream operator is deprecated and will be removed in
24596                 version 4.0.0 of the library. Please use
24597                 @ref operator>>(std::istream&, basic_json&)
24598                 instead; that is, replace calls like `j << i;` with `i >> j;`.
24599     @since version 1.0.0; deprecated since version 3.0.0
24600     */
24601     JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
operator <<(basic_json & j,std::istream & i)24602     friend std::istream& operator<<(basic_json& j, std::istream& i)
24603     {
24604         return operator>>(i, j);
24605     }
24606 
24607     /*!
24608     @brief deserialize from stream
24609 
24610     Deserializes an input stream to a JSON value.
24611 
24612     @param[in,out] i  input stream to read a serialized JSON value from
24613     @param[in,out] j  JSON value to write the deserialized input to
24614 
24615     @throw parse_error.101 in case of an unexpected token
24616     @throw parse_error.102 if to_unicode fails or surrogate error
24617     @throw parse_error.103 if to_unicode fails
24618 
24619     @complexity Linear in the length of the input. The parser is a predictive
24620     LL(1) parser.
24621 
24622     @note A UTF-8 byte order mark is silently ignored.
24623 
24624     @liveexample{The example below shows how a JSON value is constructed by
24625     reading a serialization from a stream.,operator_deserialize}
24626 
24627     @sa parse(std::istream&, const parser_callback_t) for a variant with a
24628     parser callback function to filter values while parsing
24629 
24630     @since version 1.0.0
24631     */
operator >>(std::istream & i,basic_json & j)24632     friend std::istream& operator>>(std::istream& i, basic_json& j)
24633     {
24634         parser(detail::input_adapter(i)).parse(false, j);
24635         return i;
24636     }
24637 #endif  // JSON_NO_IO
24638     /// @}
24639 
24640     ///////////////////////////
24641     // convenience functions //
24642     ///////////////////////////
24643 
24644     /*!
24645     @brief return the type as string
24646 
24647     Returns the type name as string to be used in error messages - usually to
24648     indicate that a function was called on a wrong JSON type.
24649 
24650     @return a string representation of a the @a m_type member:
24651             Value type  | return value
24652             ----------- | -------------
24653             null        | `"null"`
24654             boolean     | `"boolean"`
24655             string      | `"string"`
24656             number      | `"number"` (for all number types)
24657             object      | `"object"`
24658             array       | `"array"`
24659             binary      | `"binary"`
24660             discarded   | `"discarded"`
24661 
24662     @exceptionsafety No-throw guarantee: this function never throws exceptions.
24663 
24664     @complexity Constant.
24665 
24666     @liveexample{The following code exemplifies `type_name()` for all JSON
24667     types.,type_name}
24668 
24669     @sa see @ref type() -- return the type of the JSON value
24670     @sa see @ref operator value_t() -- return the type of the JSON value (implicit)
24671 
24672     @since version 1.0.0, public since 2.1.0, `const char*` and `noexcept`
24673     since 3.0.0
24674     */
24675     JSON_HEDLEY_RETURNS_NON_NULL
type_name() const24676     const char* type_name() const noexcept
24677     {
24678         {
24679             switch (m_type)
24680             {
24681                 case value_t::null:
24682                     return "null";
24683                 case value_t::object:
24684                     return "object";
24685                 case value_t::array:
24686                     return "array";
24687                 case value_t::string:
24688                     return "string";
24689                 case value_t::boolean:
24690                     return "boolean";
24691                 case value_t::binary:
24692                     return "binary";
24693                 case value_t::discarded:
24694                     return "discarded";
24695                 case value_t::number_integer:
24696                 case value_t::number_unsigned:
24697                 case value_t::number_float:
24698                 default:
24699                     return "number";
24700             }
24701         }
24702     }
24703 
24704 
24705   JSON_PRIVATE_UNLESS_TESTED:
24706     //////////////////////
24707     // member variables //
24708     //////////////////////
24709 
24710     /// the type of the current element
24711     value_t m_type = value_t::null;
24712 
24713     /// the value of the current element
24714     json_value m_value = {};
24715 
24716 #if JSON_DIAGNOSTICS
24717     /// a pointer to a parent value (for debugging purposes)
24718     basic_json* m_parent = nullptr;
24719 #endif
24720 
24721     //////////////////////////////////////////
24722     // binary serialization/deserialization //
24723     //////////////////////////////////////////
24724 
24725     /// @name binary serialization/deserialization support
24726     /// @{
24727 
24728   public:
24729     /*!
24730     @brief create a CBOR serialization of a given JSON value
24731 
24732     Serializes a given JSON value @a j to a byte vector using the CBOR (Concise
24733     Binary Object Representation) serialization format. CBOR is a binary
24734     serialization format which aims to be more compact than JSON itself, yet
24735     more efficient to parse.
24736 
24737     The library uses the following mapping from JSON values types to
24738     CBOR types according to the CBOR specification (RFC 7049):
24739 
24740     JSON value type | value/range                                | CBOR type                          | first byte
24741     --------------- | ------------------------------------------ | ---------------------------------- | ---------------
24742     null            | `null`                                     | Null                               | 0xF6
24743     boolean         | `true`                                     | True                               | 0xF5
24744     boolean         | `false`                                    | False                              | 0xF4
24745     number_integer  | -9223372036854775808..-2147483649          | Negative integer (8 bytes follow)  | 0x3B
24746     number_integer  | -2147483648..-32769                        | Negative integer (4 bytes follow)  | 0x3A
24747     number_integer  | -32768..-129                               | Negative integer (2 bytes follow)  | 0x39
24748     number_integer  | -128..-25                                  | Negative integer (1 byte follow)   | 0x38
24749     number_integer  | -24..-1                                    | Negative integer                   | 0x20..0x37
24750     number_integer  | 0..23                                      | Integer                            | 0x00..0x17
24751     number_integer  | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
24752     number_integer  | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
24753     number_integer  | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
24754     number_integer  | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
24755     number_unsigned | 0..23                                      | Integer                            | 0x00..0x17
24756     number_unsigned | 24..255                                    | Unsigned integer (1 byte follow)   | 0x18
24757     number_unsigned | 256..65535                                 | Unsigned integer (2 bytes follow)  | 0x19
24758     number_unsigned | 65536..4294967295                          | Unsigned integer (4 bytes follow)  | 0x1A
24759     number_unsigned | 4294967296..18446744073709551615           | Unsigned integer (8 bytes follow)  | 0x1B
24760     number_float    | *any value representable by a float*       | Single-Precision Float             | 0xFA
24761     number_float    | *any value NOT representable by a float*   | Double-Precision Float             | 0xFB
24762     string          | *length*: 0..23                            | UTF-8 string                       | 0x60..0x77
24763     string          | *length*: 23..255                          | UTF-8 string (1 byte follow)       | 0x78
24764     string          | *length*: 256..65535                       | UTF-8 string (2 bytes follow)      | 0x79
24765     string          | *length*: 65536..4294967295                | UTF-8 string (4 bytes follow)      | 0x7A
24766     string          | *length*: 4294967296..18446744073709551615 | UTF-8 string (8 bytes follow)      | 0x7B
24767     array           | *size*: 0..23                              | array                              | 0x80..0x97
24768     array           | *size*: 23..255                            | array (1 byte follow)              | 0x98
24769     array           | *size*: 256..65535                         | array (2 bytes follow)             | 0x99
24770     array           | *size*: 65536..4294967295                  | array (4 bytes follow)             | 0x9A
24771     array           | *size*: 4294967296..18446744073709551615   | array (8 bytes follow)             | 0x9B
24772     object          | *size*: 0..23                              | map                                | 0xA0..0xB7
24773     object          | *size*: 23..255                            | map (1 byte follow)                | 0xB8
24774     object          | *size*: 256..65535                         | map (2 bytes follow)               | 0xB9
24775     object          | *size*: 65536..4294967295                  | map (4 bytes follow)               | 0xBA
24776     object          | *size*: 4294967296..18446744073709551615   | map (8 bytes follow)               | 0xBB
24777     binary          | *size*: 0..23                              | byte string                        | 0x40..0x57
24778     binary          | *size*: 23..255                            | byte string (1 byte follow)        | 0x58
24779     binary          | *size*: 256..65535                         | byte string (2 bytes follow)       | 0x59
24780     binary          | *size*: 65536..4294967295                  | byte string (4 bytes follow)       | 0x5A
24781     binary          | *size*: 4294967296..18446744073709551615   | byte string (8 bytes follow)       | 0x5B
24782 
24783     Binary values with subtype are mapped to tagged values (0xD8..0xDB)
24784     depending on the subtype, followed by a byte string, see "binary" cells
24785     in the table above.
24786 
24787     @note The mapping is **complete** in the sense that any JSON value type
24788           can be converted to a CBOR value.
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     @note The following CBOR types are not used in the conversion:
24795           - UTF-8 strings terminated by "break" (0x7F)
24796           - arrays terminated by "break" (0x9F)
24797           - maps terminated by "break" (0xBF)
24798           - byte strings terminated by "break" (0x5F)
24799           - date/time (0xC0..0xC1)
24800           - bignum (0xC2..0xC3)
24801           - decimal fraction (0xC4)
24802           - bigfloat (0xC5)
24803           - expected conversions (0xD5..0xD7)
24804           - simple values (0xE0..0xF3, 0xF8)
24805           - undefined (0xF7)
24806           - half-precision floats (0xF9)
24807           - break (0xFF)
24808 
24809     @param[in] j  JSON value to serialize
24810     @return CBOR serialization as byte vector
24811 
24812     @complexity Linear in the size of the JSON value @a j.
24813 
24814     @liveexample{The example shows the serialization of a JSON value to a byte
24815     vector in CBOR format.,to_cbor}
24816 
24817     @sa http://cbor.io
24818     @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
24819         analogous deserialization
24820     @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
24821     @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
24822              related UBJSON format
24823 
24824     @since version 2.0.9; compact representation of floating-point numbers
24825            since version 3.8.0
24826     */
to_cbor(const basic_json & j)24827     static std::vector<std::uint8_t> to_cbor(const basic_json& j)
24828     {
24829         std::vector<std::uint8_t> result;
24830         to_cbor(j, result);
24831         return result;
24832     }
24833 
to_cbor(const basic_json & j,detail::output_adapter<std::uint8_t> o)24834     static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24835     {
24836         binary_writer<std::uint8_t>(o).write_cbor(j);
24837     }
24838 
to_cbor(const basic_json & j,detail::output_adapter<char> o)24839     static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
24840     {
24841         binary_writer<char>(o).write_cbor(j);
24842     }
24843 
24844     /*!
24845     @brief create a MessagePack serialization of a given JSON value
24846 
24847     Serializes a given JSON value @a j to a byte vector using the MessagePack
24848     serialization format. MessagePack is a binary serialization format which
24849     aims to be more compact than JSON itself, yet more efficient to parse.
24850 
24851     The library uses the following mapping from JSON values types to
24852     MessagePack types according to the MessagePack specification:
24853 
24854     JSON value type | value/range                       | MessagePack type | first byte
24855     --------------- | --------------------------------- | ---------------- | ----------
24856     null            | `null`                            | nil              | 0xC0
24857     boolean         | `true`                            | true             | 0xC3
24858     boolean         | `false`                           | false            | 0xC2
24859     number_integer  | -9223372036854775808..-2147483649 | int64            | 0xD3
24860     number_integer  | -2147483648..-32769               | int32            | 0xD2
24861     number_integer  | -32768..-129                      | int16            | 0xD1
24862     number_integer  | -128..-33                         | int8             | 0xD0
24863     number_integer  | -32..-1                           | negative fixint  | 0xE0..0xFF
24864     number_integer  | 0..127                            | positive fixint  | 0x00..0x7F
24865     number_integer  | 128..255                          | uint 8           | 0xCC
24866     number_integer  | 256..65535                        | uint 16          | 0xCD
24867     number_integer  | 65536..4294967295                 | uint 32          | 0xCE
24868     number_integer  | 4294967296..18446744073709551615  | uint 64          | 0xCF
24869     number_unsigned | 0..127                            | positive fixint  | 0x00..0x7F
24870     number_unsigned | 128..255                          | uint 8           | 0xCC
24871     number_unsigned | 256..65535                        | uint 16          | 0xCD
24872     number_unsigned | 65536..4294967295                 | uint 32          | 0xCE
24873     number_unsigned | 4294967296..18446744073709551615  | uint 64          | 0xCF
24874     number_float    | *any value representable by a float*     | float 32 | 0xCA
24875     number_float    | *any value NOT representable by a float* | float 64 | 0xCB
24876     string          | *length*: 0..31                   | fixstr           | 0xA0..0xBF
24877     string          | *length*: 32..255                 | str 8            | 0xD9
24878     string          | *length*: 256..65535              | str 16           | 0xDA
24879     string          | *length*: 65536..4294967295       | str 32           | 0xDB
24880     array           | *size*: 0..15                     | fixarray         | 0x90..0x9F
24881     array           | *size*: 16..65535                 | array 16         | 0xDC
24882     array           | *size*: 65536..4294967295         | array 32         | 0xDD
24883     object          | *size*: 0..15                     | fix map          | 0x80..0x8F
24884     object          | *size*: 16..65535                 | map 16           | 0xDE
24885     object          | *size*: 65536..4294967295         | map 32           | 0xDF
24886     binary          | *size*: 0..255                    | bin 8            | 0xC4
24887     binary          | *size*: 256..65535                | bin 16           | 0xC5
24888     binary          | *size*: 65536..4294967295         | bin 32           | 0xC6
24889 
24890     @note The mapping is **complete** in the sense that any JSON value type
24891           can be converted to a MessagePack value.
24892 
24893     @note The following values can **not** be converted to a MessagePack value:
24894           - strings with more than 4294967295 bytes
24895           - byte strings with more than 4294967295 bytes
24896           - arrays with more than 4294967295 elements
24897           - objects with more than 4294967295 elements
24898 
24899     @note Any MessagePack output created @ref to_msgpack can be successfully
24900           parsed by @ref from_msgpack.
24901 
24902     @note If NaN or Infinity are stored inside a JSON number, they are
24903           serialized properly. This behavior differs from the @ref dump()
24904           function which serializes NaN or Infinity to `null`.
24905 
24906     @param[in] j  JSON value to serialize
24907     @return MessagePack serialization as byte vector
24908 
24909     @complexity Linear in the size of the JSON value @a j.
24910 
24911     @liveexample{The example shows the serialization of a JSON value to a byte
24912     vector in MessagePack format.,to_msgpack}
24913 
24914     @sa http://msgpack.org
24915     @sa see @ref from_msgpack for the analogous deserialization
24916     @sa see @ref to_cbor(const basic_json& for the related CBOR format
24917     @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
24918              related UBJSON format
24919 
24920     @since version 2.0.9
24921     */
to_msgpack(const basic_json & j)24922     static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
24923     {
24924         std::vector<std::uint8_t> result;
24925         to_msgpack(j, result);
24926         return result;
24927     }
24928 
to_msgpack(const basic_json & j,detail::output_adapter<std::uint8_t> o)24929     static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24930     {
24931         binary_writer<std::uint8_t>(o).write_msgpack(j);
24932     }
24933 
to_msgpack(const basic_json & j,detail::output_adapter<char> o)24934     static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
24935     {
24936         binary_writer<char>(o).write_msgpack(j);
24937     }
24938 
24939     /*!
24940     @brief create a UBJSON serialization of a given JSON value
24941 
24942     Serializes a given JSON value @a j to a byte vector using the UBJSON
24943     (Universal Binary JSON) serialization format. UBJSON aims to be more compact
24944     than JSON itself, yet more efficient to parse.
24945 
24946     The library uses the following mapping from JSON values types to
24947     UBJSON types according to the UBJSON specification:
24948 
24949     JSON value type | value/range                       | UBJSON type | marker
24950     --------------- | --------------------------------- | ----------- | ------
24951     null            | `null`                            | null        | `Z`
24952     boolean         | `true`                            | true        | `T`
24953     boolean         | `false`                           | false       | `F`
24954     number_integer  | -9223372036854775808..-2147483649 | int64       | `L`
24955     number_integer  | -2147483648..-32769               | int32       | `l`
24956     number_integer  | -32768..-129                      | int16       | `I`
24957     number_integer  | -128..127                         | int8        | `i`
24958     number_integer  | 128..255                          | uint8       | `U`
24959     number_integer  | 256..32767                        | int16       | `I`
24960     number_integer  | 32768..2147483647                 | int32       | `l`
24961     number_integer  | 2147483648..9223372036854775807   | int64       | `L`
24962     number_unsigned | 0..127                            | int8        | `i`
24963     number_unsigned | 128..255                          | uint8       | `U`
24964     number_unsigned | 256..32767                        | int16       | `I`
24965     number_unsigned | 32768..2147483647                 | int32       | `l`
24966     number_unsigned | 2147483648..9223372036854775807   | int64       | `L`
24967     number_unsigned | 2147483649..18446744073709551615  | high-precision | `H`
24968     number_float    | *any value*                       | float64     | `D`
24969     string          | *with shortest length indicator*  | string      | `S`
24970     array           | *see notes on optimized format*   | array       | `[`
24971     object          | *see notes on optimized format*   | map         | `{`
24972 
24973     @note The mapping is **complete** in the sense that any JSON value type
24974           can be converted to a UBJSON value.
24975 
24976     @note The following values can **not** be converted to a UBJSON value:
24977           - strings with more than 9223372036854775807 bytes (theoretical)
24978 
24979     @note The following markers are not used in the conversion:
24980           - `Z`: no-op values are not created.
24981           - `C`: single-byte strings are serialized with `S` markers.
24982 
24983     @note Any UBJSON output created @ref to_ubjson can be successfully parsed
24984           by @ref from_ubjson.
24985 
24986     @note If NaN or Infinity are stored inside a JSON number, they are
24987           serialized properly. This behavior differs from the @ref dump()
24988           function which serializes NaN or Infinity to `null`.
24989 
24990     @note The optimized formats for containers are supported: Parameter
24991           @a use_size adds size information to the beginning of a container and
24992           removes the closing marker. Parameter @a use_type further checks
24993           whether all elements of a container have the same type and adds the
24994           type marker to the beginning of the container. The @a use_type
24995           parameter must only be used together with @a use_size = true. Note
24996           that @a use_size = true alone may result in larger representations -
24997           the benefit of this parameter is that the receiving side is
24998           immediately informed on the number of elements of the container.
24999 
25000     @note If the JSON data contains the binary type, the value stored is a list
25001           of integers, as suggested by the UBJSON documentation.  In particular,
25002           this means that serialization and the deserialization of a JSON
25003           containing binary values into UBJSON and back will result in a
25004           different JSON object.
25005 
25006     @param[in] j  JSON value to serialize
25007     @param[in] use_size  whether to add size annotations to container types
25008     @param[in] use_type  whether to add type annotations to container types
25009                          (must be combined with @a use_size = true)
25010     @return UBJSON serialization as byte vector
25011 
25012     @complexity Linear in the size of the JSON value @a j.
25013 
25014     @liveexample{The example shows the serialization of a JSON value to a byte
25015     vector in UBJSON format.,to_ubjson}
25016 
25017     @sa http://ubjson.org
25018     @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
25019         analogous deserialization
25020     @sa see @ref to_cbor(const basic_json& for the related CBOR format
25021     @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
25022 
25023     @since version 3.1.0
25024     */
to_ubjson(const basic_json & j,const bool use_size=false,const bool use_type=false)25025     static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
25026             const bool use_size = false,
25027             const bool use_type = false)
25028     {
25029         std::vector<std::uint8_t> result;
25030         to_ubjson(j, result, use_size, use_type);
25031         return result;
25032     }
25033 
to_ubjson(const basic_json & j,detail::output_adapter<std::uint8_t> o,const bool use_size=false,const bool use_type=false)25034     static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,
25035                           const bool use_size = false, const bool use_type = false)
25036     {
25037         binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
25038     }
25039 
to_ubjson(const basic_json & j,detail::output_adapter<char> o,const bool use_size=false,const bool use_type=false)25040     static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
25041                           const bool use_size = false, const bool use_type = false)
25042     {
25043         binary_writer<char>(o).write_ubjson(j, use_size, use_type);
25044     }
25045 
25046 
25047     /*!
25048     @brief Serializes the given JSON object `j` to BSON and returns a vector
25049            containing the corresponding BSON-representation.
25050 
25051     BSON (Binary JSON) is a binary format in which zero or more ordered key/value pairs are
25052     stored as a single entity (a so-called document).
25053 
25054     The library uses the following mapping from JSON values types to BSON types:
25055 
25056     JSON value type | value/range                       | BSON type   | marker
25057     --------------- | --------------------------------- | ----------- | ------
25058     null            | `null`                            | null        | 0x0A
25059     boolean         | `true`, `false`                   | boolean     | 0x08
25060     number_integer  | -9223372036854775808..-2147483649 | int64       | 0x12
25061     number_integer  | -2147483648..2147483647           | int32       | 0x10
25062     number_integer  | 2147483648..9223372036854775807   | int64       | 0x12
25063     number_unsigned | 0..2147483647                     | int32       | 0x10
25064     number_unsigned | 2147483648..9223372036854775807   | int64       | 0x12
25065     number_unsigned | 9223372036854775808..18446744073709551615| --   | --
25066     number_float    | *any value*                       | double      | 0x01
25067     string          | *any value*                       | string      | 0x02
25068     array           | *any value*                       | document    | 0x04
25069     object          | *any value*                       | document    | 0x03
25070     binary          | *any value*                       | binary      | 0x05
25071 
25072     @warning The mapping is **incomplete**, since only JSON-objects (and things
25073     contained therein) can be serialized to BSON.
25074     Also, integers larger than 9223372036854775807 cannot be serialized to BSON,
25075     and the keys may not contain U+0000, since they are serialized a
25076     zero-terminated c-strings.
25077 
25078     @throw out_of_range.407  if `j.is_number_unsigned() && j.get<std::uint64_t>() > 9223372036854775807`
25079     @throw out_of_range.409  if a key in `j` contains a NULL (U+0000)
25080     @throw type_error.317    if `!j.is_object()`
25081 
25082     @pre The input `j` is required to be an object: `j.is_object() == true`.
25083 
25084     @note Any BSON output created via @ref to_bson can be successfully parsed
25085           by @ref from_bson.
25086 
25087     @param[in] j  JSON value to serialize
25088     @return BSON serialization as byte vector
25089 
25090     @complexity Linear in the size of the JSON value @a j.
25091 
25092     @liveexample{The example shows the serialization of a JSON value to a byte
25093     vector in BSON format.,to_bson}
25094 
25095     @sa http://bsonspec.org/spec.html
25096     @sa see @ref from_bson(detail::input_adapter&&, const bool strict) for the
25097         analogous deserialization
25098     @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
25099              related UBJSON format
25100     @sa see @ref to_cbor(const basic_json&) for the related CBOR format
25101     @sa see @ref to_msgpack(const basic_json&) for the related MessagePack format
25102     */
to_bson(const basic_json & j)25103     static std::vector<std::uint8_t> to_bson(const basic_json& j)
25104     {
25105         std::vector<std::uint8_t> result;
25106         to_bson(j, result);
25107         return result;
25108     }
25109 
25110     /*!
25111     @brief Serializes the given JSON object `j` to BSON and forwards the
25112            corresponding BSON-representation to the given output_adapter `o`.
25113     @param j The JSON object to convert to BSON.
25114     @param o The output adapter that receives the binary BSON representation.
25115     @pre The input `j` shall be an object: `j.is_object() == true`
25116     @sa see @ref to_bson(const basic_json&)
25117     */
to_bson(const basic_json & j,detail::output_adapter<std::uint8_t> o)25118     static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)
25119     {
25120         binary_writer<std::uint8_t>(o).write_bson(j);
25121     }
25122 
25123     /*!
25124     @copydoc to_bson(const basic_json&, detail::output_adapter<std::uint8_t>)
25125     */
to_bson(const basic_json & j,detail::output_adapter<char> o)25126     static void to_bson(const basic_json& j, detail::output_adapter<char> o)
25127     {
25128         binary_writer<char>(o).write_bson(j);
25129     }
25130 
25131 
25132     /*!
25133     @brief create a JSON value from an input in CBOR format
25134 
25135     Deserializes a given input @a i to a JSON value using the CBOR (Concise
25136     Binary Object Representation) serialization format.
25137 
25138     The library maps CBOR types to JSON value types as follows:
25139 
25140     CBOR type              | JSON value type | first byte
25141     ---------------------- | --------------- | ----------
25142     Integer                | number_unsigned | 0x00..0x17
25143     Unsigned integer       | number_unsigned | 0x18
25144     Unsigned integer       | number_unsigned | 0x19
25145     Unsigned integer       | number_unsigned | 0x1A
25146     Unsigned integer       | number_unsigned | 0x1B
25147     Negative integer       | number_integer  | 0x20..0x37
25148     Negative integer       | number_integer  | 0x38
25149     Negative integer       | number_integer  | 0x39
25150     Negative integer       | number_integer  | 0x3A
25151     Negative integer       | number_integer  | 0x3B
25152     Byte string            | binary          | 0x40..0x57
25153     Byte string            | binary          | 0x58
25154     Byte string            | binary          | 0x59
25155     Byte string            | binary          | 0x5A
25156     Byte string            | binary          | 0x5B
25157     UTF-8 string           | string          | 0x60..0x77
25158     UTF-8 string           | string          | 0x78
25159     UTF-8 string           | string          | 0x79
25160     UTF-8 string           | string          | 0x7A
25161     UTF-8 string           | string          | 0x7B
25162     UTF-8 string           | string          | 0x7F
25163     array                  | array           | 0x80..0x97
25164     array                  | array           | 0x98
25165     array                  | array           | 0x99
25166     array                  | array           | 0x9A
25167     array                  | array           | 0x9B
25168     array                  | array           | 0x9F
25169     map                    | object          | 0xA0..0xB7
25170     map                    | object          | 0xB8
25171     map                    | object          | 0xB9
25172     map                    | object          | 0xBA
25173     map                    | object          | 0xBB
25174     map                    | object          | 0xBF
25175     False                  | `false`         | 0xF4
25176     True                   | `true`          | 0xF5
25177     Null                   | `null`          | 0xF6
25178     Half-Precision Float   | number_float    | 0xF9
25179     Single-Precision Float | number_float    | 0xFA
25180     Double-Precision Float | number_float    | 0xFB
25181 
25182     @warning The mapping is **incomplete** in the sense that not all CBOR
25183              types can be converted to a JSON value. The following CBOR types
25184              are not supported and will yield parse errors (parse_error.112):
25185              - date/time (0xC0..0xC1)
25186              - bignum (0xC2..0xC3)
25187              - decimal fraction (0xC4)
25188              - bigfloat (0xC5)
25189              - expected conversions (0xD5..0xD7)
25190              - simple values (0xE0..0xF3, 0xF8)
25191              - undefined (0xF7)
25192 
25193     @warning CBOR allows map keys of any type, whereas JSON only allows
25194              strings as keys in object values. Therefore, CBOR maps with keys
25195              other than UTF-8 strings are rejected (parse_error.113).
25196 
25197     @note Any CBOR output created @ref to_cbor can be successfully parsed by
25198           @ref from_cbor.
25199 
25200     @param[in] i  an input in CBOR format convertible to an input adapter
25201     @param[in] strict  whether to expect the input to be consumed until EOF
25202                        (true by default)
25203     @param[in] allow_exceptions  whether to throw exceptions in case of a
25204     parse error (optional, true by default)
25205     @param[in] tag_handler how to treat CBOR tags (optional, error by default)
25206 
25207     @return deserialized JSON value; in case of a parse error and
25208             @a allow_exceptions set to `false`, the return value will be
25209             value_t::discarded.
25210 
25211     @throw parse_error.110 if the given input ends prematurely or the end of
25212     file was not reached when @a strict was set to true
25213     @throw parse_error.112 if unsupported features from CBOR were
25214     used in the given input @a v or if the input is not valid CBOR
25215     @throw parse_error.113 if a string was expected as map key, but not found
25216 
25217     @complexity Linear in the size of the input @a i.
25218 
25219     @liveexample{The example shows the deserialization of a byte vector in CBOR
25220     format to a JSON value.,from_cbor}
25221 
25222     @sa http://cbor.io
25223     @sa see @ref to_cbor(const basic_json&) for the analogous serialization
25224     @sa see @ref from_msgpack(InputType&&, const bool, const bool) for the
25225         related MessagePack format
25226     @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
25227         related UBJSON format
25228 
25229     @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
25230            consume input adapters, removed start_index parameter, and added
25231            @a strict parameter since 3.0.0; added @a allow_exceptions parameter
25232            since 3.2.0; added @a tag_handler parameter since 3.9.0.
25233     */
25234     template<typename InputType>
25235     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)25236     static basic_json from_cbor(InputType&& i,
25237                                 const bool strict = true,
25238                                 const bool allow_exceptions = true,
25239                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25240     {
25241         basic_json result;
25242         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25243         auto ia = detail::input_adapter(std::forward<InputType>(i));
25244         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25245         return res ? result : basic_json(value_t::discarded);
25246     }
25247 
25248     /*!
25249     @copydoc from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t)
25250     */
25251     template<typename IteratorType>
25252     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)25253     static basic_json from_cbor(IteratorType first, IteratorType last,
25254                                 const bool strict = true,
25255                                 const bool allow_exceptions = true,
25256                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25257     {
25258         basic_json result;
25259         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25260         auto ia = detail::input_adapter(std::move(first), std::move(last));
25261         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25262         return res ? result : basic_json(value_t::discarded);
25263     }
25264 
25265     template<typename T>
25266     JSON_HEDLEY_WARN_UNUSED_RESULT
25267     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)25268     static basic_json from_cbor(const T* ptr, std::size_t len,
25269                                 const bool strict = true,
25270                                 const bool allow_exceptions = true,
25271                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25272     {
25273         return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
25274     }
25275 
25276 
25277     JSON_HEDLEY_WARN_UNUSED_RESULT
25278     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)25279     static basic_json from_cbor(detail::span_input_adapter&& i,
25280                                 const bool strict = true,
25281                                 const bool allow_exceptions = true,
25282                                 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25283     {
25284         basic_json result;
25285         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25286         auto ia = i.get();
25287         // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25288         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25289         return res ? result : basic_json(value_t::discarded);
25290     }
25291 
25292     /*!
25293     @brief create a JSON value from an input in MessagePack format
25294 
25295     Deserializes a given input @a i to a JSON value using the MessagePack
25296     serialization format.
25297 
25298     The library maps MessagePack types to JSON value types as follows:
25299 
25300     MessagePack type | JSON value type | first byte
25301     ---------------- | --------------- | ----------
25302     positive fixint  | number_unsigned | 0x00..0x7F
25303     fixmap           | object          | 0x80..0x8F
25304     fixarray         | array           | 0x90..0x9F
25305     fixstr           | string          | 0xA0..0xBF
25306     nil              | `null`          | 0xC0
25307     false            | `false`         | 0xC2
25308     true             | `true`          | 0xC3
25309     float 32         | number_float    | 0xCA
25310     float 64         | number_float    | 0xCB
25311     uint 8           | number_unsigned | 0xCC
25312     uint 16          | number_unsigned | 0xCD
25313     uint 32          | number_unsigned | 0xCE
25314     uint 64          | number_unsigned | 0xCF
25315     int 8            | number_integer  | 0xD0
25316     int 16           | number_integer  | 0xD1
25317     int 32           | number_integer  | 0xD2
25318     int 64           | number_integer  | 0xD3
25319     str 8            | string          | 0xD9
25320     str 16           | string          | 0xDA
25321     str 32           | string          | 0xDB
25322     array 16         | array           | 0xDC
25323     array 32         | array           | 0xDD
25324     map 16           | object          | 0xDE
25325     map 32           | object          | 0xDF
25326     bin 8            | binary          | 0xC4
25327     bin 16           | binary          | 0xC5
25328     bin 32           | binary          | 0xC6
25329     ext 8            | binary          | 0xC7
25330     ext 16           | binary          | 0xC8
25331     ext 32           | binary          | 0xC9
25332     fixext 1         | binary          | 0xD4
25333     fixext 2         | binary          | 0xD5
25334     fixext 4         | binary          | 0xD6
25335     fixext 8         | binary          | 0xD7
25336     fixext 16        | binary          | 0xD8
25337     negative fixint  | number_integer  | 0xE0-0xFF
25338 
25339     @note Any MessagePack output created @ref to_msgpack can be successfully
25340           parsed by @ref from_msgpack.
25341 
25342     @param[in] i  an input in MessagePack format convertible to an input
25343                   adapter
25344     @param[in] strict  whether to expect the input to be consumed until EOF
25345                        (true by default)
25346     @param[in] allow_exceptions  whether to throw exceptions in case of a
25347     parse error (optional, true by default)
25348 
25349     @return deserialized JSON value; in case of a parse error and
25350             @a allow_exceptions set to `false`, the return value will be
25351             value_t::discarded.
25352 
25353     @throw parse_error.110 if the given input ends prematurely or the end of
25354     file was not reached when @a strict was set to true
25355     @throw parse_error.112 if unsupported features from MessagePack were
25356     used in the given input @a i or if the input is not valid MessagePack
25357     @throw parse_error.113 if a string was expected as map key, but not found
25358 
25359     @complexity Linear in the size of the input @a i.
25360 
25361     @liveexample{The example shows the deserialization of a byte vector in
25362     MessagePack format to a JSON value.,from_msgpack}
25363 
25364     @sa http://msgpack.org
25365     @sa see @ref to_msgpack(const basic_json&) for the analogous serialization
25366     @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25367         related CBOR format
25368     @sa see @ref from_ubjson(InputType&&, const bool, const bool) for
25369         the related UBJSON format
25370     @sa see @ref from_bson(InputType&&, const bool, const bool) for
25371         the related BSON format
25372 
25373     @since version 2.0.9; parameter @a start_index since 2.1.1; changed to
25374            consume input adapters, removed start_index parameter, and added
25375            @a strict parameter since 3.0.0; added @a allow_exceptions parameter
25376            since 3.2.0
25377     */
25378     template<typename InputType>
25379     JSON_HEDLEY_WARN_UNUSED_RESULT
from_msgpack(InputType && i,const bool strict=true,const bool allow_exceptions=true)25380     static basic_json from_msgpack(InputType&& i,
25381                                    const bool strict = true,
25382                                    const bool allow_exceptions = true)
25383     {
25384         basic_json result;
25385         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25386         auto ia = detail::input_adapter(std::forward<InputType>(i));
25387         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25388         return res ? result : basic_json(value_t::discarded);
25389     }
25390 
25391     /*!
25392     @copydoc from_msgpack(InputType&&, const bool, const bool)
25393     */
25394     template<typename IteratorType>
25395     JSON_HEDLEY_WARN_UNUSED_RESULT
from_msgpack(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)25396     static basic_json from_msgpack(IteratorType first, IteratorType last,
25397                                    const bool strict = true,
25398                                    const bool allow_exceptions = true)
25399     {
25400         basic_json result;
25401         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25402         auto ia = detail::input_adapter(std::move(first), std::move(last));
25403         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25404         return res ? result : basic_json(value_t::discarded);
25405     }
25406 
25407 
25408     template<typename T>
25409     JSON_HEDLEY_WARN_UNUSED_RESULT
25410     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)25411     static basic_json from_msgpack(const T* ptr, std::size_t len,
25412                                    const bool strict = true,
25413                                    const bool allow_exceptions = true)
25414     {
25415         return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
25416     }
25417 
25418     JSON_HEDLEY_WARN_UNUSED_RESULT
25419     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)25420     static basic_json from_msgpack(detail::span_input_adapter&& i,
25421                                    const bool strict = true,
25422                                    const bool allow_exceptions = true)
25423     {
25424         basic_json result;
25425         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25426         auto ia = i.get();
25427         // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25428         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25429         return res ? result : basic_json(value_t::discarded);
25430     }
25431 
25432 
25433     /*!
25434     @brief create a JSON value from an input in UBJSON format
25435 
25436     Deserializes a given input @a i to a JSON value using the UBJSON (Universal
25437     Binary JSON) serialization format.
25438 
25439     The library maps UBJSON types to JSON value types as follows:
25440 
25441     UBJSON type | JSON value type                         | marker
25442     ----------- | --------------------------------------- | ------
25443     no-op       | *no value, next value is read*          | `N`
25444     null        | `null`                                  | `Z`
25445     false       | `false`                                 | `F`
25446     true        | `true`                                  | `T`
25447     float32     | number_float                            | `d`
25448     float64     | number_float                            | `D`
25449     uint8       | number_unsigned                         | `U`
25450     int8        | number_integer                          | `i`
25451     int16       | number_integer                          | `I`
25452     int32       | number_integer                          | `l`
25453     int64       | number_integer                          | `L`
25454     high-precision number | number_integer, number_unsigned, or number_float - depends on number string | 'H'
25455     string      | string                                  | `S`
25456     char        | string                                  | `C`
25457     array       | array (optimized values are supported)  | `[`
25458     object      | object (optimized values are supported) | `{`
25459 
25460     @note The mapping is **complete** in the sense that any UBJSON value can
25461           be converted to a JSON value.
25462 
25463     @param[in] i  an input in UBJSON format convertible to an input adapter
25464     @param[in] strict  whether to expect the input to be consumed until EOF
25465                        (true by default)
25466     @param[in] allow_exceptions  whether to throw exceptions in case of a
25467     parse error (optional, true by default)
25468 
25469     @return deserialized JSON value; in case of a parse error and
25470             @a allow_exceptions set to `false`, the return value will be
25471             value_t::discarded.
25472 
25473     @throw parse_error.110 if the given input ends prematurely or the end of
25474     file was not reached when @a strict was set to true
25475     @throw parse_error.112 if a parse error occurs
25476     @throw parse_error.113 if a string could not be parsed successfully
25477 
25478     @complexity Linear in the size of the input @a i.
25479 
25480     @liveexample{The example shows the deserialization of a byte vector in
25481     UBJSON format to a JSON value.,from_ubjson}
25482 
25483     @sa http://ubjson.org
25484     @sa see @ref to_ubjson(const basic_json&, const bool, const bool) for the
25485              analogous serialization
25486     @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25487         related CBOR format
25488     @sa see @ref from_msgpack(InputType&&, const bool, const bool) for
25489         the related MessagePack format
25490     @sa see @ref from_bson(InputType&&, const bool, const bool) for
25491         the related BSON format
25492 
25493     @since version 3.1.0; added @a allow_exceptions parameter since 3.2.0
25494     */
25495     template<typename InputType>
25496     JSON_HEDLEY_WARN_UNUSED_RESULT
from_ubjson(InputType && i,const bool strict=true,const bool allow_exceptions=true)25497     static basic_json from_ubjson(InputType&& i,
25498                                   const bool strict = true,
25499                                   const bool allow_exceptions = true)
25500     {
25501         basic_json result;
25502         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25503         auto ia = detail::input_adapter(std::forward<InputType>(i));
25504         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25505         return res ? result : basic_json(value_t::discarded);
25506     }
25507 
25508     /*!
25509     @copydoc from_ubjson(InputType&&, const bool, const bool)
25510     */
25511     template<typename IteratorType>
25512     JSON_HEDLEY_WARN_UNUSED_RESULT
from_ubjson(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)25513     static basic_json from_ubjson(IteratorType first, IteratorType last,
25514                                   const bool strict = true,
25515                                   const bool allow_exceptions = true)
25516     {
25517         basic_json result;
25518         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25519         auto ia = detail::input_adapter(std::move(first), std::move(last));
25520         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25521         return res ? result : basic_json(value_t::discarded);
25522     }
25523 
25524     template<typename T>
25525     JSON_HEDLEY_WARN_UNUSED_RESULT
25526     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)25527     static basic_json from_ubjson(const T* ptr, std::size_t len,
25528                                   const bool strict = true,
25529                                   const bool allow_exceptions = true)
25530     {
25531         return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
25532     }
25533 
25534     JSON_HEDLEY_WARN_UNUSED_RESULT
25535     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)25536     static basic_json from_ubjson(detail::span_input_adapter&& i,
25537                                   const bool strict = true,
25538                                   const bool allow_exceptions = true)
25539     {
25540         basic_json result;
25541         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25542         auto ia = i.get();
25543         // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25544         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25545         return res ? result : basic_json(value_t::discarded);
25546     }
25547 
25548 
25549     /*!
25550     @brief Create a JSON value from an input in BSON format
25551 
25552     Deserializes a given input @a i to a JSON value using the BSON (Binary JSON)
25553     serialization format.
25554 
25555     The library maps BSON record types to JSON value types as follows:
25556 
25557     BSON type       | BSON marker byte | JSON value type
25558     --------------- | ---------------- | ---------------------------
25559     double          | 0x01             | number_float
25560     string          | 0x02             | string
25561     document        | 0x03             | object
25562     array           | 0x04             | array
25563     binary          | 0x05             | binary
25564     undefined       | 0x06             | still unsupported
25565     ObjectId        | 0x07             | still unsupported
25566     boolean         | 0x08             | boolean
25567     UTC Date-Time   | 0x09             | still unsupported
25568     null            | 0x0A             | null
25569     Regular Expr.   | 0x0B             | still unsupported
25570     DB Pointer      | 0x0C             | still unsupported
25571     JavaScript Code | 0x0D             | still unsupported
25572     Symbol          | 0x0E             | still unsupported
25573     JavaScript Code | 0x0F             | still unsupported
25574     int32           | 0x10             | number_integer
25575     Timestamp       | 0x11             | still unsupported
25576     128-bit decimal float | 0x13       | still unsupported
25577     Max Key         | 0x7F             | still unsupported
25578     Min Key         | 0xFF             | still unsupported
25579 
25580     @warning The mapping is **incomplete**. The unsupported mappings
25581              are indicated in the table above.
25582 
25583     @param[in] i  an input in BSON format convertible to an input adapter
25584     @param[in] strict  whether to expect the input to be consumed until EOF
25585                        (true by default)
25586     @param[in] allow_exceptions  whether to throw exceptions in case of a
25587     parse error (optional, true by default)
25588 
25589     @return deserialized JSON value; in case of a parse error and
25590             @a allow_exceptions set to `false`, the return value will be
25591             value_t::discarded.
25592 
25593     @throw parse_error.114 if an unsupported BSON record type is encountered
25594 
25595     @complexity Linear in the size of the input @a i.
25596 
25597     @liveexample{The example shows the deserialization of a byte vector in
25598     BSON format to a JSON value.,from_bson}
25599 
25600     @sa http://bsonspec.org/spec.html
25601     @sa see @ref to_bson(const basic_json&) for the analogous serialization
25602     @sa see @ref from_cbor(InputType&&, const bool, const bool, const cbor_tag_handler_t) for the
25603         related CBOR format
25604     @sa see @ref from_msgpack(InputType&&, const bool, const bool) for
25605         the related MessagePack format
25606     @sa see @ref from_ubjson(InputType&&, const bool, const bool) for the
25607         related UBJSON format
25608     */
25609     template<typename InputType>
25610     JSON_HEDLEY_WARN_UNUSED_RESULT
from_bson(InputType && i,const bool strict=true,const bool allow_exceptions=true)25611     static basic_json from_bson(InputType&& i,
25612                                 const bool strict = true,
25613                                 const bool allow_exceptions = true)
25614     {
25615         basic_json result;
25616         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25617         auto ia = detail::input_adapter(std::forward<InputType>(i));
25618         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25619         return res ? result : basic_json(value_t::discarded);
25620     }
25621 
25622     /*!
25623     @copydoc from_bson(InputType&&, const bool, const bool)
25624     */
25625     template<typename IteratorType>
25626     JSON_HEDLEY_WARN_UNUSED_RESULT
from_bson(IteratorType first,IteratorType last,const bool strict=true,const bool allow_exceptions=true)25627     static basic_json from_bson(IteratorType first, IteratorType last,
25628                                 const bool strict = true,
25629                                 const bool allow_exceptions = true)
25630     {
25631         basic_json result;
25632         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25633         auto ia = detail::input_adapter(std::move(first), std::move(last));
25634         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25635         return res ? result : basic_json(value_t::discarded);
25636     }
25637 
25638     template<typename T>
25639     JSON_HEDLEY_WARN_UNUSED_RESULT
25640     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)25641     static basic_json from_bson(const T* ptr, std::size_t len,
25642                                 const bool strict = true,
25643                                 const bool allow_exceptions = true)
25644     {
25645         return from_bson(ptr, ptr + len, strict, allow_exceptions);
25646     }
25647 
25648     JSON_HEDLEY_WARN_UNUSED_RESULT
25649     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)25650     static basic_json from_bson(detail::span_input_adapter&& i,
25651                                 const bool strict = true,
25652                                 const bool allow_exceptions = true)
25653     {
25654         basic_json result;
25655         detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25656         auto ia = i.get();
25657         // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25658         const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25659         return res ? result : basic_json(value_t::discarded);
25660     }
25661     /// @}
25662 
25663     //////////////////////////
25664     // JSON Pointer support //
25665     //////////////////////////
25666 
25667     /// @name JSON Pointer functions
25668     /// @{
25669 
25670     /*!
25671     @brief access specified element via JSON Pointer
25672 
25673     Uses a JSON pointer to retrieve a reference to the respective JSON value.
25674     No bound checking is performed. Similar to @ref operator[](const typename
25675     object_t::key_type&), `null` values are created in arrays and objects if
25676     necessary.
25677 
25678     In particular:
25679     - If the JSON pointer points to an object key that does not exist, it
25680       is created an filled with a `null` value before a reference to it
25681       is returned.
25682     - If the JSON pointer points to an array index that does not exist, it
25683       is created an filled with a `null` value before a reference to it
25684       is returned. All indices between the current maximum and the given
25685       index are also filled with `null`.
25686     - The special value `-` is treated as a synonym for the index past the
25687       end.
25688 
25689     @param[in] ptr  a JSON pointer
25690 
25691     @return reference to the element pointed to by @a ptr
25692 
25693     @complexity Constant.
25694 
25695     @throw parse_error.106   if an array index begins with '0'
25696     @throw parse_error.109   if an array index was not a number
25697     @throw out_of_range.404  if the JSON pointer can not be resolved
25698 
25699     @liveexample{The behavior is shown in the example.,operatorjson_pointer}
25700 
25701     @since version 2.0.0
25702     */
operator [](const json_pointer & ptr)25703     reference operator[](const json_pointer& ptr)
25704     {
25705         return ptr.get_unchecked(this);
25706     }
25707 
25708     /*!
25709     @brief access specified element via JSON Pointer
25710 
25711     Uses a JSON pointer to retrieve a reference to the respective JSON value.
25712     No bound checking is performed. The function does not change the JSON
25713     value; no `null` values are created. In particular, the special value
25714     `-` yields an exception.
25715 
25716     @param[in] ptr  JSON pointer to the desired element
25717 
25718     @return const reference to the element pointed to by @a ptr
25719 
25720     @complexity Constant.
25721 
25722     @throw parse_error.106   if an array index begins with '0'
25723     @throw parse_error.109   if an array index was not a number
25724     @throw out_of_range.402  if the array index '-' is used
25725     @throw out_of_range.404  if the JSON pointer can not be resolved
25726 
25727     @liveexample{The behavior is shown in the example.,operatorjson_pointer_const}
25728 
25729     @since version 2.0.0
25730     */
operator [](const json_pointer & ptr) const25731     const_reference operator[](const json_pointer& ptr) const
25732     {
25733         return ptr.get_unchecked(this);
25734     }
25735 
25736     /*!
25737     @brief access specified element via JSON Pointer
25738 
25739     Returns a reference to the element at with specified JSON pointer @a ptr,
25740     with bounds checking.
25741 
25742     @param[in] ptr  JSON pointer to the desired element
25743 
25744     @return reference to the element pointed to by @a ptr
25745 
25746     @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
25747     begins with '0'. See example below.
25748 
25749     @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
25750     is not a number. See example below.
25751 
25752     @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
25753     is out of range. See example below.
25754 
25755     @throw out_of_range.402 if the array index '-' is used in the passed JSON
25756     pointer @a ptr. As `at` provides checked access (and no elements are
25757     implicitly inserted), the index '-' is always invalid. See example below.
25758 
25759     @throw out_of_range.403 if the JSON pointer describes a key of an object
25760     which cannot be found. See example below.
25761 
25762     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
25763     See example below.
25764 
25765     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
25766     changes in the JSON value.
25767 
25768     @complexity Constant.
25769 
25770     @since version 2.0.0
25771 
25772     @liveexample{The behavior is shown in the example.,at_json_pointer}
25773     */
at(const json_pointer & ptr)25774     reference at(const json_pointer& ptr)
25775     {
25776         return ptr.get_checked(this);
25777     }
25778 
25779     /*!
25780     @brief access specified element via JSON Pointer
25781 
25782     Returns a const reference to the element at with specified JSON pointer @a
25783     ptr, with bounds checking.
25784 
25785     @param[in] ptr  JSON pointer to the desired element
25786 
25787     @return reference to the element pointed to by @a ptr
25788 
25789     @throw parse_error.106 if an array index in the passed JSON pointer @a ptr
25790     begins with '0'. See example below.
25791 
25792     @throw parse_error.109 if an array index in the passed JSON pointer @a ptr
25793     is not a number. See example below.
25794 
25795     @throw out_of_range.401 if an array index in the passed JSON pointer @a ptr
25796     is out of range. See example below.
25797 
25798     @throw out_of_range.402 if the array index '-' is used in the passed JSON
25799     pointer @a ptr. As `at` provides checked access (and no elements are
25800     implicitly inserted), the index '-' is always invalid. See example below.
25801 
25802     @throw out_of_range.403 if the JSON pointer describes a key of an object
25803     which cannot be found. See example below.
25804 
25805     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
25806     See example below.
25807 
25808     @exceptionsafety Strong guarantee: if an exception is thrown, there are no
25809     changes in the JSON value.
25810 
25811     @complexity Constant.
25812 
25813     @since version 2.0.0
25814 
25815     @liveexample{The behavior is shown in the example.,at_json_pointer_const}
25816     */
at(const json_pointer & ptr) const25817     const_reference at(const json_pointer& ptr) const
25818     {
25819         return ptr.get_checked(this);
25820     }
25821 
25822     /*!
25823     @brief return flattened JSON value
25824 
25825     The function creates a JSON object whose keys are JSON pointers (see [RFC
25826     6901](https://tools.ietf.org/html/rfc6901)) and whose values are all
25827     primitive. The original JSON value can be restored using the @ref
25828     unflatten() function.
25829 
25830     @return an object that maps JSON pointers to primitive values
25831 
25832     @note Empty objects and arrays are flattened to `null` and will not be
25833           reconstructed correctly by the @ref unflatten() function.
25834 
25835     @complexity Linear in the size the JSON value.
25836 
25837     @liveexample{The following code shows how a JSON object is flattened to an
25838     object whose keys consist of JSON pointers.,flatten}
25839 
25840     @sa see @ref unflatten() for the reverse function
25841 
25842     @since version 2.0.0
25843     */
flatten() const25844     basic_json flatten() const
25845     {
25846         basic_json result(value_t::object);
25847         json_pointer::flatten("", *this, result);
25848         return result;
25849     }
25850 
25851     /*!
25852     @brief unflatten a previously flattened JSON value
25853 
25854     The function restores the arbitrary nesting of a JSON value that has been
25855     flattened before using the @ref flatten() function. The JSON value must
25856     meet certain constraints:
25857     1. The value must be an object.
25858     2. The keys must be JSON pointers (see
25859        [RFC 6901](https://tools.ietf.org/html/rfc6901))
25860     3. The mapped values must be primitive JSON types.
25861 
25862     @return the original JSON from a flattened version
25863 
25864     @note Empty objects and arrays are flattened by @ref flatten() to `null`
25865           values and can not unflattened to their original type. Apart from
25866           this example, for a JSON value `j`, the following is always true:
25867           `j == j.flatten().unflatten()`.
25868 
25869     @complexity Linear in the size the JSON value.
25870 
25871     @throw type_error.314  if value is not an object
25872     @throw type_error.315  if object values are not primitive
25873 
25874     @liveexample{The following code shows how a flattened JSON object is
25875     unflattened into the original nested JSON object.,unflatten}
25876 
25877     @sa see @ref flatten() for the reverse function
25878 
25879     @since version 2.0.0
25880     */
unflatten() const25881     basic_json unflatten() const
25882     {
25883         return json_pointer::unflatten(*this);
25884     }
25885 
25886     /// @}
25887 
25888     //////////////////////////
25889     // JSON Patch functions //
25890     //////////////////////////
25891 
25892     /// @name JSON Patch functions
25893     /// @{
25894 
25895     /*!
25896     @brief applies a JSON patch
25897 
25898     [JSON Patch](http://jsonpatch.com) defines a JSON document structure for
25899     expressing a sequence of operations to apply to a JSON) document. With
25900     this function, a JSON Patch is applied to the current JSON value by
25901     executing all operations from the patch.
25902 
25903     @param[in] json_patch  JSON patch document
25904     @return patched document
25905 
25906     @note The application of a patch is atomic: Either all operations succeed
25907           and the patched document is returned or an exception is thrown. In
25908           any case, the original value is not changed: the patch is applied
25909           to a copy of the value.
25910 
25911     @throw parse_error.104 if the JSON patch does not consist of an array of
25912     objects
25913 
25914     @throw parse_error.105 if the JSON patch is malformed (e.g., mandatory
25915     attributes are missing); example: `"operation add must have member path"`
25916 
25917     @throw out_of_range.401 if an array index is out of range.
25918 
25919     @throw out_of_range.403 if a JSON pointer inside the patch could not be
25920     resolved successfully in the current JSON value; example: `"key baz not
25921     found"`
25922 
25923     @throw out_of_range.405 if JSON pointer has no parent ("add", "remove",
25924     "move")
25925 
25926     @throw other_error.501 if "test" operation was unsuccessful
25927 
25928     @complexity Linear in the size of the JSON value and the length of the
25929     JSON patch. As usually only a fraction of the JSON value is affected by
25930     the patch, the complexity can usually be neglected.
25931 
25932     @liveexample{The following code shows how a JSON patch is applied to a
25933     value.,patch}
25934 
25935     @sa see @ref diff -- create a JSON patch by comparing two JSON values
25936 
25937     @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
25938     @sa [RFC 6901 (JSON Pointer)](https://tools.ietf.org/html/rfc6901)
25939 
25940     @since version 2.0.0
25941     */
patch(const basic_json & json_patch) const25942     basic_json patch(const basic_json& json_patch) const
25943     {
25944         // make a working copy to apply the patch to
25945         basic_json result = *this;
25946 
25947         // the valid JSON Patch operations
25948         enum class patch_operations {add, remove, replace, move, copy, test, invalid};
25949 
25950         const auto get_op = [](const std::string & op)
25951         {
25952             if (op == "add")
25953             {
25954                 return patch_operations::add;
25955             }
25956             if (op == "remove")
25957             {
25958                 return patch_operations::remove;
25959             }
25960             if (op == "replace")
25961             {
25962                 return patch_operations::replace;
25963             }
25964             if (op == "move")
25965             {
25966                 return patch_operations::move;
25967             }
25968             if (op == "copy")
25969             {
25970                 return patch_operations::copy;
25971             }
25972             if (op == "test")
25973             {
25974                 return patch_operations::test;
25975             }
25976 
25977             return patch_operations::invalid;
25978         };
25979 
25980         // wrapper for "add" operation; add value at ptr
25981         const auto operation_add = [&result](json_pointer & ptr, basic_json val)
25982         {
25983             // adding to the root of the target document means replacing it
25984             if (ptr.empty())
25985             {
25986                 result = val;
25987                 return;
25988             }
25989 
25990             // make sure the top element of the pointer exists
25991             json_pointer top_pointer = ptr.top();
25992             if (top_pointer != ptr)
25993             {
25994                 result.at(top_pointer);
25995             }
25996 
25997             // get reference to parent of JSON pointer ptr
25998             const auto last_path = ptr.back();
25999             ptr.pop_back();
26000             basic_json& parent = result[ptr];
26001 
26002             switch (parent.m_type)
26003             {
26004                 case value_t::null:
26005                 case value_t::object:
26006                 {
26007                     // use operator[] to add value
26008                     parent[last_path] = val;
26009                     break;
26010                 }
26011 
26012                 case value_t::array:
26013                 {
26014                     if (last_path == "-")
26015                     {
26016                         // special case: append to back
26017                         parent.push_back(val);
26018                     }
26019                     else
26020                     {
26021                         const auto idx = json_pointer::array_index(last_path);
26022                         if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
26023                         {
26024                             // avoid undefined behavior
26025                             JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
26026                         }
26027 
26028                         // default case: insert add offset
26029                         parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
26030                     }
26031                     break;
26032                 }
26033 
26034                 // if there exists a parent it cannot be primitive
26035                 case value_t::string: // LCOV_EXCL_LINE
26036                 case value_t::boolean: // LCOV_EXCL_LINE
26037                 case value_t::number_integer: // LCOV_EXCL_LINE
26038                 case value_t::number_unsigned: // LCOV_EXCL_LINE
26039                 case value_t::number_float: // LCOV_EXCL_LINE
26040                 case value_t::binary: // LCOV_EXCL_LINE
26041                 case value_t::discarded: // LCOV_EXCL_LINE
26042                 default:            // LCOV_EXCL_LINE
26043                     JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
26044             }
26045         };
26046 
26047         // wrapper for "remove" operation; remove value at ptr
26048         const auto operation_remove = [this, &result](json_pointer & ptr)
26049         {
26050             // get reference to parent of JSON pointer ptr
26051             const auto last_path = ptr.back();
26052             ptr.pop_back();
26053             basic_json& parent = result.at(ptr);
26054 
26055             // remove child
26056             if (parent.is_object())
26057             {
26058                 // perform range check
26059                 auto it = parent.find(last_path);
26060                 if (JSON_HEDLEY_LIKELY(it != parent.end()))
26061                 {
26062                     parent.erase(it);
26063                 }
26064                 else
26065                 {
26066                     JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
26067                 }
26068             }
26069             else if (parent.is_array())
26070             {
26071                 // note erase performs range check
26072                 parent.erase(json_pointer::array_index(last_path));
26073             }
26074         };
26075 
26076         // type check: top level value must be an array
26077         if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
26078         {
26079             JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
26080         }
26081 
26082         // iterate and apply the operations
26083         for (const auto& val : json_patch)
26084         {
26085             // wrapper to get a value for an operation
26086             const auto get_value = [&val](const std::string & op,
26087                                           const std::string & member,
26088                                           bool string_type) -> basic_json &
26089             {
26090                 // find value
26091                 auto it = val.m_value.object->find(member);
26092 
26093                 // context-sensitive error message
26094                 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
26095 
26096                 // check if desired value is present
26097                 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
26098                 {
26099                     // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
26100                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
26101                 }
26102 
26103                 // check if result is of type string
26104                 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
26105                 {
26106                     // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
26107                     JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
26108                 }
26109 
26110                 // no error: return value
26111                 return it->second;
26112             };
26113 
26114             // type check: every element of the array must be an object
26115             if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
26116             {
26117                 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
26118             }
26119 
26120             // collect mandatory members
26121             const auto op = get_value("op", "op", true).template get<std::string>();
26122             const auto path = get_value(op, "path", true).template get<std::string>();
26123             json_pointer ptr(path);
26124 
26125             switch (get_op(op))
26126             {
26127                 case patch_operations::add:
26128                 {
26129                     operation_add(ptr, get_value("add", "value", false));
26130                     break;
26131                 }
26132 
26133                 case patch_operations::remove:
26134                 {
26135                     operation_remove(ptr);
26136                     break;
26137                 }
26138 
26139                 case patch_operations::replace:
26140                 {
26141                     // the "path" location must exist - use at()
26142                     result.at(ptr) = get_value("replace", "value", false);
26143                     break;
26144                 }
26145 
26146                 case patch_operations::move:
26147                 {
26148                     const auto from_path = get_value("move", "from", true).template get<std::string>();
26149                     json_pointer from_ptr(from_path);
26150 
26151                     // the "from" location must exist - use at()
26152                     basic_json v = result.at(from_ptr);
26153 
26154                     // The move operation is functionally identical to a
26155                     // "remove" operation on the "from" location, followed
26156                     // immediately by an "add" operation at the target
26157                     // location with the value that was just removed.
26158                     operation_remove(from_ptr);
26159                     operation_add(ptr, v);
26160                     break;
26161                 }
26162 
26163                 case patch_operations::copy:
26164                 {
26165                     const auto from_path = get_value("copy", "from", true).template get<std::string>();
26166                     const json_pointer from_ptr(from_path);
26167 
26168                     // the "from" location must exist - use at()
26169                     basic_json v = result.at(from_ptr);
26170 
26171                     // The copy is functionally identical to an "add"
26172                     // operation at the target location using the value
26173                     // specified in the "from" member.
26174                     operation_add(ptr, v);
26175                     break;
26176                 }
26177 
26178                 case patch_operations::test:
26179                 {
26180                     bool success = false;
26181                     JSON_TRY
26182                     {
26183                         // check if "value" matches the one at "path"
26184                         // the "path" location must exist - use at()
26185                         success = (result.at(ptr) == get_value("test", "value", false));
26186                     }
26187                     JSON_INTERNAL_CATCH (out_of_range&)
26188                     {
26189                         // ignore out of range errors: success remains false
26190                     }
26191 
26192                     // throw an exception if test fails
26193                     if (JSON_HEDLEY_UNLIKELY(!success))
26194                     {
26195                         JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
26196                     }
26197 
26198                     break;
26199                 }
26200 
26201                 case patch_operations::invalid:
26202                 default:
26203                 {
26204                     // op must be "add", "remove", "replace", "move", "copy", or
26205                     // "test"
26206                     JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
26207                 }
26208             }
26209         }
26210 
26211         return result;
26212     }
26213 
26214     /*!
26215     @brief creates a diff as a JSON patch
26216 
26217     Creates a [JSON Patch](http://jsonpatch.com) so that value @a source can
26218     be changed into the value @a target by calling @ref patch function.
26219 
26220     @invariant For two JSON values @a source and @a target, the following code
26221     yields always `true`:
26222     @code {.cpp}
26223     source.patch(diff(source, target)) == target;
26224     @endcode
26225 
26226     @note Currently, only `remove`, `add`, and `replace` operations are
26227           generated.
26228 
26229     @param[in] source  JSON value to compare from
26230     @param[in] target  JSON value to compare against
26231     @param[in] path    helper value to create JSON pointers
26232 
26233     @return a JSON patch to convert the @a source to @a target
26234 
26235     @complexity Linear in the lengths of @a source and @a target.
26236 
26237     @liveexample{The following code shows how a JSON patch is created as a
26238     diff for two JSON values.,diff}
26239 
26240     @sa see @ref patch -- apply a JSON patch
26241     @sa see @ref merge_patch -- apply a JSON Merge Patch
26242 
26243     @sa [RFC 6902 (JSON Patch)](https://tools.ietf.org/html/rfc6902)
26244 
26245     @since version 2.0.0
26246     */
26247     JSON_HEDLEY_WARN_UNUSED_RESULT
diff(const basic_json & source,const basic_json & target,const std::string & path="")26248     static basic_json diff(const basic_json& source, const basic_json& target,
26249                            const std::string& path = "")
26250     {
26251         // the patch
26252         basic_json result(value_t::array);
26253 
26254         // if the values are the same, return empty patch
26255         if (source == target)
26256         {
26257             return result;
26258         }
26259 
26260         if (source.type() != target.type())
26261         {
26262             // different types: replace value
26263             result.push_back(
26264             {
26265                 {"op", "replace"}, {"path", path}, {"value", target}
26266             });
26267             return result;
26268         }
26269 
26270         switch (source.type())
26271         {
26272             case value_t::array:
26273             {
26274                 // first pass: traverse common elements
26275                 std::size_t i = 0;
26276                 while (i < source.size() && i < target.size())
26277                 {
26278                     // recursive call to compare array values at index i
26279                     auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
26280                     result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26281                     ++i;
26282                 }
26283 
26284                 // i now reached the end of at least one array
26285                 // in a second pass, traverse the remaining elements
26286 
26287                 // remove my remaining elements
26288                 const auto end_index = static_cast<difference_type>(result.size());
26289                 while (i < source.size())
26290                 {
26291                     // add operations in reverse order to avoid invalid
26292                     // indices
26293                     result.insert(result.begin() + end_index, object(
26294                     {
26295                         {"op", "remove"},
26296                         {"path", path + "/" + std::to_string(i)}
26297                     }));
26298                     ++i;
26299                 }
26300 
26301                 // add other remaining elements
26302                 while (i < target.size())
26303                 {
26304                     result.push_back(
26305                     {
26306                         {"op", "add"},
26307                         {"path", path + "/-"},
26308                         {"value", target[i]}
26309                     });
26310                     ++i;
26311                 }
26312 
26313                 break;
26314             }
26315 
26316             case value_t::object:
26317             {
26318                 // first pass: traverse this object's elements
26319                 for (auto it = source.cbegin(); it != source.cend(); ++it)
26320                 {
26321                     // escape the key name to be used in a JSON patch
26322                     const auto path_key = path + "/" + detail::escape(it.key());
26323 
26324                     if (target.find(it.key()) != target.end())
26325                     {
26326                         // recursive call to compare object values at key it
26327                         auto temp_diff = diff(it.value(), target[it.key()], path_key);
26328                         result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26329                     }
26330                     else
26331                     {
26332                         // found a key that is not in o -> remove it
26333                         result.push_back(object(
26334                         {
26335                             {"op", "remove"}, {"path", path_key}
26336                         }));
26337                     }
26338                 }
26339 
26340                 // second pass: traverse other object's elements
26341                 for (auto it = target.cbegin(); it != target.cend(); ++it)
26342                 {
26343                     if (source.find(it.key()) == source.end())
26344                     {
26345                         // found a key that is not in this -> add it
26346                         const auto path_key = path + "/" + detail::escape(it.key());
26347                         result.push_back(
26348                         {
26349                             {"op", "add"}, {"path", path_key},
26350                             {"value", it.value()}
26351                         });
26352                     }
26353                 }
26354 
26355                 break;
26356             }
26357 
26358             case value_t::null:
26359             case value_t::string:
26360             case value_t::boolean:
26361             case value_t::number_integer:
26362             case value_t::number_unsigned:
26363             case value_t::number_float:
26364             case value_t::binary:
26365             case value_t::discarded:
26366             default:
26367             {
26368                 // both primitive type: replace value
26369                 result.push_back(
26370                 {
26371                     {"op", "replace"}, {"path", path}, {"value", target}
26372                 });
26373                 break;
26374             }
26375         }
26376 
26377         return result;
26378     }
26379 
26380     /// @}
26381 
26382     ////////////////////////////////
26383     // JSON Merge Patch functions //
26384     ////////////////////////////////
26385 
26386     /// @name JSON Merge Patch functions
26387     /// @{
26388 
26389     /*!
26390     @brief applies a JSON Merge Patch
26391 
26392     The merge patch format is primarily intended for use with the HTTP PATCH
26393     method as a means of describing a set of modifications to a target
26394     resource's content. This function applies a merge patch to the current
26395     JSON value.
26396 
26397     The function implements the following algorithm from Section 2 of
26398     [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396):
26399 
26400     ```
26401     define MergePatch(Target, Patch):
26402       if Patch is an Object:
26403         if Target is not an Object:
26404           Target = {} // Ignore the contents and set it to an empty Object
26405         for each Name/Value pair in Patch:
26406           if Value is null:
26407             if Name exists in Target:
26408               remove the Name/Value pair from Target
26409           else:
26410             Target[Name] = MergePatch(Target[Name], Value)
26411         return Target
26412       else:
26413         return Patch
26414     ```
26415 
26416     Thereby, `Target` is the current object; that is, the patch is applied to
26417     the current value.
26418 
26419     @param[in] apply_patch  the patch to apply
26420 
26421     @complexity Linear in the lengths of @a patch.
26422 
26423     @liveexample{The following code shows how a JSON Merge Patch is applied to
26424     a JSON document.,merge_patch}
26425 
26426     @sa see @ref patch -- apply a JSON patch
26427     @sa [RFC 7396 (JSON Merge Patch)](https://tools.ietf.org/html/rfc7396)
26428 
26429     @since version 3.0.0
26430     */
merge_patch(const basic_json & apply_patch)26431     void merge_patch(const basic_json& apply_patch)
26432     {
26433         if (apply_patch.is_object())
26434         {
26435             if (!is_object())
26436             {
26437                 *this = object();
26438             }
26439             for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
26440             {
26441                 if (it.value().is_null())
26442                 {
26443                     erase(it.key());
26444                 }
26445                 else
26446                 {
26447                     operator[](it.key()).merge_patch(it.value());
26448                 }
26449             }
26450         }
26451         else
26452         {
26453             *this = apply_patch;
26454         }
26455     }
26456 
26457     /// @}
26458 };
26459 
26460 /*!
26461 @brief user-defined to_string function for JSON values
26462 
26463 This function implements a user-defined to_string  for JSON objects.
26464 
26465 @param[in] j  a JSON object
26466 @return a std::string object
26467 */
26468 
26469 NLOHMANN_BASIC_JSON_TPL_DECLARATION
to_string(const NLOHMANN_BASIC_JSON_TPL & j)26470 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
26471 {
26472     return j.dump();
26473 }
26474 } // namespace nlohmann
26475 
26476 ///////////////////////
26477 // nonmember support //
26478 ///////////////////////
26479 
26480 // specialization of std::swap, and std::hash
26481 namespace std
26482 {
26483 
26484 /// hash value for JSON objects
26485 template<>
26486 struct hash<nlohmann::json>
26487 {
26488     /*!
26489     @brief return a hash value for a JSON object
26490 
26491     @since version 1.0.0
26492     */
operator ()std::hash26493     std::size_t operator()(const nlohmann::json& j) const
26494     {
26495         return nlohmann::detail::hash(j);
26496     }
26497 };
26498 
26499 /// specialization for std::less<value_t>
26500 /// @note: do not remove the space after '<',
26501 ///        see https://github.com/nlohmann/json/pull/679
26502 template<>
26503 struct less<::nlohmann::detail::value_t>
26504 {
26505     /*!
26506     @brief compare two value_t enum values
26507     @since version 3.0.0
26508     */
operator ()std::less26509     bool operator()(nlohmann::detail::value_t lhs,
26510                     nlohmann::detail::value_t rhs) const noexcept
26511     {
26512         return nlohmann::detail::operator<(lhs, rhs);
26513     }
26514 };
26515 
26516 // C++20 prohibit function specialization in the std namespace.
26517 #ifndef JSON_HAS_CPP_20
26518 
26519 /*!
26520 @brief exchanges the values of two JSON objects
26521 
26522 @since version 1.0.0
26523 */
26524 template<>
swap(nlohmann::json & j1,nlohmann::json & j2)26525 inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
26526     is_nothrow_move_constructible<nlohmann::json>::value&&  // NOLINT(misc-redundant-expression)
26527     is_nothrow_move_assignable<nlohmann::json>::value
26528                               )
26529 {
26530     j1.swap(j2);
26531 }
26532 
26533 #endif
26534 
26535 } // namespace std
26536 
26537 /*!
26538 @brief user-defined string literal for JSON values
26539 
26540 This operator implements a user-defined string literal for JSON objects. It
26541 can be used by adding `"_json"` to a string literal and returns a JSON object
26542 if no parse error occurred.
26543 
26544 @param[in] s  a string representation of a JSON object
26545 @param[in] n  the length of string @a s
26546 @return a JSON object
26547 
26548 @since version 1.0.0
26549 */
26550 JSON_HEDLEY_NON_NULL(1)
operator ""_json(const char * s,std::size_t n)26551 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
26552 {
26553     return nlohmann::json::parse(s, s + n);
26554 }
26555 
26556 /*!
26557 @brief user-defined string literal for JSON pointer
26558 
26559 This operator implements a user-defined string literal for JSON Pointers. It
26560 can be used by adding `"_json_pointer"` to a string literal and returns a JSON pointer
26561 object if no parse error occurred.
26562 
26563 @param[in] s  a string representation of a JSON Pointer
26564 @param[in] n  the length of string @a s
26565 @return a JSON pointer object
26566 
26567 @since version 2.0.0
26568 */
26569 JSON_HEDLEY_NON_NULL(1)
operator ""_json_pointer(const char * s,std::size_t n)26570 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
26571 {
26572     return nlohmann::json::json_pointer(std::string(s, n));
26573 }
26574 
26575 // #include <nlohmann/detail/macro_unscope.hpp>
26576 
26577 
26578 // restore clang diagnostic settings
26579 #if defined(__clang__)
26580     #pragma clang diagnostic pop
26581 #endif
26582 
26583 // clean up
26584 #undef JSON_ASSERT
26585 #undef JSON_INTERNAL_CATCH
26586 #undef JSON_CATCH
26587 #undef JSON_THROW
26588 #undef JSON_TRY
26589 #undef JSON_PRIVATE_UNLESS_TESTED
26590 #undef JSON_HAS_CPP_11
26591 #undef JSON_HAS_CPP_14
26592 #undef JSON_HAS_CPP_17
26593 #undef JSON_HAS_CPP_20
26594 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
26595 #undef NLOHMANN_BASIC_JSON_TPL
26596 #undef JSON_EXPLICIT
26597 #undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
26598 
26599 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
26600 
26601 
26602 #undef JSON_HEDLEY_ALWAYS_INLINE
26603 #undef JSON_HEDLEY_ARM_VERSION
26604 #undef JSON_HEDLEY_ARM_VERSION_CHECK
26605 #undef JSON_HEDLEY_ARRAY_PARAM
26606 #undef JSON_HEDLEY_ASSUME
26607 #undef JSON_HEDLEY_BEGIN_C_DECLS
26608 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
26609 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
26610 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
26611 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
26612 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
26613 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
26614 #undef JSON_HEDLEY_CLANG_HAS_WARNING
26615 #undef JSON_HEDLEY_COMPCERT_VERSION
26616 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
26617 #undef JSON_HEDLEY_CONCAT
26618 #undef JSON_HEDLEY_CONCAT3
26619 #undef JSON_HEDLEY_CONCAT3_EX
26620 #undef JSON_HEDLEY_CONCAT_EX
26621 #undef JSON_HEDLEY_CONST
26622 #undef JSON_HEDLEY_CONSTEXPR
26623 #undef JSON_HEDLEY_CONST_CAST
26624 #undef JSON_HEDLEY_CPP_CAST
26625 #undef JSON_HEDLEY_CRAY_VERSION
26626 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
26627 #undef JSON_HEDLEY_C_DECL
26628 #undef JSON_HEDLEY_DEPRECATED
26629 #undef JSON_HEDLEY_DEPRECATED_FOR
26630 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
26631 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
26632 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
26633 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
26634 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
26635 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
26636 #undef JSON_HEDLEY_DIAGNOSTIC_POP
26637 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
26638 #undef JSON_HEDLEY_DMC_VERSION
26639 #undef JSON_HEDLEY_DMC_VERSION_CHECK
26640 #undef JSON_HEDLEY_EMPTY_BASES
26641 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
26642 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
26643 #undef JSON_HEDLEY_END_C_DECLS
26644 #undef JSON_HEDLEY_FLAGS
26645 #undef JSON_HEDLEY_FLAGS_CAST
26646 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
26647 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
26648 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
26649 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
26650 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
26651 #undef JSON_HEDLEY_GCC_HAS_FEATURE
26652 #undef JSON_HEDLEY_GCC_HAS_WARNING
26653 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
26654 #undef JSON_HEDLEY_GCC_VERSION
26655 #undef JSON_HEDLEY_GCC_VERSION_CHECK
26656 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
26657 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
26658 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
26659 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
26660 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
26661 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
26662 #undef JSON_HEDLEY_GNUC_HAS_WARNING
26663 #undef JSON_HEDLEY_GNUC_VERSION
26664 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
26665 #undef JSON_HEDLEY_HAS_ATTRIBUTE
26666 #undef JSON_HEDLEY_HAS_BUILTIN
26667 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
26668 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
26669 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
26670 #undef JSON_HEDLEY_HAS_EXTENSION
26671 #undef JSON_HEDLEY_HAS_FEATURE
26672 #undef JSON_HEDLEY_HAS_WARNING
26673 #undef JSON_HEDLEY_IAR_VERSION
26674 #undef JSON_HEDLEY_IAR_VERSION_CHECK
26675 #undef JSON_HEDLEY_IBM_VERSION
26676 #undef JSON_HEDLEY_IBM_VERSION_CHECK
26677 #undef JSON_HEDLEY_IMPORT
26678 #undef JSON_HEDLEY_INLINE
26679 #undef JSON_HEDLEY_INTEL_CL_VERSION
26680 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
26681 #undef JSON_HEDLEY_INTEL_VERSION
26682 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
26683 #undef JSON_HEDLEY_IS_CONSTANT
26684 #undef JSON_HEDLEY_IS_CONSTEXPR_
26685 #undef JSON_HEDLEY_LIKELY
26686 #undef JSON_HEDLEY_MALLOC
26687 #undef JSON_HEDLEY_MCST_LCC_VERSION
26688 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
26689 #undef JSON_HEDLEY_MESSAGE
26690 #undef JSON_HEDLEY_MSVC_VERSION
26691 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
26692 #undef JSON_HEDLEY_NEVER_INLINE
26693 #undef JSON_HEDLEY_NON_NULL
26694 #undef JSON_HEDLEY_NO_ESCAPE
26695 #undef JSON_HEDLEY_NO_RETURN
26696 #undef JSON_HEDLEY_NO_THROW
26697 #undef JSON_HEDLEY_NULL
26698 #undef JSON_HEDLEY_PELLES_VERSION
26699 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
26700 #undef JSON_HEDLEY_PGI_VERSION
26701 #undef JSON_HEDLEY_PGI_VERSION_CHECK
26702 #undef JSON_HEDLEY_PREDICT
26703 #undef JSON_HEDLEY_PRINTF_FORMAT
26704 #undef JSON_HEDLEY_PRIVATE
26705 #undef JSON_HEDLEY_PUBLIC
26706 #undef JSON_HEDLEY_PURE
26707 #undef JSON_HEDLEY_REINTERPRET_CAST
26708 #undef JSON_HEDLEY_REQUIRE
26709 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
26710 #undef JSON_HEDLEY_REQUIRE_MSG
26711 #undef JSON_HEDLEY_RESTRICT
26712 #undef JSON_HEDLEY_RETURNS_NON_NULL
26713 #undef JSON_HEDLEY_SENTINEL
26714 #undef JSON_HEDLEY_STATIC_ASSERT
26715 #undef JSON_HEDLEY_STATIC_CAST
26716 #undef JSON_HEDLEY_STRINGIFY
26717 #undef JSON_HEDLEY_STRINGIFY_EX
26718 #undef JSON_HEDLEY_SUNPRO_VERSION
26719 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
26720 #undef JSON_HEDLEY_TINYC_VERSION
26721 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
26722 #undef JSON_HEDLEY_TI_ARMCL_VERSION
26723 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
26724 #undef JSON_HEDLEY_TI_CL2000_VERSION
26725 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
26726 #undef JSON_HEDLEY_TI_CL430_VERSION
26727 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
26728 #undef JSON_HEDLEY_TI_CL6X_VERSION
26729 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
26730 #undef JSON_HEDLEY_TI_CL7X_VERSION
26731 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
26732 #undef JSON_HEDLEY_TI_CLPRU_VERSION
26733 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
26734 #undef JSON_HEDLEY_TI_VERSION
26735 #undef JSON_HEDLEY_TI_VERSION_CHECK
26736 #undef JSON_HEDLEY_UNAVAILABLE
26737 #undef JSON_HEDLEY_UNLIKELY
26738 #undef JSON_HEDLEY_UNPREDICTABLE
26739 #undef JSON_HEDLEY_UNREACHABLE
26740 #undef JSON_HEDLEY_UNREACHABLE_RETURN
26741 #undef JSON_HEDLEY_VERSION
26742 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
26743 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
26744 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
26745 #undef JSON_HEDLEY_VERSION_ENCODE
26746 #undef JSON_HEDLEY_WARNING
26747 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
26748 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
26749 #undef JSON_HEDLEY_FALL_THROUGH
26750 
26751 
26752 
26753 #endif  // INCLUDE_NLOHMANN_JSON_HPP_
26754