Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
json.hpp
Go to the documentation of this file.
1/*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4| | |__ | | | | | | version 3.10.5
5|_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8SPDX-License-Identifier: MIT
9Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
10
11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal
13in the Software without restriction, including without limitation the rights
14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15copies of the Software, and to permit persons to whom the Software is
16furnished to do so, subject to the following conditions:
17
18The above copyright notice and this permission notice shall be included in all
19copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27SOFTWARE.
28*/
29
30/****************************************************************************\
31 * Note on documentation: The source files contain links to the online *
32 * documentation of the public API at https://json.nlohmann.me. This URL *
33 * contains the most recent documentation and should also be applicable to *
34 * previous versions; documentation for deprecated functions is not *
35 * removed, but marked deprecated. See "Generate documentation" section in *
36 * file doc/README.md. *
37\****************************************************************************/
38
39#ifndef INCLUDE_NLOHMANN_JSON_HPP_
40#define INCLUDE_NLOHMANN_JSON_HPP_
41
42#define NLOHMANN_JSON_VERSION_MAJOR 3
43#define NLOHMANN_JSON_VERSION_MINOR 10
44#define NLOHMANN_JSON_VERSION_PATCH 5
45
46#include <algorithm> // all_of, find, for_each
47#include <cstddef> // nullptr_t, ptrdiff_t, size_t
48#include <functional> // hash, less
49#include <initializer_list> // initializer_list
50#ifndef JSON_NO_IO
51 #include <iosfwd> // istream, ostream
52#endif // JSON_NO_IO
53#include <iterator> // random_access_iterator_tag
54#include <memory> // unique_ptr
55#include <numeric> // accumulate
56#include <string> // string, stoi, to_string
57#include <utility> // declval, forward, move, pair, swap
58#include <vector> // vector
59
60// #include <nlohmann/adl_serializer.hpp>
61
62
63#include <type_traits>
64#include <utility>
65
66// #include <nlohmann/detail/conversions/from_json.hpp>
67
68
69#include <algorithm> // transform
70#include <array> // array
71#include <forward_list> // forward_list
72#include <iterator> // inserter, front_inserter, end
73#include <map> // map
74#include <string> // string
75#include <tuple> // tuple, make_tuple
76#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
77#include <unordered_map> // unordered_map
78#include <utility> // pair, declval
79#include <valarray> // valarray
80
81// #include <nlohmann/detail/exceptions.hpp>
82
83
84#include <exception> // exception
85#include <stdexcept> // runtime_error
86#include <string> // to_string
87#include <vector> // vector
88
89// #include <nlohmann/detail/value_t.hpp>
90
91
92#include <array> // array
93#include <cstddef> // size_t
94#include <cstdint> // uint8_t
95#include <string> // string
96
97namespace nlohmann
98{
99namespace detail
100{
102// JSON type enumeration //
104
129enum class value_t : std::uint8_t
130{
131 null,
132 object,
133 array,
134 string,
135 boolean,
139 binary,
140 discarded
141};
142
156inline bool operator<(const value_t lhs, const value_t rhs) noexcept
157{
158 static constexpr std::array<std::uint8_t, 9> order = {{
159 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
160 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
161 6 /* binary */
162 }
163 };
164
165 const auto l_index = static_cast<std::size_t>(lhs);
166 const auto r_index = static_cast<std::size_t>(rhs);
167 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
168}
169} // namespace detail
170} // namespace nlohmann
171
172// #include <nlohmann/detail/string_escape.hpp>
173
174
175#include <string>
176// #include <nlohmann/detail/macro_scope.hpp>
177
178
179#include <utility> // declval, pair
180// #include <nlohmann/thirdparty/hedley/hedley.hpp>
181
182
183/* Hedley - https://nemequ.github.io/hedley
184 * Created by Evan Nemerson <evan@nemerson.com>
185 *
186 * To the extent possible under law, the author(s) have dedicated all
187 * copyright and related and neighboring rights to this software to
188 * the public domain worldwide. This software is distributed without
189 * any warranty.
190 *
191 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
192 * SPDX-License-Identifier: CC0-1.0
193 */
194
195#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
196#if defined(JSON_HEDLEY_VERSION)
197 #undef JSON_HEDLEY_VERSION
198#endif
199#define JSON_HEDLEY_VERSION 15
200
201#if defined(JSON_HEDLEY_STRINGIFY_EX)
202 #undef JSON_HEDLEY_STRINGIFY_EX
203#endif
204#define JSON_HEDLEY_STRINGIFY_EX(x) #x
205
206#if defined(JSON_HEDLEY_STRINGIFY)
207 #undef JSON_HEDLEY_STRINGIFY
208#endif
209#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
210
211#if defined(JSON_HEDLEY_CONCAT_EX)
212 #undef JSON_HEDLEY_CONCAT_EX
213#endif
214#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
215
216#if defined(JSON_HEDLEY_CONCAT)
217 #undef JSON_HEDLEY_CONCAT
218#endif
219#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
220
221#if defined(JSON_HEDLEY_CONCAT3_EX)
222 #undef JSON_HEDLEY_CONCAT3_EX
223#endif
224#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
225
226#if defined(JSON_HEDLEY_CONCAT3)
227 #undef JSON_HEDLEY_CONCAT3
228#endif
229#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
230
231#if defined(JSON_HEDLEY_VERSION_ENCODE)
232 #undef JSON_HEDLEY_VERSION_ENCODE
233#endif
234#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
235
236#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
237 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
238#endif
239#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
240
241#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
242 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
243#endif
244#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
245
246#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
247 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
248#endif
249#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
250
251#if defined(JSON_HEDLEY_GNUC_VERSION)
252 #undef JSON_HEDLEY_GNUC_VERSION
253#endif
254#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
255 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
256#elif defined(__GNUC__)
257 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
258#endif
259
260#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
261 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
262#endif
263#if defined(JSON_HEDLEY_GNUC_VERSION)
264 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
265#else
266 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
267#endif
268
269#if defined(JSON_HEDLEY_MSVC_VERSION)
270 #undef JSON_HEDLEY_MSVC_VERSION
271#endif
272#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
273 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
274#elif defined(_MSC_FULL_VER) && !defined(__ICL)
275 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
276#elif defined(_MSC_VER) && !defined(__ICL)
277 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
278#endif
279
280#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
281 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
282#endif
283#if !defined(JSON_HEDLEY_MSVC_VERSION)
284 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
285#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
286 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
287#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
288 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
289#else
290 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
291#endif
292
293#if defined(JSON_HEDLEY_INTEL_VERSION)
294 #undef JSON_HEDLEY_INTEL_VERSION
295#endif
296#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
297 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
298#elif defined(__INTEL_COMPILER) && !defined(__ICL)
299 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
300#endif
301
302#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
303 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
304#endif
305#if defined(JSON_HEDLEY_INTEL_VERSION)
306 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
307#else
308 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
309#endif
310
311#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
312 #undef JSON_HEDLEY_INTEL_CL_VERSION
313#endif
314#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
315 #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
316#endif
317
318#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
319 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
320#endif
321#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
322 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
323#else
324 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
325#endif
326
327#if defined(JSON_HEDLEY_PGI_VERSION)
328 #undef JSON_HEDLEY_PGI_VERSION
329#endif
330#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
331 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
332#endif
333
334#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
335 #undef JSON_HEDLEY_PGI_VERSION_CHECK
336#endif
337#if defined(JSON_HEDLEY_PGI_VERSION)
338 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
339#else
340 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
341#endif
342
343#if defined(JSON_HEDLEY_SUNPRO_VERSION)
344 #undef JSON_HEDLEY_SUNPRO_VERSION
345#endif
346#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
347 #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)
348#elif defined(__SUNPRO_C)
349 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
350#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
351 #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)
352#elif defined(__SUNPRO_CC)
353 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
354#endif
355
356#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
357 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
358#endif
359#if defined(JSON_HEDLEY_SUNPRO_VERSION)
360 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
361#else
362 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
363#endif
364
365#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
366 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
367#endif
368#if defined(__EMSCRIPTEN__)
369 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
370#endif
371
372#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
373 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
374#endif
375#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
376 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
377#else
378 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
379#endif
380
381#if defined(JSON_HEDLEY_ARM_VERSION)
382 #undef JSON_HEDLEY_ARM_VERSION
383#endif
384#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
385 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
386#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
387 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
388#endif
389
390#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
391 #undef JSON_HEDLEY_ARM_VERSION_CHECK
392#endif
393#if defined(JSON_HEDLEY_ARM_VERSION)
394 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
395#else
396 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
397#endif
398
399#if defined(JSON_HEDLEY_IBM_VERSION)
400 #undef JSON_HEDLEY_IBM_VERSION
401#endif
402#if defined(__ibmxl__)
403 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
404#elif defined(__xlC__) && defined(__xlC_ver__)
405 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
406#elif defined(__xlC__)
407 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
408#endif
409
410#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
411 #undef JSON_HEDLEY_IBM_VERSION_CHECK
412#endif
413#if defined(JSON_HEDLEY_IBM_VERSION)
414 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
415#else
416 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
417#endif
418
419#if defined(JSON_HEDLEY_TI_VERSION)
420 #undef JSON_HEDLEY_TI_VERSION
421#endif
422#if \
423 defined(__TI_COMPILER_VERSION__) && \
424 ( \
425 defined(__TMS470__) || defined(__TI_ARM__) || \
426 defined(__MSP430__) || \
427 defined(__TMS320C2000__) \
428 )
429#if (__TI_COMPILER_VERSION__ >= 16000000)
430 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
431#endif
432#endif
433
434#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
435 #undef JSON_HEDLEY_TI_VERSION_CHECK
436#endif
437#if defined(JSON_HEDLEY_TI_VERSION)
438 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
439#else
440 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
441#endif
442
443#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
444 #undef JSON_HEDLEY_TI_CL2000_VERSION
445#endif
446#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
447 #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
448#endif
449
450#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
451 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
452#endif
453#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
454 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
455#else
456 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
457#endif
458
459#if defined(JSON_HEDLEY_TI_CL430_VERSION)
460 #undef JSON_HEDLEY_TI_CL430_VERSION
461#endif
462#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
463 #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
464#endif
465
466#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
467 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
468#endif
469#if defined(JSON_HEDLEY_TI_CL430_VERSION)
470 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
471#else
472 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
473#endif
474
475#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
476 #undef JSON_HEDLEY_TI_ARMCL_VERSION
477#endif
478#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
479 #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
480#endif
481
482#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
483 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
484#endif
485#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
486 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
487#else
488 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
489#endif
490
491#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
492 #undef JSON_HEDLEY_TI_CL6X_VERSION
493#endif
494#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
495 #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
496#endif
497
498#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
499 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
500#endif
501#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
502 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
503#else
504 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
505#endif
506
507#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
508 #undef JSON_HEDLEY_TI_CL7X_VERSION
509#endif
510#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
511 #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
512#endif
513
514#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
515 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
516#endif
517#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
518 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
519#else
520 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
521#endif
522
523#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
524 #undef JSON_HEDLEY_TI_CLPRU_VERSION
525#endif
526#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
527 #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
528#endif
529
530#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
531 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
532#endif
533#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
534 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
535#else
536 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
537#endif
538
539#if defined(JSON_HEDLEY_CRAY_VERSION)
540 #undef JSON_HEDLEY_CRAY_VERSION
541#endif
542#if defined(_CRAYC)
543 #if defined(_RELEASE_PATCHLEVEL)
544 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
545 #else
546 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
547 #endif
548#endif
549
550#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
551 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
552#endif
553#if defined(JSON_HEDLEY_CRAY_VERSION)
554 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
555#else
556 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
557#endif
558
559#if defined(JSON_HEDLEY_IAR_VERSION)
560 #undef JSON_HEDLEY_IAR_VERSION
561#endif
562#if defined(__IAR_SYSTEMS_ICC__)
563 #if __VER__ > 1000
564 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
565 #else
566 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
567 #endif
568#endif
569
570#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
571 #undef JSON_HEDLEY_IAR_VERSION_CHECK
572#endif
573#if defined(JSON_HEDLEY_IAR_VERSION)
574 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
575#else
576 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
577#endif
578
579#if defined(JSON_HEDLEY_TINYC_VERSION)
580 #undef JSON_HEDLEY_TINYC_VERSION
581#endif
582#if defined(__TINYC__)
583 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
584#endif
585
586#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
587 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
588#endif
589#if defined(JSON_HEDLEY_TINYC_VERSION)
590 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
591#else
592 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
593#endif
594
595#if defined(JSON_HEDLEY_DMC_VERSION)
596 #undef JSON_HEDLEY_DMC_VERSION
597#endif
598#if defined(__DMC__)
599 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
600#endif
601
602#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
603 #undef JSON_HEDLEY_DMC_VERSION_CHECK
604#endif
605#if defined(JSON_HEDLEY_DMC_VERSION)
606 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
607#else
608 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
609#endif
610
611#if defined(JSON_HEDLEY_COMPCERT_VERSION)
612 #undef JSON_HEDLEY_COMPCERT_VERSION
613#endif
614#if defined(__COMPCERT_VERSION__)
615 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
616#endif
617
618#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
619 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
620#endif
621#if defined(JSON_HEDLEY_COMPCERT_VERSION)
622 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
623#else
624 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
625#endif
626
627#if defined(JSON_HEDLEY_PELLES_VERSION)
628 #undef JSON_HEDLEY_PELLES_VERSION
629#endif
630#if defined(__POCC__)
631 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
632#endif
633
634#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
635 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
636#endif
637#if defined(JSON_HEDLEY_PELLES_VERSION)
638 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
639#else
640 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
641#endif
642
643#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
644 #undef JSON_HEDLEY_MCST_LCC_VERSION
645#endif
646#if defined(__LCC__) && defined(__LCC_MINOR__)
647 #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
648#endif
649
650#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
651 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
652#endif
653#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
654 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
655#else
656 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
657#endif
658
659#if defined(JSON_HEDLEY_GCC_VERSION)
660 #undef JSON_HEDLEY_GCC_VERSION
661#endif
662#if \
663 defined(JSON_HEDLEY_GNUC_VERSION) && \
664 !defined(__clang__) && \
665 !defined(JSON_HEDLEY_INTEL_VERSION) && \
666 !defined(JSON_HEDLEY_PGI_VERSION) && \
667 !defined(JSON_HEDLEY_ARM_VERSION) && \
668 !defined(JSON_HEDLEY_CRAY_VERSION) && \
669 !defined(JSON_HEDLEY_TI_VERSION) && \
670 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
671 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
672 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
673 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
674 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
675 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
676 !defined(__COMPCERT__) && \
677 !defined(JSON_HEDLEY_MCST_LCC_VERSION)
678 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
679#endif
680
681#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
682 #undef JSON_HEDLEY_GCC_VERSION_CHECK
683#endif
684#if defined(JSON_HEDLEY_GCC_VERSION)
685 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
686#else
687 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
688#endif
689
690#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
691 #undef JSON_HEDLEY_HAS_ATTRIBUTE
692#endif
693#if \
694 defined(__has_attribute) && \
695 ( \
696 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
697 )
698# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
699#else
700# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
701#endif
702
703#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
704 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
705#endif
706#if defined(__has_attribute)
707 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
708#else
709 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
710#endif
711
712#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
713 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
714#endif
715#if defined(__has_attribute)
716 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
717#else
718 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
719#endif
720
721#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
722 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
723#endif
724#if \
725 defined(__has_cpp_attribute) && \
726 defined(__cplusplus) && \
727 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
728 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
729#else
730 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
731#endif
732
733#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
734 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
735#endif
736#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
737 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
738#elif \
739 !defined(JSON_HEDLEY_PGI_VERSION) && \
740 !defined(JSON_HEDLEY_IAR_VERSION) && \
741 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
742 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
743 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
744#else
745 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
746#endif
747
748#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
749 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
750#endif
751#if defined(__has_cpp_attribute) && defined(__cplusplus)
752 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
753#else
754 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
755#endif
756
757#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
758 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
759#endif
760#if defined(__has_cpp_attribute) && defined(__cplusplus)
761 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
762#else
763 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
764#endif
765
766#if defined(JSON_HEDLEY_HAS_BUILTIN)
767 #undef JSON_HEDLEY_HAS_BUILTIN
768#endif
769#if defined(__has_builtin)
770 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
771#else
772 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
773#endif
774
775#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
776 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
777#endif
778#if defined(__has_builtin)
779 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
780#else
781 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
782#endif
783
784#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
785 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
786#endif
787#if defined(__has_builtin)
788 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
789#else
790 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
791#endif
792
793#if defined(JSON_HEDLEY_HAS_FEATURE)
794 #undef JSON_HEDLEY_HAS_FEATURE
795#endif
796#if defined(__has_feature)
797 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
798#else
799 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
800#endif
801
802#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
803 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
804#endif
805#if defined(__has_feature)
806 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
807#else
808 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
809#endif
810
811#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
812 #undef JSON_HEDLEY_GCC_HAS_FEATURE
813#endif
814#if defined(__has_feature)
815 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
816#else
817 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
818#endif
819
820#if defined(JSON_HEDLEY_HAS_EXTENSION)
821 #undef JSON_HEDLEY_HAS_EXTENSION
822#endif
823#if defined(__has_extension)
824 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
825#else
826 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
827#endif
828
829#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
830 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
831#endif
832#if defined(__has_extension)
833 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
834#else
835 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
836#endif
837
838#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
839 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
840#endif
841#if defined(__has_extension)
842 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
843#else
844 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
845#endif
846
847#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
848 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
849#endif
850#if defined(__has_declspec_attribute)
851 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
852#else
853 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
854#endif
855
856#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
857 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
858#endif
859#if defined(__has_declspec_attribute)
860 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
861#else
862 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
863#endif
864
865#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
866 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
867#endif
868#if defined(__has_declspec_attribute)
869 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
870#else
871 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
872#endif
873
874#if defined(JSON_HEDLEY_HAS_WARNING)
875 #undef JSON_HEDLEY_HAS_WARNING
876#endif
877#if defined(__has_warning)
878 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
879#else
880 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
881#endif
882
883#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
884 #undef JSON_HEDLEY_GNUC_HAS_WARNING
885#endif
886#if defined(__has_warning)
887 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
888#else
889 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
890#endif
891
892#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
893 #undef JSON_HEDLEY_GCC_HAS_WARNING
894#endif
895#if defined(__has_warning)
896 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
897#else
898 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
899#endif
900
901#if \
902 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
903 defined(__clang__) || \
904 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
905 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
906 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
907 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
908 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
909 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
910 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
911 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
912 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
913 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
914 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
915 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
916 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
917 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
918 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
919 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
920 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
921#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
922 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
923#else
924 #define JSON_HEDLEY_PRAGMA(value)
925#endif
926
927#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
928 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
929#endif
930#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
931 #undef JSON_HEDLEY_DIAGNOSTIC_POP
932#endif
933#if defined(__clang__)
934 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
935 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
936#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
937 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
938 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
939#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
940 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
941 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
942#elif \
943 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
944 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
945 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
946 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
947#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
948 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
949 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
950#elif \
951 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
952 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
953 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
954 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
955 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
956 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
957 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
958 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
959#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
960 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
961 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
962#else
963 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
964 #define JSON_HEDLEY_DIAGNOSTIC_POP
965#endif
966
967/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
968 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
969#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
970 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
971#endif
972#if defined(__cplusplus)
973# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
974# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
975# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
976# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
977 JSON_HEDLEY_DIAGNOSTIC_PUSH \
978 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
979 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
980 _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
981 xpr \
982 JSON_HEDLEY_DIAGNOSTIC_POP
983# else
984# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
985 JSON_HEDLEY_DIAGNOSTIC_PUSH \
986 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
987 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
988 xpr \
989 JSON_HEDLEY_DIAGNOSTIC_POP
990# endif
991# else
992# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
993 JSON_HEDLEY_DIAGNOSTIC_PUSH \
994 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
995 xpr \
996 JSON_HEDLEY_DIAGNOSTIC_POP
997# endif
998# endif
999#endif
1000#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
1001 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
1002#endif
1003
1004#if defined(JSON_HEDLEY_CONST_CAST)
1005 #undef JSON_HEDLEY_CONST_CAST
1006#endif
1007#if defined(__cplusplus)
1008# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1009#elif \
1010 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1011 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1012 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1013# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1014 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1015 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1016 ((T) (expr)); \
1017 JSON_HEDLEY_DIAGNOSTIC_POP \
1018 }))
1019#else
1020# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1021#endif
1022
1023#if defined(JSON_HEDLEY_REINTERPRET_CAST)
1024 #undef JSON_HEDLEY_REINTERPRET_CAST
1025#endif
1026#if defined(__cplusplus)
1027 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1028#else
1029 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1030#endif
1031
1032#if defined(JSON_HEDLEY_STATIC_CAST)
1033 #undef JSON_HEDLEY_STATIC_CAST
1034#endif
1035#if defined(__cplusplus)
1036 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1037#else
1038 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1039#endif
1040
1041#if defined(JSON_HEDLEY_CPP_CAST)
1042 #undef JSON_HEDLEY_CPP_CAST
1043#endif
1044#if defined(__cplusplus)
1045# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1046# define JSON_HEDLEY_CPP_CAST(T, expr) \
1047 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1048 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1049 ((T) (expr)) \
1050 JSON_HEDLEY_DIAGNOSTIC_POP
1051# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1052# define JSON_HEDLEY_CPP_CAST(T, expr) \
1053 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1054 _Pragma("diag_suppress=Pe137") \
1055 JSON_HEDLEY_DIAGNOSTIC_POP
1056# else
1057# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1058# endif
1059#else
1060# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1061#endif
1062
1063#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1064 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1065#endif
1066#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1067 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1068#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1069 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1070#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1071 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1072#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1073 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1074#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1075 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1076#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1077 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1078#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1079 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1080#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1081 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1082#elif \
1083 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1084 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1085 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1086 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1087 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1088 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1089 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1090 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1091 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1092 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1093 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1094 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1095#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1096 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1097#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1098 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1099#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1100 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1101#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1102 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1103#else
1104 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1105#endif
1106
1107#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1108 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1109#endif
1110#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1111 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1112#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1113 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1114#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1115 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1116#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1117 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1118#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1119 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1120#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1121 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1122#elif \
1123 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1124 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1125 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1126 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1127 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1128#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1129 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1130#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1131 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1132#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1133 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1134#else
1135 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1136#endif
1137
1138#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1139 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1140#endif
1141#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1142 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1143#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1144 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1145#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1146 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1147#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1148 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1149#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1150 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1151#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1152 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1153#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1154 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1155#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1156 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1157#elif \
1158 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1159 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1160 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1161 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1162#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1163 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1164#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1165 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1166#else
1167 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1168#endif
1169
1170#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1171 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1172#endif
1173#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1174 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1175#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1176 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1177#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1178 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1179#else
1180 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1181#endif
1182
1183#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1184 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1185#endif
1186#if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1187 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1188#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1189 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1190#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1191 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1192#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1193 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1194#else
1195 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1196#endif
1197
1198#if defined(JSON_HEDLEY_DEPRECATED)
1199 #undef JSON_HEDLEY_DEPRECATED
1200#endif
1201#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1202 #undef JSON_HEDLEY_DEPRECATED_FOR
1203#endif
1204#if \
1205 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1206 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1207 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1208 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1209#elif \
1210 (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1211 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1212 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1213 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1214 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1215 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1216 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1217 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1218 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1219 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1220 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1221 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1222 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1223 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1224#elif defined(__cplusplus) && (__cplusplus >= 201402L)
1225 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1226 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1227#elif \
1228 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1229 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1230 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1231 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1232 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1233 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1234 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1235 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1236 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1237 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1238 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1239 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1240 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1241 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1242 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1243 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1244 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1245 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1246#elif \
1247 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1248 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1249 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1250 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1251 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1252#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1253 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1254 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1255#else
1256 #define JSON_HEDLEY_DEPRECATED(since)
1257 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1258#endif
1259
1260#if defined(JSON_HEDLEY_UNAVAILABLE)
1261 #undef JSON_HEDLEY_UNAVAILABLE
1262#endif
1263#if \
1264 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1265 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1266 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1267 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1268 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1269#else
1270 #define JSON_HEDLEY_UNAVAILABLE(available_since)
1271#endif
1272
1273#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1274 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1275#endif
1276#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1277 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1278#endif
1279#if \
1280 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1281 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1282 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1283 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1284 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1285 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1286 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1287 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1288 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1289 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1290 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1291 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1292 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1293 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1294 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1295 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1296 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1297 #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1298 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1299#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1300 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1301 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1302#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1303 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1304 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1305#elif defined(_Check_return_) /* SAL */
1306 #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1307 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1308#else
1309 #define JSON_HEDLEY_WARN_UNUSED_RESULT
1310 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1311#endif
1312
1313#if defined(JSON_HEDLEY_SENTINEL)
1314 #undef JSON_HEDLEY_SENTINEL
1315#endif
1316#if \
1317 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1318 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1319 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1320 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1321 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1322 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1323#else
1324 #define JSON_HEDLEY_SENTINEL(position)
1325#endif
1326
1327#if defined(JSON_HEDLEY_NO_RETURN)
1328 #undef JSON_HEDLEY_NO_RETURN
1329#endif
1330#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1331 #define JSON_HEDLEY_NO_RETURN __noreturn
1332#elif \
1333 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1334 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1335 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1336#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1337 #define JSON_HEDLEY_NO_RETURN _Noreturn
1338#elif defined(__cplusplus) && (__cplusplus >= 201103L)
1339 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1340#elif \
1341 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1342 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1343 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1344 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1345 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1346 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1347 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1348 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1349 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1350 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1351 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1352 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1353 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1354 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1355 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1356 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1357 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1358 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1359#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1360 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1361#elif \
1362 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1363 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1364 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1365#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1366 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1367#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1368 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1369#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1370 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1371#else
1372 #define JSON_HEDLEY_NO_RETURN
1373#endif
1374
1375#if defined(JSON_HEDLEY_NO_ESCAPE)
1376 #undef JSON_HEDLEY_NO_ESCAPE
1377#endif
1378#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1379 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1380#else
1381 #define JSON_HEDLEY_NO_ESCAPE
1382#endif
1383
1384#if defined(JSON_HEDLEY_UNREACHABLE)
1385 #undef JSON_HEDLEY_UNREACHABLE
1386#endif
1387#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1388 #undef JSON_HEDLEY_UNREACHABLE_RETURN
1389#endif
1390#if defined(JSON_HEDLEY_ASSUME)
1391 #undef JSON_HEDLEY_ASSUME
1392#endif
1393#if \
1394 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1395 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1396 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1397 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1398#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1399 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1400#elif \
1401 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1402 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1403 #if defined(__cplusplus)
1404 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1405 #else
1406 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1407 #endif
1408#endif
1409#if \
1410 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1411 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1412 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1413 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1414 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1415 JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1416 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1417 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1418#elif defined(JSON_HEDLEY_ASSUME)
1419 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1420#endif
1421#if !defined(JSON_HEDLEY_ASSUME)
1422 #if defined(JSON_HEDLEY_UNREACHABLE)
1423 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1424 #else
1425 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1426 #endif
1427#endif
1428#if defined(JSON_HEDLEY_UNREACHABLE)
1429 #if \
1430 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1431 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1432 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1433 #else
1434 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1435 #endif
1436#else
1437 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1438#endif
1439#if !defined(JSON_HEDLEY_UNREACHABLE)
1440 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1441#endif
1442
1444#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1445 #pragma clang diagnostic ignored "-Wpedantic"
1446#endif
1447#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1448 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1449#endif
1450#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1451 #if defined(__clang__)
1452 #pragma clang diagnostic ignored "-Wvariadic-macros"
1453 #elif defined(JSON_HEDLEY_GCC_VERSION)
1454 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1455 #endif
1456#endif
1457#if defined(JSON_HEDLEY_NON_NULL)
1458 #undef JSON_HEDLEY_NON_NULL
1459#endif
1460#if \
1461 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1462 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1463 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1464 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1465 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1466#else
1467 #define JSON_HEDLEY_NON_NULL(...)
1468#endif
1470
1471#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1472 #undef JSON_HEDLEY_PRINTF_FORMAT
1473#endif
1474#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1475 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1476#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1477 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1478#elif \
1479 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1480 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1481 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1482 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1483 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1484 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1485 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1486 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1487 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1488 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1489 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1490 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1491 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1492 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1493 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1494 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1495 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1496 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1497#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1498 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1499#else
1500 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1501#endif
1502
1503#if defined(JSON_HEDLEY_CONSTEXPR)
1504 #undef JSON_HEDLEY_CONSTEXPR
1505#endif
1506#if defined(__cplusplus)
1507 #if __cplusplus >= 201103L
1508 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1509 #endif
1510#endif
1511#if !defined(JSON_HEDLEY_CONSTEXPR)
1512 #define JSON_HEDLEY_CONSTEXPR
1513#endif
1514
1515#if defined(JSON_HEDLEY_PREDICT)
1516 #undef JSON_HEDLEY_PREDICT
1517#endif
1518#if defined(JSON_HEDLEY_LIKELY)
1519 #undef JSON_HEDLEY_LIKELY
1520#endif
1521#if defined(JSON_HEDLEY_UNLIKELY)
1522 #undef JSON_HEDLEY_UNLIKELY
1523#endif
1524#if defined(JSON_HEDLEY_UNPREDICTABLE)
1525 #undef JSON_HEDLEY_UNPREDICTABLE
1526#endif
1527#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1528 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1529#endif
1530#if \
1531 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1532 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1533 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1534# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1535# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1536# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1537# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1538# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1539#elif \
1540 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1541 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1542 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1543 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1544 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1545 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1546 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1547 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1548 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1549 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1550 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1551 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1552 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1553 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1554 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1555 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1556# define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1557 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1558# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1559 (__extension__ ({ \
1560 double hedley_probability_ = (probability); \
1561 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1562 }))
1563# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1564 (__extension__ ({ \
1565 double hedley_probability_ = (probability); \
1566 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1567 }))
1568# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1569# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1570#else
1571# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1572# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1573# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1574# define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1575# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1576#endif
1577#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1578 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1579#endif
1580
1581#if defined(JSON_HEDLEY_MALLOC)
1582 #undef JSON_HEDLEY_MALLOC
1583#endif
1584#if \
1585 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1586 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1587 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1588 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1589 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1590 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1591 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1592 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1593 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1594 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1595 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1596 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1597 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1598 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1599 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1600 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1601 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1602 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1603 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1604#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1605 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1606#elif \
1607 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1608 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1609 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1610#else
1611 #define JSON_HEDLEY_MALLOC
1612#endif
1613
1614#if defined(JSON_HEDLEY_PURE)
1615 #undef JSON_HEDLEY_PURE
1616#endif
1617#if \
1618 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1619 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1620 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1621 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1622 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1623 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1624 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1625 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1626 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1627 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1628 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1629 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1630 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1631 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1632 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1633 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1634 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1635 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1636 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1637# define JSON_HEDLEY_PURE __attribute__((__pure__))
1638#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1639# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1640#elif defined(__cplusplus) && \
1641 ( \
1642 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1643 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1644 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1645 )
1646# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1647#else
1648# define JSON_HEDLEY_PURE
1649#endif
1650
1651#if defined(JSON_HEDLEY_CONST)
1652 #undef JSON_HEDLEY_CONST
1653#endif
1654#if \
1655 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1656 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1657 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1658 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1659 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1660 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1661 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1662 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1663 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1664 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1665 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1666 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1667 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1668 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1669 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1670 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1671 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1672 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1673 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1674 #define JSON_HEDLEY_CONST __attribute__((__const__))
1675#elif \
1676 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1677 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1678#else
1679 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1680#endif
1681
1682#if defined(JSON_HEDLEY_RESTRICT)
1683 #undef JSON_HEDLEY_RESTRICT
1684#endif
1685#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1686 #define JSON_HEDLEY_RESTRICT restrict
1687#elif \
1688 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1689 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1690 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1691 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1692 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1693 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1694 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1695 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1696 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1697 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1698 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1699 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1700 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1701 defined(__clang__) || \
1702 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1703 #define JSON_HEDLEY_RESTRICT __restrict
1704#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1705 #define JSON_HEDLEY_RESTRICT _Restrict
1706#else
1707 #define JSON_HEDLEY_RESTRICT
1708#endif
1709
1710#if defined(JSON_HEDLEY_INLINE)
1711 #undef JSON_HEDLEY_INLINE
1712#endif
1713#if \
1714 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1715 (defined(__cplusplus) && (__cplusplus >= 199711L))
1716 #define JSON_HEDLEY_INLINE inline
1717#elif \
1718 defined(JSON_HEDLEY_GCC_VERSION) || \
1719 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1720 #define JSON_HEDLEY_INLINE __inline__
1721#elif \
1722 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1723 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1724 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1725 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1726 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1727 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1728 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1729 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1730 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1731 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1732 #define JSON_HEDLEY_INLINE __inline
1733#else
1734 #define JSON_HEDLEY_INLINE
1735#endif
1736
1737#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1738 #undef JSON_HEDLEY_ALWAYS_INLINE
1739#endif
1740#if \
1741 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1742 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1743 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1744 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1745 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1746 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1747 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1748 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1749 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1750 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1751 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1752 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1753 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1754 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1755 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1756 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1757 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1758 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1759 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1760# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1761#elif \
1762 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1763 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1764# define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1765#elif defined(__cplusplus) && \
1766 ( \
1767 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1768 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1769 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1770 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1771 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1772 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1773 )
1774# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1775#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1776# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1777#else
1778# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1779#endif
1780
1781#if defined(JSON_HEDLEY_NEVER_INLINE)
1782 #undef JSON_HEDLEY_NEVER_INLINE
1783#endif
1784#if \
1785 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1786 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1787 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1788 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1789 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1790 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1791 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1792 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1793 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1794 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1795 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1796 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1797 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1798 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1799 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1800 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1801 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1802 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1803 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1804 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1805#elif \
1806 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1807 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1808 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1809#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1810 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1811#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1812 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1813#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1814 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1815#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1816 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1817#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1818 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1819#else
1820 #define JSON_HEDLEY_NEVER_INLINE
1821#endif
1822
1823#if defined(JSON_HEDLEY_PRIVATE)
1824 #undef JSON_HEDLEY_PRIVATE
1825#endif
1826#if defined(JSON_HEDLEY_PUBLIC)
1827 #undef JSON_HEDLEY_PUBLIC
1828#endif
1829#if defined(JSON_HEDLEY_IMPORT)
1830 #undef JSON_HEDLEY_IMPORT
1831#endif
1832#if defined(_WIN32) || defined(__CYGWIN__)
1833# define JSON_HEDLEY_PRIVATE
1834# define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1835# define JSON_HEDLEY_IMPORT __declspec(dllimport)
1836#else
1837# if \
1838 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1839 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1840 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1841 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1842 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1843 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1844 ( \
1845 defined(__TI_EABI__) && \
1846 ( \
1847 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1848 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1849 ) \
1850 ) || \
1851 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1852# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1853# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1854# else
1855# define JSON_HEDLEY_PRIVATE
1856# define JSON_HEDLEY_PUBLIC
1857# endif
1858# define JSON_HEDLEY_IMPORT extern
1859#endif
1860
1861#if defined(JSON_HEDLEY_NO_THROW)
1862 #undef JSON_HEDLEY_NO_THROW
1863#endif
1864#if \
1865 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1866 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1867 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1868 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1869 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1870#elif \
1871 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1872 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1873 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1874 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1875#else
1876 #define JSON_HEDLEY_NO_THROW
1877#endif
1878
1879#if defined(JSON_HEDLEY_FALL_THROUGH)
1880 #undef JSON_HEDLEY_FALL_THROUGH
1881#endif
1882#if \
1883 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1884 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
1885 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1886 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1887#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1888 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1889#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1890 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1891#elif defined(__fallthrough) /* SAL */
1892 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1893#else
1894 #define JSON_HEDLEY_FALL_THROUGH
1895#endif
1896
1897#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1898 #undef JSON_HEDLEY_RETURNS_NON_NULL
1899#endif
1900#if \
1901 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1902 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1903 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1904 #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1905#elif defined(_Ret_notnull_) /* SAL */
1906 #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1907#else
1908 #define JSON_HEDLEY_RETURNS_NON_NULL
1909#endif
1910
1911#if defined(JSON_HEDLEY_ARRAY_PARAM)
1912 #undef JSON_HEDLEY_ARRAY_PARAM
1913#endif
1914#if \
1915 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1916 !defined(__STDC_NO_VLA__) && \
1917 !defined(__cplusplus) && \
1918 !defined(JSON_HEDLEY_PGI_VERSION) && \
1919 !defined(JSON_HEDLEY_TINYC_VERSION)
1920 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1921#else
1922 #define JSON_HEDLEY_ARRAY_PARAM(name)
1923#endif
1924
1925#if defined(JSON_HEDLEY_IS_CONSTANT)
1926 #undef JSON_HEDLEY_IS_CONSTANT
1927#endif
1928#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1929 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1930#endif
1931/* JSON_HEDLEY_IS_CONSTEXPR_ is for
1932 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1933#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1934 #undef JSON_HEDLEY_IS_CONSTEXPR_
1935#endif
1936#if \
1937 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1938 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1939 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1940 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1941 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1942 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1943 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1944 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1945 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1946 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1947 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1948#endif
1949#if !defined(__cplusplus)
1950# if \
1951 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1952 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1953 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1954 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1955 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1956 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1957 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1958#if defined(__INTPTR_TYPE__)
1959 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1960#else
1961 #include <stdint.h>
1962 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1963#endif
1964# elif \
1965 ( \
1966 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1967 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1968 !defined(JSON_HEDLEY_PGI_VERSION) && \
1969 !defined(JSON_HEDLEY_IAR_VERSION)) || \
1970 (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1971 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1972 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1973 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1974 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1975#if defined(__INTPTR_TYPE__)
1976 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1977#else
1978 #include <stdint.h>
1979 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1980#endif
1981# elif \
1982 defined(JSON_HEDLEY_GCC_VERSION) || \
1983 defined(JSON_HEDLEY_INTEL_VERSION) || \
1984 defined(JSON_HEDLEY_TINYC_VERSION) || \
1985 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1986 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1987 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1988 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1989 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1990 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1991 defined(__clang__)
1992# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1993 sizeof(void) != \
1994 sizeof(*( \
1995 1 ? \
1996 ((void*) ((expr) * 0L) ) : \
1997((struct { char v[sizeof(void) * 2]; } *) 1) \
1998 ) \
1999 ) \
2000 )
2001# endif
2002#endif
2003#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
2004 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2005 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
2006 #endif
2007 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
2008#else
2009 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2010 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2011 #endif
2012 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2013#endif
2014
2015#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2016 #undef JSON_HEDLEY_BEGIN_C_DECLS
2017#endif
2018#if defined(JSON_HEDLEY_END_C_DECLS)
2019 #undef JSON_HEDLEY_END_C_DECLS
2020#endif
2021#if defined(JSON_HEDLEY_C_DECL)
2022 #undef JSON_HEDLEY_C_DECL
2023#endif
2024#if defined(__cplusplus)
2025 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2026 #define JSON_HEDLEY_END_C_DECLS }
2027 #define JSON_HEDLEY_C_DECL extern "C"
2028#else
2029 #define JSON_HEDLEY_BEGIN_C_DECLS
2030 #define JSON_HEDLEY_END_C_DECLS
2031 #define JSON_HEDLEY_C_DECL
2032#endif
2033
2034#if defined(JSON_HEDLEY_STATIC_ASSERT)
2035 #undef JSON_HEDLEY_STATIC_ASSERT
2036#endif
2037#if \
2038 !defined(__cplusplus) && ( \
2039 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2040 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2041 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2042 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2043 defined(_Static_assert) \
2044 )
2045# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2046#elif \
2047 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2048 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2049 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2050# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2051#else
2052# define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2053#endif
2054
2055#if defined(JSON_HEDLEY_NULL)
2056 #undef JSON_HEDLEY_NULL
2057#endif
2058#if defined(__cplusplus)
2059 #if __cplusplus >= 201103L
2060 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2061 #elif defined(NULL)
2062 #define JSON_HEDLEY_NULL NULL
2063 #else
2064 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2065 #endif
2066#elif defined(NULL)
2067 #define JSON_HEDLEY_NULL NULL
2068#else
2069 #define JSON_HEDLEY_NULL ((void*) 0)
2070#endif
2071
2072#if defined(JSON_HEDLEY_MESSAGE)
2073 #undef JSON_HEDLEY_MESSAGE
2074#endif
2075#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2076# define JSON_HEDLEY_MESSAGE(msg) \
2077 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2078 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2079 JSON_HEDLEY_PRAGMA(message msg) \
2080 JSON_HEDLEY_DIAGNOSTIC_POP
2081#elif \
2082 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2083 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2084# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2085#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2086# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2087#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2088# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2089#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2090# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2091#else
2092# define JSON_HEDLEY_MESSAGE(msg)
2093#endif
2094
2095#if defined(JSON_HEDLEY_WARNING)
2096 #undef JSON_HEDLEY_WARNING
2097#endif
2098#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2099# define JSON_HEDLEY_WARNING(msg) \
2100 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2101 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2102 JSON_HEDLEY_PRAGMA(clang warning msg) \
2103 JSON_HEDLEY_DIAGNOSTIC_POP
2104#elif \
2105 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2106 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2107 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2108# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2109#elif \
2110 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2111 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2112# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2113#else
2114# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2115#endif
2116
2117#if defined(JSON_HEDLEY_REQUIRE)
2118 #undef JSON_HEDLEY_REQUIRE
2119#endif
2120#if defined(JSON_HEDLEY_REQUIRE_MSG)
2121 #undef JSON_HEDLEY_REQUIRE_MSG
2122#endif
2123#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2124# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2125# define JSON_HEDLEY_REQUIRE(expr) \
2126 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2127 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2128 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2129 JSON_HEDLEY_DIAGNOSTIC_POP
2130# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2131 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2132 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2133 __attribute__((diagnose_if(!(expr), msg, "error"))) \
2134 JSON_HEDLEY_DIAGNOSTIC_POP
2135# else
2136# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2137# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2138# endif
2139#else
2140# define JSON_HEDLEY_REQUIRE(expr)
2141# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2142#endif
2143
2144#if defined(JSON_HEDLEY_FLAGS)
2145 #undef JSON_HEDLEY_FLAGS
2146#endif
2147#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2148 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2149#else
2150 #define JSON_HEDLEY_FLAGS
2151#endif
2152
2153#if defined(JSON_HEDLEY_FLAGS_CAST)
2154 #undef JSON_HEDLEY_FLAGS_CAST
2155#endif
2156#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2157# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2158 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2159 _Pragma("warning(disable:188)") \
2160 ((T) (expr)); \
2161 JSON_HEDLEY_DIAGNOSTIC_POP \
2162 }))
2163#else
2164# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2165#endif
2166
2167#if defined(JSON_HEDLEY_EMPTY_BASES)
2168 #undef JSON_HEDLEY_EMPTY_BASES
2169#endif
2170#if \
2171 (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2172 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2173 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2174#else
2175 #define JSON_HEDLEY_EMPTY_BASES
2176#endif
2177
2178/* Remaining macros are deprecated. */
2179
2180#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2181 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2182#endif
2183#if defined(__clang__)
2184 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2185#else
2186 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2187#endif
2188
2189#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2190 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2191#endif
2192#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2193
2194#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2195 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2196#endif
2197#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2198
2199#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2200 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2201#endif
2202#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2203
2204#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2205 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2206#endif
2207#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2208
2209#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2210 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2211#endif
2212#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2213
2214#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2215 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2216#endif
2217#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2218
2219#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2220 #undef JSON_HEDLEY_CLANG_HAS_WARNING
2221#endif
2222#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2223
2224#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2225
2226// #include <nlohmann/detail/meta/detected.hpp>
2227
2228
2229#include <type_traits>
2230
2231// #include <nlohmann/detail/meta/void_t.hpp>
2232
2233
2234namespace nlohmann
2235{
2236namespace detail
2237{
2238template<typename ...Ts> struct make_void
2239{
2240 using type = void;
2241};
2242template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2243} // namespace detail
2244} // namespace nlohmann
2245
2246
2247// https://en.cppreference.com/w/cpp/experimental/is_detected
2248namespace nlohmann
2249{
2250namespace detail
2251{
2253{
2254 nonesuch() = delete;
2255 ~nonesuch() = delete;
2256 nonesuch(nonesuch const&) = delete;
2257 nonesuch(nonesuch const&&) = delete;
2258 void operator=(nonesuch const&) = delete;
2259 void operator=(nonesuch&&) = delete;
2260};
2261
2262template<class Default,
2263 class AlwaysVoid,
2264 template<class...> class Op,
2265 class... Args>
2267{
2268 using value_t = std::false_type;
2269 using type = Default;
2270};
2271
2272template<class Default, template<class...> class Op, class... Args>
2273struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2274{
2275 using value_t = std::true_type;
2276 using type = Op<Args...>;
2277};
2278
2279template<template<class...> class Op, class... Args>
2280using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2281
2282template<template<class...> class Op, class... Args>
2283struct is_detected_lazy : is_detected<Op, Args...> { };
2284
2285template<template<class...> class Op, class... Args>
2286using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2287
2288template<class Default, template<class...> class Op, class... Args>
2289using detected_or = detector<Default, void, Op, Args...>;
2290
2291template<class Default, template<class...> class Op, class... Args>
2292using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2293
2294template<class Expected, template<class...> class Op, class... Args>
2295using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2296
2297template<class To, template<class...> class Op, class... Args>
2299 std::is_convertible<detected_t<Op, Args...>, To>;
2300} // namespace detail
2301} // namespace nlohmann
2302
2303
2304// This file contains all internal macro definitions
2305// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2306
2307// exclude unsupported compilers
2308#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2309 #if defined(__clang__)
2310 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2311 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2312 #endif
2313 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2314 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2315 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2316 #endif
2317 #endif
2318#endif
2319
2320// C++ language standard detection
2321// if the user manually specified the used c++ version this is skipped
2322#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2323 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2324 #define JSON_HAS_CPP_20
2325 #define JSON_HAS_CPP_17
2326 #define JSON_HAS_CPP_14
2327 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2328 #define JSON_HAS_CPP_17
2329 #define JSON_HAS_CPP_14
2330 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2331 #define JSON_HAS_CPP_14
2332 #endif
2333 // the cpp 11 flag is always specified because it is the minimal required version
2334 #define JSON_HAS_CPP_11
2335#endif
2336
2337#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
2338 #ifdef JSON_HAS_CPP_17
2339 #if defined(__cpp_lib_filesystem)
2340 #define JSON_HAS_FILESYSTEM 1
2341 #elif defined(__cpp_lib_experimental_filesystem)
2342 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2343 #elif !defined(__has_include)
2344 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2345 #elif __has_include(<filesystem>)
2346 #define JSON_HAS_FILESYSTEM 1
2347 #elif __has_include(<experimental/filesystem>)
2348 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2349 #endif
2350
2351 // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
2352 #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
2353 #undef JSON_HAS_FILESYSTEM
2354 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2355 #endif
2356
2357 // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
2358 #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
2359 #undef JSON_HAS_FILESYSTEM
2360 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2361 #endif
2362
2363 // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
2364 #if defined(__clang_major__) && __clang_major__ < 7
2365 #undef JSON_HAS_FILESYSTEM
2366 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2367 #endif
2368
2369 // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
2370 #if defined(_MSC_VER) && _MSC_VER < 1940
2371 #undef JSON_HAS_FILESYSTEM
2372 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2373 #endif
2374
2375 // no filesystem support before iOS 13
2376 #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
2377 #undef JSON_HAS_FILESYSTEM
2378 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2379 #endif
2380
2381 // no filesystem support before macOS Catalina
2382 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
2383 #undef JSON_HAS_FILESYSTEM
2384 #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2385 #endif
2386 #endif
2387#endif
2388
2389#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2390 #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
2391#endif
2392
2393#ifndef JSON_HAS_FILESYSTEM
2394 #define JSON_HAS_FILESYSTEM 0
2395#endif
2396
2397// disable documentation warnings on clang
2398#if defined(__clang__)
2399 #pragma clang diagnostic push
2400 #pragma clang diagnostic ignored "-Wdocumentation"
2401 #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2402#endif
2403
2404// allow disabling exceptions
2405#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2406 #define JSON_THROW(exception) throw exception
2407 #define JSON_TRY try
2408 #define JSON_CATCH(exception) catch(exception)
2409 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2410#else
2411 #include <cstdlib>
2412 #define JSON_THROW(exception) std::abort()
2413 #define JSON_TRY if(true)
2414 #define JSON_CATCH(exception) if(false)
2415 #define JSON_INTERNAL_CATCH(exception) if(false)
2416#endif
2417
2418// override exception macros
2419#if defined(JSON_THROW_USER)
2420 #undef JSON_THROW
2421 #define JSON_THROW JSON_THROW_USER
2422#endif
2423#if defined(JSON_TRY_USER)
2424 #undef JSON_TRY
2425 #define JSON_TRY JSON_TRY_USER
2426#endif
2427#if defined(JSON_CATCH_USER)
2428 #undef JSON_CATCH
2429 #define JSON_CATCH JSON_CATCH_USER
2430 #undef JSON_INTERNAL_CATCH
2431 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2432#endif
2433#if defined(JSON_INTERNAL_CATCH_USER)
2434 #undef JSON_INTERNAL_CATCH
2435 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2436#endif
2437
2438// allow overriding assert
2439#if !defined(JSON_ASSERT)
2440 #include <cassert> // assert
2441 #define JSON_ASSERT(x) assert(x)
2442#endif
2443
2444// allow to access some private functions (needed by the test suite)
2445#if defined(JSON_TESTS_PRIVATE)
2446 #define JSON_PRIVATE_UNLESS_TESTED public
2447#else
2448 #define JSON_PRIVATE_UNLESS_TESTED private
2449#endif
2450
2456#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2457 template<typename BasicJsonType> \
2458 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2459 { \
2460 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2461 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2462 auto it = std::find_if(std::begin(m), std::end(m), \
2463 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2464 { \
2465 return ej_pair.first == e; \
2466 }); \
2467 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2468 } \
2469 template<typename BasicJsonType> \
2470 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2471 { \
2472 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2473 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2474 auto it = std::find_if(std::begin(m), std::end(m), \
2475 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2476 { \
2477 return ej_pair.second == j; \
2478 }); \
2479 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2480 }
2481
2482// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2483// may be removed in the future once the class is split.
2484
2485#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2486 template<template<typename, typename, typename...> class ObjectType, \
2487 template<typename, typename...> class ArrayType, \
2488 class StringType, class BooleanType, class NumberIntegerType, \
2489 class NumberUnsignedType, class NumberFloatType, \
2490 template<typename> class AllocatorType, \
2491 template<typename, typename = void> class JSONSerializer, \
2492 class BinaryType>
2493
2494#define NLOHMANN_BASIC_JSON_TPL \
2495 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2496 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2497 AllocatorType, JSONSerializer, BinaryType>
2498
2499// Macros to simplify conversion from/to types
2500
2501#define NLOHMANN_JSON_EXPAND( x ) x
2502#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
2503#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2504 NLOHMANN_JSON_PASTE64, \
2505 NLOHMANN_JSON_PASTE63, \
2506 NLOHMANN_JSON_PASTE62, \
2507 NLOHMANN_JSON_PASTE61, \
2508 NLOHMANN_JSON_PASTE60, \
2509 NLOHMANN_JSON_PASTE59, \
2510 NLOHMANN_JSON_PASTE58, \
2511 NLOHMANN_JSON_PASTE57, \
2512 NLOHMANN_JSON_PASTE56, \
2513 NLOHMANN_JSON_PASTE55, \
2514 NLOHMANN_JSON_PASTE54, \
2515 NLOHMANN_JSON_PASTE53, \
2516 NLOHMANN_JSON_PASTE52, \
2517 NLOHMANN_JSON_PASTE51, \
2518 NLOHMANN_JSON_PASTE50, \
2519 NLOHMANN_JSON_PASTE49, \
2520 NLOHMANN_JSON_PASTE48, \
2521 NLOHMANN_JSON_PASTE47, \
2522 NLOHMANN_JSON_PASTE46, \
2523 NLOHMANN_JSON_PASTE45, \
2524 NLOHMANN_JSON_PASTE44, \
2525 NLOHMANN_JSON_PASTE43, \
2526 NLOHMANN_JSON_PASTE42, \
2527 NLOHMANN_JSON_PASTE41, \
2528 NLOHMANN_JSON_PASTE40, \
2529 NLOHMANN_JSON_PASTE39, \
2530 NLOHMANN_JSON_PASTE38, \
2531 NLOHMANN_JSON_PASTE37, \
2532 NLOHMANN_JSON_PASTE36, \
2533 NLOHMANN_JSON_PASTE35, \
2534 NLOHMANN_JSON_PASTE34, \
2535 NLOHMANN_JSON_PASTE33, \
2536 NLOHMANN_JSON_PASTE32, \
2537 NLOHMANN_JSON_PASTE31, \
2538 NLOHMANN_JSON_PASTE30, \
2539 NLOHMANN_JSON_PASTE29, \
2540 NLOHMANN_JSON_PASTE28, \
2541 NLOHMANN_JSON_PASTE27, \
2542 NLOHMANN_JSON_PASTE26, \
2543 NLOHMANN_JSON_PASTE25, \
2544 NLOHMANN_JSON_PASTE24, \
2545 NLOHMANN_JSON_PASTE23, \
2546 NLOHMANN_JSON_PASTE22, \
2547 NLOHMANN_JSON_PASTE21, \
2548 NLOHMANN_JSON_PASTE20, \
2549 NLOHMANN_JSON_PASTE19, \
2550 NLOHMANN_JSON_PASTE18, \
2551 NLOHMANN_JSON_PASTE17, \
2552 NLOHMANN_JSON_PASTE16, \
2553 NLOHMANN_JSON_PASTE15, \
2554 NLOHMANN_JSON_PASTE14, \
2555 NLOHMANN_JSON_PASTE13, \
2556 NLOHMANN_JSON_PASTE12, \
2557 NLOHMANN_JSON_PASTE11, \
2558 NLOHMANN_JSON_PASTE10, \
2559 NLOHMANN_JSON_PASTE9, \
2560 NLOHMANN_JSON_PASTE8, \
2561 NLOHMANN_JSON_PASTE7, \
2562 NLOHMANN_JSON_PASTE6, \
2563 NLOHMANN_JSON_PASTE5, \
2564 NLOHMANN_JSON_PASTE4, \
2565 NLOHMANN_JSON_PASTE3, \
2566 NLOHMANN_JSON_PASTE2, \
2567 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2568#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2569#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2570#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2571#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2572#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2573#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)
2574#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)
2575#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)
2576#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)
2577#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)
2578#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)
2579#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)
2580#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)
2581#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)
2582#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)
2583#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)
2584#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)
2585#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)
2586#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)
2587#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)
2588#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)
2589#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)
2590#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)
2591#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)
2592#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)
2593#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)
2594#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)
2595#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)
2596#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)
2597#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)
2598#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)
2599#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)
2600#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)
2601#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)
2602#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)
2603#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)
2604#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)
2605#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)
2606#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)
2607#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)
2608#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)
2609#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)
2610#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)
2611#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)
2612#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)
2613#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)
2614#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)
2615#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)
2616#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)
2617#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)
2618#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)
2619#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)
2620#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)
2621#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)
2622#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)
2623#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)
2624#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)
2625#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)
2626#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)
2627#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)
2628#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)
2629#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)
2630#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)
2631
2632#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2633#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2634
2640#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2641 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__)) } \
2642 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__)) }
2643
2649#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2650 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__)) } \
2651 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__)) }
2652
2653
2654// inspired from https://stackoverflow.com/a/26745591
2655// allows to call any std function as if (e.g. with begin):
2656// using std::begin; begin(x);
2657//
2658// it allows using the detected idiom to retrieve the return type
2659// of such an expression
2660#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2661 namespace detail { \
2662 using std::std_name; \
2663 \
2664 template<typename... T> \
2665 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2666 } \
2667 \
2668 namespace detail2 { \
2669 struct std_name##_tag \
2670 { \
2671 }; \
2672 \
2673 template<typename... T> \
2674 std_name##_tag std_name(T&&...); \
2675 \
2676 template<typename... T> \
2677 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2678 \
2679 template<typename... T> \
2680 struct would_call_std_##std_name \
2681 { \
2682 static constexpr auto const value = ::nlohmann::detail:: \
2683 is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2684 }; \
2685 } /* namespace detail2 */ \
2686 \
2687 template<typename... T> \
2688 struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2689 { \
2690 }
2691
2692#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2693 #define JSON_USE_IMPLICIT_CONVERSIONS 1
2694#endif
2695
2696#if JSON_USE_IMPLICIT_CONVERSIONS
2697 #define JSON_EXPLICIT
2698#else
2699 #define JSON_EXPLICIT explicit
2700#endif
2701
2702#ifndef JSON_DIAGNOSTICS
2703 #define JSON_DIAGNOSTICS 0
2704#endif
2705
2706
2707namespace nlohmann
2708{
2709namespace detail
2710{
2711
2725inline void replace_substring(std::string& s, const std::string& f,
2726 const std::string& t)
2727{
2728 JSON_ASSERT(!f.empty());
2729 for (auto pos = s.find(f); // find first occurrence of f
2730 pos != std::string::npos; // make sure f was found
2731 s.replace(pos, f.size(), t), // replace with t, and
2732 pos = s.find(f, pos + t.size())) // find next occurrence of f
2733 {}
2734}
2735
2743inline std::string escape(std::string s)
2744{
2745 replace_substring(s, "~", "~0");
2746 replace_substring(s, "/", "~1");
2747 return s;
2748}
2749
2757static void unescape(std::string& s)
2758{
2759 replace_substring(s, "~1", "/");
2760 replace_substring(s, "~0", "~");
2761}
2762
2763} // namespace detail
2764} // namespace nlohmann
2765
2766// #include <nlohmann/detail/input/position_t.hpp>
2767
2768
2769#include <cstddef> // size_t
2770
2771namespace nlohmann
2772{
2773namespace detail
2774{
2777{
2779 std::size_t chars_read_total = 0;
2783 std::size_t lines_read = 0;
2784
2786 constexpr operator size_t() const
2787 {
2788 return chars_read_total;
2789 }
2790};
2791
2792} // namespace detail
2793} // namespace nlohmann
2794
2795// #include <nlohmann/detail/macro_scope.hpp>
2796
2797
2798namespace nlohmann
2799{
2800namespace detail
2801{
2803// exceptions //
2805
2808class exception : public std::exception
2809{
2810 public:
2812 const char* what() const noexcept override
2813 {
2814 return m.what();
2815 }
2816
2818 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
2819
2820 protected:
2822 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
2823
2824 static std::string name(const std::string& ename, int id_)
2825 {
2826 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2827 }
2828
2829 template<typename BasicJsonType>
2830 static std::string diagnostics(const BasicJsonType& leaf_element)
2831 {
2832#if JSON_DIAGNOSTICS
2833 std::vector<std::string> tokens;
2834 for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
2835 {
2836 switch (current->m_parent->type())
2837 {
2838 case value_t::array:
2839 {
2840 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
2841 {
2842 if (&current->m_parent->m_value.array->operator[](i) == current)
2843 {
2844 tokens.emplace_back(std::to_string(i));
2845 break;
2846 }
2847 }
2848 break;
2849 }
2850
2851 case value_t::object:
2852 {
2853 for (const auto& element : *current->m_parent->m_value.object)
2854 {
2855 if (&element.second == current)
2856 {
2857 tokens.emplace_back(element.first.c_str());
2858 break;
2859 }
2860 }
2861 break;
2862 }
2863
2864 case value_t::null: // LCOV_EXCL_LINE
2865 case value_t::string: // LCOV_EXCL_LINE
2866 case value_t::boolean: // LCOV_EXCL_LINE
2867 case value_t::number_integer: // LCOV_EXCL_LINE
2868 case value_t::number_unsigned: // LCOV_EXCL_LINE
2869 case value_t::number_float: // LCOV_EXCL_LINE
2870 case value_t::binary: // LCOV_EXCL_LINE
2871 case value_t::discarded: // LCOV_EXCL_LINE
2872 default: // LCOV_EXCL_LINE
2873 break; // LCOV_EXCL_LINE
2874 }
2875 }
2876
2877 if (tokens.empty())
2878 {
2879 return "";
2880 }
2881
2882 return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
2883 [](const std::string & a, const std::string & b)
2884 {
2885 return a + "/" + detail::escape(b);
2886 }) + ") ";
2887#else
2888 static_cast<void>(leaf_element);
2889 return "";
2890#endif
2891 }
2892
2893 private:
2895 std::runtime_error m;
2896};
2897
2901{
2902 public:
2912 template<typename BasicJsonType>
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 {id_, pos.chars_read_total, w.c_str()};
2918 }
2919
2920 template<typename BasicJsonType>
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 {id_, byte_, w.c_str()};
2927 }
2928
2938 const std::size_t byte;
2939
2940 private:
2941 parse_error(int id_, std::size_t byte_, const char* what_arg)
2942 : exception(id_, what_arg), byte(byte_) {}
2943
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
2954{
2955 public:
2956 template<typename BasicJsonType>
2957 static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
2958 {
2959 std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
2960 return {id_, w.c_str()};
2961 }
2962
2963 private:
2965 invalid_iterator(int id_, const char* what_arg)
2966 : exception(id_, what_arg) {}
2967};
2968
2971class type_error : public exception
2972{
2973 public:
2974 template<typename BasicJsonType>
2975 static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
2976 {
2977 std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
2978 return {id_, w.c_str()};
2979 }
2980
2981 private:
2983 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2984};
2985
2989{
2990 public:
2991 template<typename BasicJsonType>
2992 static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
2993 {
2994 std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
2995 return {id_, w.c_str()};
2996 }
2997
2998 private:
3000 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
3001};
3002
3006{
3007 public:
3008 template<typename BasicJsonType>
3009 static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3010 {
3011 std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
3012 return {id_, w.c_str()};
3013 }
3014
3015 private:
3017 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3018};
3019
3020} // namespace detail
3021} // namespace nlohmann
3022
3023// #include <nlohmann/detail/macro_scope.hpp>
3024
3025// #include <nlohmann/detail/meta/cpp_future.hpp>
3026
3027
3028#include <cstddef> // size_t
3029#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3030#include <utility> // index_sequence, make_index_sequence, index_sequence_for
3031
3032// #include <nlohmann/detail/macro_scope.hpp>
3033
3034
3035namespace nlohmann
3036{
3037namespace detail
3038{
3039
3040template<typename T>
3041using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3042
3043#ifdef JSON_HAS_CPP_14
3044
3045// the following utilities are natively available in C++14
3046using std::enable_if_t;
3047using std::index_sequence;
3048using std::make_index_sequence;
3049using std::index_sequence_for;
3050
3051#else
3052
3053// alias templates to reduce boilerplate
3054template<bool B, typename T = void>
3055using enable_if_t = typename std::enable_if<B, T>::type;
3056
3057// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3058// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3059
3061
3062// integer_sequence
3063//
3064// Class template representing a compile-time integer sequence. An instantiation
3065// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3066// type through its template arguments (which is a common need when
3067// working with C++11 variadic templates). `absl::integer_sequence` is designed
3068// to be a drop-in replacement for C++14's `std::integer_sequence`.
3069//
3070// Example:
3071//
3072// template< class T, T... Ints >
3073// void user_function(integer_sequence<T, Ints...>);
3074//
3075// int main()
3076// {
3077// // user_function's `T` will be deduced to `int` and `Ints...`
3078// // will be deduced to `0, 1, 2, 3, 4`.
3079// user_function(make_integer_sequence<int, 5>());
3080// }
3081template <typename T, T... Ints>
3083{
3084 using value_type = T;
3085 static constexpr std::size_t size() noexcept
3086 {
3087 return sizeof...(Ints);
3088 }
3089};
3090
3091// index_sequence
3092//
3093// A helper template for an `integer_sequence` of `size_t`,
3094// `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3095// `std::index_sequence`.
3096template <size_t... Ints>
3097using index_sequence = integer_sequence<size_t, Ints...>;
3098
3099namespace utility_internal
3100{
3101
3102template <typename Seq, size_t SeqSize, size_t Rem>
3103struct Extend;
3104
3105// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3106template <typename T, T... Ints, size_t SeqSize>
3107struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3108{
3109 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3110};
3111
3112template <typename T, T... Ints, size_t SeqSize>
3113struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3114{
3115 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3116};
3117
3118// Recursion helper for 'make_integer_sequence<T, N>'.
3119// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3120template <typename T, size_t N>
3121struct Gen
3122{
3123 using type =
3124 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3125};
3126
3127template <typename T>
3128struct Gen<T, 0>
3129{
3131};
3132
3133} // namespace utility_internal
3134
3135// Compile-time sequences of integers
3136
3137// make_integer_sequence
3138//
3139// This template alias is equivalent to
3140// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3141// replacement for C++14's `std::make_integer_sequence`.
3142template <typename T, T N>
3144
3145// make_index_sequence
3146//
3147// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3148// and is designed to be a drop-in replacement for C++14's
3149// `std::make_index_sequence`.
3150template <size_t N>
3152
3153// index_sequence_for
3154//
3155// Converts a typename pack into an index sequence of the same length, and
3156// is designed to be a drop-in replacement for C++14's
3157// `std::index_sequence_for()`
3158template <typename... Ts>
3160
3162
3163#endif
3164
3165// dispatch utility (taken from ranges-v3)
3166template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3167template<> struct priority_tag<0> {};
3168
3169// taken from ranges-v3
3170template<typename T>
3172{
3173 static constexpr T value{};
3174};
3175
3176template<typename T>
3177constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
3178
3179} // namespace detail
3180} // namespace nlohmann
3181
3182// #include <nlohmann/detail/meta/identity_tag.hpp>
3183
3184
3185namespace nlohmann
3186{
3187namespace detail
3188{
3189// dispatching helper struct
3190template <class T> struct identity_tag {};
3191} // namespace detail
3192} // namespace nlohmann
3193
3194// #include <nlohmann/detail/meta/type_traits.hpp>
3195
3196
3197#include <limits> // numeric_limits
3198#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3199#include <utility> // declval
3200#include <tuple> // tuple
3201
3202// #include <nlohmann/detail/macro_scope.hpp>
3203
3204
3205// #include <nlohmann/detail/iterators/iterator_traits.hpp>
3206
3207
3208#include <iterator> // random_access_iterator_tag
3209
3210// #include <nlohmann/detail/meta/void_t.hpp>
3211
3212// #include <nlohmann/detail/meta/cpp_future.hpp>
3213
3214
3215namespace nlohmann
3216{
3217namespace detail
3218{
3219template<typename It, typename = void>
3221
3222template<typename It>
3224 It,
3225 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3226 typename It::reference, typename It::iterator_category >>
3227{
3228 using difference_type = typename It::difference_type;
3229 using value_type = typename It::value_type;
3230 using pointer = typename It::pointer;
3231 using reference = typename It::reference;
3232 using iterator_category = typename It::iterator_category;
3233};
3234
3235// This is required as some compilers implement std::iterator_traits in a way that
3236// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3237template<typename T, typename = void>
3239{
3240};
3241
3242template<typename T>
3243struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3244 : iterator_types<T>
3245{
3246};
3247
3248template<typename T>
3250{
3251 using iterator_category = std::random_access_iterator_tag;
3252 using value_type = T;
3253 using difference_type = ptrdiff_t;
3254 using pointer = T*;
3255 using reference = T&;
3256};
3257} // namespace detail
3258} // namespace nlohmann
3259
3260// #include <nlohmann/detail/meta/call_std/begin.hpp>
3261
3262
3263// #include <nlohmann/detail/macro_scope.hpp>
3264
3265
3266namespace nlohmann
3267{
3269} // namespace nlohmann
3270
3271// #include <nlohmann/detail/meta/call_std/end.hpp>
3272
3273
3274// #include <nlohmann/detail/macro_scope.hpp>
3275
3276
3277namespace nlohmann
3278{
3280} // namespace nlohmann
3281
3282// #include <nlohmann/detail/meta/cpp_future.hpp>
3283
3284// #include <nlohmann/detail/meta/detected.hpp>
3285
3286// #include <nlohmann/json_fwd.hpp>
3287#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3288#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3289
3290#include <cstdint> // int64_t, uint64_t
3291#include <map> // map
3292#include <memory> // allocator
3293#include <string> // string
3294#include <vector> // vector
3295
3301namespace nlohmann
3302{
3310template<typename T = void, typename SFINAE = void>
3311struct adl_serializer;
3312
3315template<template<typename U, typename V, typename... Args> class ObjectType =
3316 std::map,
3317 template<typename U, typename... Args> class ArrayType = std::vector,
3318 class StringType = std::string, class BooleanType = bool,
3319 class NumberIntegerType = std::int64_t,
3320 class NumberUnsignedType = std::uint64_t,
3321 class NumberFloatType = double,
3322 template<typename U> class AllocatorType = std::allocator,
3323 template<typename T, typename SFINAE = void> class JSONSerializer =
3324 adl_serializer,
3325 class BinaryType = std::vector<std::uint8_t>>
3326class basic_json;
3327
3330template<typename BasicJsonType>
3331class json_pointer;
3332
3338
3341template<class Key, class T, class IgnoredLess, class Allocator>
3342struct ordered_map;
3343
3347
3348} // namespace nlohmann
3349
3350#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3351
3352
3353namespace nlohmann
3354{
3363namespace detail
3364{
3366// helpers //
3368
3369// Note to maintainers:
3370//
3371// Every trait in this file expects a non CV-qualified type.
3372// The only exceptions are in the 'aliases for detected' section
3373// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3374//
3375// In this case, T has to be properly CV-qualified to constraint the function arguments
3376// (e.g. to_json(BasicJsonType&, const T&))
3377
3378template<typename> struct is_basic_json : std::false_type {};
3379
3381struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3382
3384// json_ref helpers //
3386
3387template<typename>
3388class json_ref;
3389
3390template<typename>
3391struct is_json_ref : std::false_type {};
3392
3393template<typename T>
3394struct is_json_ref<json_ref<T>> : std::true_type {};
3395
3397// aliases for detected //
3399
3400template<typename T>
3401using mapped_type_t = typename T::mapped_type;
3402
3403template<typename T>
3404using key_type_t = typename T::key_type;
3405
3406template<typename T>
3407using value_type_t = typename T::value_type;
3408
3409template<typename T>
3410using difference_type_t = typename T::difference_type;
3411
3412template<typename T>
3413using pointer_t = typename T::pointer;
3414
3415template<typename T>
3416using reference_t = typename T::reference;
3417
3418template<typename T>
3419using iterator_category_t = typename T::iterator_category;
3420
3421template<typename T, typename... Args>
3422using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3423
3424template<typename T, typename... Args>
3425using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3426
3427template<typename T, typename U>
3428using get_template_function = decltype(std::declval<T>().template get<U>());
3429
3430// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3431template<typename BasicJsonType, typename T, typename = void>
3432struct has_from_json : std::false_type {};
3433
3434// trait checking if j.get<T> is valid
3435// use this trait instead of std::is_constructible or std::is_convertible,
3436// both rely on, or make use of implicit conversions, and thus fail when T
3437// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3438template <typename BasicJsonType, typename T>
3443
3444template<typename BasicJsonType, typename T>
3445struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3446{
3447 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3448
3449 static constexpr bool value =
3451 const BasicJsonType&, T&>::value;
3452};
3453
3454// This trait checks if JSONSerializer<T>::from_json(json const&) exists
3455// this overload is used for non-default-constructible user-defined-types
3456template<typename BasicJsonType, typename T, typename = void>
3457struct has_non_default_from_json : std::false_type {};
3458
3459template<typename BasicJsonType, typename T>
3460struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3461{
3462 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3463
3464 static constexpr bool value =
3466 const BasicJsonType&>::value;
3467};
3468
3469// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3470// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3471template<typename BasicJsonType, typename T, typename = void>
3472struct has_to_json : std::false_type {};
3473
3474template<typename BasicJsonType, typename T>
3475struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3476{
3477 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3478
3479 static constexpr bool value =
3480 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3481 T>::value;
3482};
3483
3484
3486// is_ functions //
3488
3489// https://en.cppreference.com/w/cpp/types/conjunction
3490template<class...> struct conjunction : std::true_type { };
3491template<class B1> struct conjunction<B1> : B1 { };
3492template<class B1, class... Bn>
3493struct conjunction<B1, Bn...>
3494: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3495
3496// https://en.cppreference.com/w/cpp/types/negation
3497template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3498
3499// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3500// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3501// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3502template <typename T>
3503struct is_default_constructible : std::is_default_constructible<T> {};
3504
3505template <typename T1, typename T2>
3506struct is_default_constructible<std::pair<T1, T2>>
3507 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3508
3509template <typename T1, typename T2>
3510struct is_default_constructible<const std::pair<T1, T2>>
3511 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3512
3513template <typename... Ts>
3514struct is_default_constructible<std::tuple<Ts...>>
3515 : conjunction<is_default_constructible<Ts>...> {};
3516
3517template <typename... Ts>
3518struct is_default_constructible<const std::tuple<Ts...>>
3519 : conjunction<is_default_constructible<Ts>...> {};
3520
3521
3522template <typename T, typename... Args>
3523struct is_constructible : std::is_constructible<T, Args...> {};
3524
3525template <typename T1, typename T2>
3526struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3527
3528template <typename T1, typename T2>
3529struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3530
3531template <typename... Ts>
3532struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3533
3534template <typename... Ts>
3535struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3536
3537
3538template<typename T, typename = void>
3539struct is_iterator_traits : std::false_type {};
3540
3541template<typename T>
3555
3556template<typename T>
3558{
3559 private:
3560 using t_ref = typename std::add_lvalue_reference<T>::type;
3561
3564
3565 // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3566 // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3567 // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3568 static constexpr auto is_iterator_begin =
3570
3571 public:
3572 static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3573};
3574
3575template<typename R>
3576using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3577
3578template<typename T>
3580
3581// The following implementation of is_complete_type is taken from
3582// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3583// and is written by Xiang Fan who agreed to using it in this library.
3584
3585template<typename T, typename = void>
3586struct is_complete_type : std::false_type {};
3587
3588template<typename T>
3589struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3590
3591template<typename BasicJsonType, typename CompatibleObjectType,
3592 typename = void>
3593struct is_compatible_object_type_impl : std::false_type {};
3594
3595template<typename BasicJsonType, typename CompatibleObjectType>
3597 BasicJsonType, CompatibleObjectType,
3598 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3599 is_detected<key_type_t, CompatibleObjectType>::value >>
3600{
3601 using object_t = typename BasicJsonType::object_t;
3602
3603 // macOS's is_constructible does not play well with nonesuch...
3604 static constexpr bool value =
3605 is_constructible<typename object_t::key_type,
3606 typename CompatibleObjectType::key_type>::value &&
3607 is_constructible<typename object_t::mapped_type,
3608 typename CompatibleObjectType::mapped_type>::value;
3609};
3610
3611template<typename BasicJsonType, typename CompatibleObjectType>
3613 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3614
3615template<typename BasicJsonType, typename ConstructibleObjectType,
3616 typename = void>
3617struct is_constructible_object_type_impl : std::false_type {};
3618
3619template<typename BasicJsonType, typename ConstructibleObjectType>
3621 BasicJsonType, ConstructibleObjectType,
3622 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3623 is_detected<key_type_t, ConstructibleObjectType>::value >>
3624{
3625 using object_t = typename BasicJsonType::object_t;
3626
3627 static constexpr bool value =
3629 (std::is_move_assignable<ConstructibleObjectType>::value ||
3630 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3631 (is_constructible<typename ConstructibleObjectType::key_type,
3632 typename object_t::key_type>::value &&
3633 std::is_same <
3634 typename object_t::mapped_type,
3635 typename ConstructibleObjectType::mapped_type >::value)) ||
3636 (has_from_json<BasicJsonType,
3637 typename ConstructibleObjectType::mapped_type>::value ||
3639 BasicJsonType,
3640 typename ConstructibleObjectType::mapped_type >::value);
3641};
3642
3643template<typename BasicJsonType, typename ConstructibleObjectType>
3645 : is_constructible_object_type_impl<BasicJsonType,
3646 ConstructibleObjectType> {};
3647
3648template<typename BasicJsonType, typename CompatibleStringType>
3654
3655template<typename BasicJsonType, typename ConstructibleStringType>
3657{
3658 static constexpr auto value =
3659 is_constructible<ConstructibleStringType,
3660 typename BasicJsonType::string_t>::value;
3661};
3662
3663template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3664struct is_compatible_array_type_impl : std::false_type {};
3665
3666template<typename BasicJsonType, typename CompatibleArrayType>
3668 BasicJsonType, CompatibleArrayType,
3669 enable_if_t <
3670 is_detected<iterator_t, CompatibleArrayType>::value&&
3671 is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
3672// special case for types like std::filesystem::path whose iterator's value_type are themselves
3673// c.f. https://github.com/nlohmann/json/pull/3073
3674 !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3675{
3676 static constexpr bool value =
3677 is_constructible<BasicJsonType,
3679};
3680
3681template<typename BasicJsonType, typename CompatibleArrayType>
3683 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3684
3685template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3686struct is_constructible_array_type_impl : std::false_type {};
3687
3688template<typename BasicJsonType, typename ConstructibleArrayType>
3690 BasicJsonType, ConstructibleArrayType,
3691 enable_if_t<std::is_same<ConstructibleArrayType,
3692 typename BasicJsonType::value_type>::value >>
3693 : std::true_type {};
3694
3695template<typename BasicJsonType, typename ConstructibleArrayType>
3697 BasicJsonType, ConstructibleArrayType,
3698 enable_if_t < !std::is_same<ConstructibleArrayType,
3699 typename BasicJsonType::value_type>::value&&
3700 !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3701 is_default_constructible<ConstructibleArrayType>::value&&
3702(std::is_move_assignable<ConstructibleArrayType>::value ||
3703 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3704is_detected<iterator_t, ConstructibleArrayType>::value&&
3705is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3706is_detected<range_value_t, ConstructibleArrayType>::value&&
3707// special case for types like std::filesystem::path whose iterator's value_type are themselves
3708// c.f. https://github.com/nlohmann/json/pull/3073
3709!std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3711 detected_t<range_value_t, ConstructibleArrayType >>::value >>
3712{
3714
3715 static constexpr bool value =
3716 std::is_same<value_type,
3717 typename BasicJsonType::array_t::value_type>::value ||
3718 has_from_json<BasicJsonType,
3721 BasicJsonType,
3723};
3724
3725template<typename BasicJsonType, typename ConstructibleArrayType>
3727 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3728
3729template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3730 typename = void>
3731struct is_compatible_integer_type_impl : std::false_type {};
3732
3733template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3735 RealIntegerType, CompatibleNumberIntegerType,
3736 enable_if_t < std::is_integral<RealIntegerType>::value&&
3737 std::is_integral<CompatibleNumberIntegerType>::value&&
3738 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3739{
3740 // is there an assert somewhere on overflows?
3741 using RealLimits = std::numeric_limits<RealIntegerType>;
3742 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3743
3744 static constexpr auto value =
3745 is_constructible<RealIntegerType,
3746 CompatibleNumberIntegerType>::value &&
3747 CompatibleLimits::is_integer &&
3748 RealLimits::is_signed == CompatibleLimits::is_signed;
3749};
3750
3751template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3753 : is_compatible_integer_type_impl<RealIntegerType,
3754 CompatibleNumberIntegerType> {};
3755
3756template<typename BasicJsonType, typename CompatibleType, typename = void>
3757struct is_compatible_type_impl: std::false_type {};
3758
3759template<typename BasicJsonType, typename CompatibleType>
3761 BasicJsonType, CompatibleType,
3762 enable_if_t<is_complete_type<CompatibleType>::value >>
3763{
3764 static constexpr bool value =
3766};
3767
3768template<typename BasicJsonType, typename CompatibleType>
3770 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3771
3772template<typename T1, typename T2>
3773struct is_constructible_tuple : std::false_type {};
3774
3775template<typename T1, typename... Args>
3776struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3777
3778// a naive helper to check if a type is an ordered_map (exploits the fact that
3779// ordered_map inherits capacity() from std::vector)
3780template <typename T>
3782{
3783 using one = char;
3784
3785 struct two
3786 {
3787 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3788 };
3789
3790 template <typename C> static one test( decltype(&C::capacity) ) ;
3791 template <typename C> static two test(...);
3792
3793 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3794};
3795
3796// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3797template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3799{
3800 return static_cast<T>(value);
3801}
3802
3803template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3805{
3806 return value;
3807}
3808
3809} // namespace detail
3810} // namespace nlohmann
3811
3812// #include <nlohmann/detail/value_t.hpp>
3813
3814
3815#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
3816#include <experimental/filesystem>
3817namespace nlohmann::detail
3818{
3819namespace std_fs = std::experimental::filesystem;
3820} // namespace nlohmann::detail
3821#elif JSON_HAS_FILESYSTEM
3822#include <filesystem>
3823namespace nlohmann::detail
3824{
3825namespace std_fs = std::filesystem;
3826} // namespace nlohmann::detail
3827#endif
3828
3829namespace nlohmann
3830{
3831namespace detail
3832{
3833template<typename BasicJsonType>
3834void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3835{
3836 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3837 {
3838 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
3839 }
3840 n = nullptr;
3841}
3842
3843// overloads for basic_json template parameters
3844template < typename BasicJsonType, typename ArithmeticType,
3845 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3846 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3847 int > = 0 >
3848void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3849{
3850 switch (static_cast<value_t>(j))
3851 {
3853 {
3854 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3855 break;
3856 }
3858 {
3859 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3860 break;
3861 }
3863 {
3864 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3865 break;
3866 }
3867
3868 case value_t::null:
3869 case value_t::object:
3870 case value_t::array:
3871 case value_t::string:
3872 case value_t::boolean:
3873 case value_t::binary:
3874 case value_t::discarded:
3875 default:
3876 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
3877 }
3878}
3879
3880template<typename BasicJsonType>
3881void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3882{
3883 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3884 {
3885 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
3886 }
3887 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3888}
3889
3890template<typename BasicJsonType>
3891void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3892{
3893 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3894 {
3895 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3896 }
3897 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3898}
3899
3900template <
3901 typename BasicJsonType, typename ConstructibleStringType,
3902 enable_if_t <
3904 !std::is_same<typename BasicJsonType::string_t,
3905 ConstructibleStringType>::value,
3906 int > = 0 >
3907void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3908{
3909 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3910 {
3911 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3912 }
3913
3914 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3915}
3916
3917template<typename BasicJsonType>
3918void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3919{
3920 get_arithmetic_value(j, val);
3921}
3922
3923template<typename BasicJsonType>
3924void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3925{
3926 get_arithmetic_value(j, val);
3927}
3928
3929template<typename BasicJsonType>
3930void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3931{
3932 get_arithmetic_value(j, val);
3933}
3934
3935template<typename BasicJsonType, typename EnumType,
3936 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3937void from_json(const BasicJsonType& j, EnumType& e)
3938{
3939 typename std::underlying_type<EnumType>::type val;
3940 get_arithmetic_value(j, val);
3941 e = static_cast<EnumType>(val);
3942}
3943
3944// forward_list doesn't have an insert method
3945template<typename BasicJsonType, typename T, typename Allocator,
3946 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3947void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
3948{
3949 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3950 {
3951 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
3952 }
3953 l.clear();
3954 std::transform(j.rbegin(), j.rend(),
3955 std::front_inserter(l), [](const BasicJsonType & i)
3956 {
3957 return i.template get<T>();
3958 });
3959}
3960
3961// valarray doesn't have an insert method
3962template<typename BasicJsonType, typename T,
3963 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
3964void from_json(const BasicJsonType& j, std::valarray<T>& l)
3965{
3966 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
3967 {
3968 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
3969 }
3970 l.resize(j.size());
3971 std::transform(j.begin(), j.end(), std::begin(l),
3972 [](const BasicJsonType & elem)
3973 {
3974 return elem.template get<T>();
3975 });
3976}
3977
3978template<typename BasicJsonType, typename T, std::size_t N>
3979auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3980-> decltype(j.template get<T>(), void())
3981{
3982 for (std::size_t i = 0; i < N; ++i)
3983 {
3984 arr[i] = j.at(i).template get<T>();
3985 }
3986}
3987
3988template<typename BasicJsonType>
3989void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
3990{
3991 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
3992}
3993
3994template<typename BasicJsonType, typename T, std::size_t N>
3995auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
3996 priority_tag<2> /*unused*/)
3997-> decltype(j.template get<T>(), void())
3998{
3999 for (std::size_t i = 0; i < N; ++i)
4000 {
4001 arr[i] = j.at(i).template get<T>();
4002 }
4003}
4004
4005template<typename BasicJsonType, typename ConstructibleArrayType,
4007 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4008 int> = 0>
4009auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4010-> decltype(
4011 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4012 j.template get<typename ConstructibleArrayType::value_type>(),
4013 void())
4014{
4015 using std::end;
4016
4017 ConstructibleArrayType ret;
4018 ret.reserve(j.size());
4019 std::transform(j.begin(), j.end(),
4020 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4021 {
4022 // get<BasicJsonType>() returns *this, this won't call a from_json
4023 // method when value_type is BasicJsonType
4024 return i.template get<typename ConstructibleArrayType::value_type>();
4025 });
4026 arr = std::move(ret);
4027}
4028
4029template<typename BasicJsonType, typename ConstructibleArrayType,
4031 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4032 int> = 0>
4033void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4034 priority_tag<0> /*unused*/)
4035{
4036 using std::end;
4037
4038 ConstructibleArrayType ret;
4039 std::transform(
4040 j.begin(), j.end(), std::inserter(ret, end(ret)),
4041 [](const BasicJsonType & i)
4042 {
4043 // get<BasicJsonType>() returns *this, this won't call a from_json
4044 // method when value_type is BasicJsonType
4045 return i.template get<typename ConstructibleArrayType::value_type>();
4046 });
4047 arr = std::move(ret);
4048}
4049
4050template < typename BasicJsonType, typename ConstructibleArrayType,
4051 enable_if_t <
4052 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4053 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4055 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4056 !is_basic_json<ConstructibleArrayType>::value,
4057 int > = 0 >
4058auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4059-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4060j.template get<typename ConstructibleArrayType::value_type>(),
4061void())
4062{
4063 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4064 {
4065 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4066 }
4067
4068 from_json_array_impl(j, arr, priority_tag<3> {});
4069}
4070
4071template < typename BasicJsonType, typename T, std::size_t... Idx >
4072std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4073 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4074{
4075 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4076}
4077
4078template < typename BasicJsonType, typename T, std::size_t N >
4079auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4080-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4081{
4082 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4083 {
4084 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4085 }
4086
4087 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4088}
4089
4090template<typename BasicJsonType>
4091void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4092{
4093 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4094 {
4095 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
4096 }
4097
4098 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4099}
4100
4101template<typename BasicJsonType, typename ConstructibleObjectType,
4102 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4103void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4104{
4105 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4106 {
4107 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
4108 }
4109
4110 ConstructibleObjectType ret;
4111 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4112 using value_type = typename ConstructibleObjectType::value_type;
4113 std::transform(
4114 inner_object->begin(), inner_object->end(),
4115 std::inserter(ret, ret.begin()),
4116 [](typename BasicJsonType::object_t::value_type const & p)
4117 {
4118 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4119 });
4120 obj = std::move(ret);
4121}
4122
4123// overload for arithmetic types, not chosen for basic_json template arguments
4124// (BooleanType, etc..); note: Is it really necessary to provide explicit
4125// overloads for boolean_t etc. in case of a custom BooleanType which is not
4126// an arithmetic type?
4127template < typename BasicJsonType, typename ArithmeticType,
4128 enable_if_t <
4129 std::is_arithmetic<ArithmeticType>::value&&
4130 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4131 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4132 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4133 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4134 int > = 0 >
4135void from_json(const BasicJsonType& j, ArithmeticType& val)
4136{
4137 switch (static_cast<value_t>(j))
4138 {
4140 {
4141 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4142 break;
4143 }
4145 {
4146 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4147 break;
4148 }
4150 {
4151 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4152 break;
4153 }
4154 case value_t::boolean:
4155 {
4156 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4157 break;
4158 }
4159
4160 case value_t::null:
4161 case value_t::object:
4162 case value_t::array:
4163 case value_t::string:
4164 case value_t::binary:
4165 case value_t::discarded:
4166 default:
4167 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4168 }
4169}
4170
4171template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4172std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4173{
4174 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4175}
4176
4177template < typename BasicJsonType, class A1, class A2 >
4178std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4179{
4180 return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4181 std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4182}
4183
4184template<typename BasicJsonType, typename A1, typename A2>
4185void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4186{
4187 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4188}
4189
4190template<typename BasicJsonType, typename... Args>
4191std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4192{
4193 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4194}
4195
4196template<typename BasicJsonType, typename... Args>
4197void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4198{
4199 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4200}
4201
4202template<typename BasicJsonType, typename TupleRelated>
4203auto from_json(BasicJsonType&& j, TupleRelated&& t)
4204-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4205{
4206 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4207 {
4208 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4209 }
4210
4211 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4212}
4213
4214template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4215 typename = enable_if_t < !std::is_constructible <
4216 typename BasicJsonType::string_t, Key >::value >>
4217void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4218{
4219 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4220 {
4221 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4222 }
4223 m.clear();
4224 for (const auto& p : j)
4225 {
4226 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4227 {
4228 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4229 }
4230 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4231 }
4232}
4233
4234template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4235 typename = enable_if_t < !std::is_constructible <
4236 typename BasicJsonType::string_t, Key >::value >>
4237void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4238{
4239 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4240 {
4241 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4242 }
4243 m.clear();
4244 for (const auto& p : j)
4245 {
4246 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4247 {
4248 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4249 }
4250 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4251 }
4252}
4253
4254#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
4255template<typename BasicJsonType>
4256void from_json(const BasicJsonType& j, std_fs::path& p)
4257{
4258 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4259 {
4260 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4261 }
4262 p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4263}
4264#endif
4265
4267{
4268 template<typename BasicJsonType, typename T>
4269 auto operator()(const BasicJsonType& j, T&& val) const
4270 noexcept(noexcept(from_json(j, std::forward<T>(val))))
4271 -> decltype(from_json(j, std::forward<T>(val)))
4272 {
4273 return from_json(j, std::forward<T>(val));
4274 }
4275};
4276} // namespace detail
4277
4281namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4282{
4283constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4284} // namespace
4285} // namespace nlohmann
4286
4287// #include <nlohmann/detail/conversions/to_json.hpp>
4288
4289
4290#include <algorithm> // copy
4291#include <iterator> // begin, end
4292#include <string> // string
4293#include <tuple> // tuple, get
4294#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4295#include <utility> // move, forward, declval, pair
4296#include <valarray> // valarray
4297#include <vector> // vector
4298
4299// #include <nlohmann/detail/macro_scope.hpp>
4300
4301// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4302
4303
4304#include <cstddef> // size_t
4305#include <iterator> // input_iterator_tag
4306#include <string> // string, to_string
4307#include <tuple> // tuple_size, get, tuple_element
4308#include <utility> // move
4309
4310// #include <nlohmann/detail/meta/type_traits.hpp>
4311
4312// #include <nlohmann/detail/value_t.hpp>
4313
4314
4315namespace nlohmann
4316{
4317namespace detail
4318{
4319template<typename string_type>
4320void int_to_string( string_type& target, std::size_t value )
4321{
4322 // For ADL
4323 using std::to_string;
4324 target = to_string(value);
4325}
4326template<typename IteratorType> class iteration_proxy_value
4327{
4328 public:
4329 using difference_type = std::ptrdiff_t;
4333 using iterator_category = std::input_iterator_tag;
4334 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4335
4336 private:
4338 IteratorType anchor;
4340 std::size_t array_index = 0;
4342 mutable std::size_t array_index_last = 0;
4347
4348 public:
4349 explicit iteration_proxy_value(IteratorType it) noexcept
4350 : anchor(std::move(it))
4351 {}
4352
4355 {
4356 return *this;
4357 }
4358
4361 {
4362 ++anchor;
4363 ++array_index;
4364
4365 return *this;
4366 }
4367
4370 {
4371 return anchor == o.anchor;
4372 }
4373
4376 {
4377 return anchor != o.anchor;
4378 }
4379
4381 const string_type& key() const
4382 {
4383 JSON_ASSERT(anchor.m_object != nullptr);
4384
4385 switch (anchor.m_object->type())
4386 {
4387 // use integer array index as key
4388 case value_t::array:
4389 {
4391 {
4394 }
4395 return array_index_str;
4396 }
4397
4398 // use key from the object
4399 case value_t::object:
4400 return anchor.key();
4401
4402 // use an empty key for all primitive types
4403 case value_t::null:
4404 case value_t::string:
4405 case value_t::boolean:
4409 case value_t::binary:
4410 case value_t::discarded:
4411 default:
4412 return empty_str;
4413 }
4414 }
4415
4417 typename IteratorType::reference value() const
4418 {
4419 return anchor.value();
4420 }
4421};
4422
4424template<typename IteratorType> class iteration_proxy
4425{
4426 private:
4428 typename IteratorType::reference container;
4429
4430 public:
4432 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4433 : container(cont) {}
4434
4440
4446};
4447// Structured Bindings Support
4448// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4449// And see https://github.com/nlohmann/json/pull/1391
4450template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4452{
4453 return i.key();
4454}
4455// Structured Bindings Support
4456// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4457// And see https://github.com/nlohmann/json/pull/1391
4458template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4459auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4460{
4461 return i.value();
4462}
4463} // namespace detail
4464} // namespace nlohmann
4465
4466// The Addition to the STD Namespace is required to add
4467// Structured Bindings Support to the iteration_proxy_value class
4468// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4469// And see https://github.com/nlohmann/json/pull/1391
4470namespace std
4471{
4472#if defined(__clang__)
4473 // Fix: https://github.com/nlohmann/json/issues/1401
4474 #pragma clang diagnostic push
4475 #pragma clang diagnostic ignored "-Wmismatched-tags"
4476#endif
4477template<typename IteratorType>
4478class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4479 : public std::integral_constant<std::size_t, 2> {};
4480
4481template<std::size_t N, typename IteratorType>
4482class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4483{
4484 public:
4485 using type = decltype(
4486 get<N>(std::declval <
4488};
4489#if defined(__clang__)
4490 #pragma clang diagnostic pop
4491#endif
4492} // namespace std
4493
4494// #include <nlohmann/detail/meta/cpp_future.hpp>
4495
4496// #include <nlohmann/detail/meta/type_traits.hpp>
4497
4498// #include <nlohmann/detail/value_t.hpp>
4499
4500
4501#if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4502#include <experimental/filesystem>
4503namespace nlohmann::detail
4504{
4505namespace std_fs = std::experimental::filesystem;
4506} // namespace nlohmann::detail
4507#elif JSON_HAS_FILESYSTEM
4508#include <filesystem>
4509namespace nlohmann::detail
4510{
4511namespace std_fs = std::filesystem;
4512} // namespace nlohmann::detail
4513#endif
4514
4515namespace nlohmann
4516{
4517namespace detail
4518{
4520// constructors //
4522
4523/*
4524 * Note all external_constructor<>::construct functions need to call
4525 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4526 * allocated value (e.g., a string). See bug issue
4527 * https://github.com/nlohmann/json/issues/2865 for more information.
4528 */
4529
4530template<value_t> struct external_constructor;
4531
4532template<>
4534{
4535 template<typename BasicJsonType>
4536 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4537 {
4538 j.m_value.destroy(j.m_type);
4539 j.m_type = value_t::boolean;
4540 j.m_value = b;
4541 j.assert_invariant();
4542 }
4543};
4544
4545template<>
4547{
4548 template<typename BasicJsonType>
4549 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4550 {
4551 j.m_value.destroy(j.m_type);
4552 j.m_type = value_t::string;
4553 j.m_value = s;
4554 j.assert_invariant();
4555 }
4556
4557 template<typename BasicJsonType>
4558 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4559 {
4560 j.m_value.destroy(j.m_type);
4561 j.m_type = value_t::string;
4562 j.m_value = std::move(s);
4563 j.assert_invariant();
4564 }
4565
4566 template < typename BasicJsonType, typename CompatibleStringType,
4567 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4568 int > = 0 >
4569 static void construct(BasicJsonType& j, const CompatibleStringType& str)
4570 {
4571 j.m_value.destroy(j.m_type);
4572 j.m_type = value_t::string;
4573 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4574 j.assert_invariant();
4575 }
4576};
4577
4578template<>
4580{
4581 template<typename BasicJsonType>
4582 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4583 {
4584 j.m_value.destroy(j.m_type);
4585 j.m_type = value_t::binary;
4586 j.m_value = typename BasicJsonType::binary_t(b);
4587 j.assert_invariant();
4588 }
4589
4590 template<typename BasicJsonType>
4591 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4592 {
4593 j.m_value.destroy(j.m_type);
4594 j.m_type = value_t::binary;
4595 j.m_value = typename BasicJsonType::binary_t(std::move(b));
4596 j.assert_invariant();
4597 }
4598};
4599
4600template<>
4602{
4603 template<typename BasicJsonType>
4604 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4605 {
4606 j.m_value.destroy(j.m_type);
4607 j.m_type = value_t::number_float;
4608 j.m_value = val;
4609 j.assert_invariant();
4610 }
4611};
4612
4613template<>
4615{
4616 template<typename BasicJsonType>
4617 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4618 {
4619 j.m_value.destroy(j.m_type);
4620 j.m_type = value_t::number_unsigned;
4621 j.m_value = val;
4622 j.assert_invariant();
4623 }
4624};
4625
4626template<>
4628{
4629 template<typename BasicJsonType>
4630 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4631 {
4632 j.m_value.destroy(j.m_type);
4633 j.m_type = value_t::number_integer;
4634 j.m_value = val;
4635 j.assert_invariant();
4636 }
4637};
4638
4639template<>
4641{
4642 template<typename BasicJsonType>
4643 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4644 {
4645 j.m_value.destroy(j.m_type);
4646 j.m_type = value_t::array;
4647 j.m_value = arr;
4648 j.set_parents();
4649 j.assert_invariant();
4650 }
4651
4652 template<typename BasicJsonType>
4653 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4654 {
4655 j.m_value.destroy(j.m_type);
4656 j.m_type = value_t::array;
4657 j.m_value = std::move(arr);
4658 j.set_parents();
4659 j.assert_invariant();
4660 }
4661
4662 template < typename BasicJsonType, typename CompatibleArrayType,
4663 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4664 int > = 0 >
4665 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4666 {
4667 using std::begin;
4668 using std::end;
4669
4670 j.m_value.destroy(j.m_type);
4671 j.m_type = value_t::array;
4672 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4673 j.set_parents();
4674 j.assert_invariant();
4675 }
4676
4677 template<typename BasicJsonType>
4678 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4679 {
4680 j.m_value.destroy(j.m_type);
4681 j.m_type = value_t::array;
4682 j.m_value = value_t::array;
4683 j.m_value.array->reserve(arr.size());
4684 for (const bool x : arr)
4685 {
4686 j.m_value.array->push_back(x);
4687 j.set_parent(j.m_value.array->back());
4688 }
4689 j.assert_invariant();
4690 }
4691
4692 template<typename BasicJsonType, typename T,
4694 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4695 {
4696 j.m_value.destroy(j.m_type);
4697 j.m_type = value_t::array;
4698 j.m_value = value_t::array;
4699 j.m_value.array->resize(arr.size());
4700 if (arr.size() > 0)
4701 {
4702 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4703 }
4704 j.set_parents();
4705 j.assert_invariant();
4706 }
4707};
4708
4709template<>
4711{
4712 template<typename BasicJsonType>
4713 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4714 {
4715 j.m_value.destroy(j.m_type);
4716 j.m_type = value_t::object;
4717 j.m_value = obj;
4718 j.set_parents();
4719 j.assert_invariant();
4720 }
4721
4722 template<typename BasicJsonType>
4723 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4724 {
4725 j.m_value.destroy(j.m_type);
4726 j.m_type = value_t::object;
4727 j.m_value = std::move(obj);
4728 j.set_parents();
4729 j.assert_invariant();
4730 }
4731
4732 template < typename BasicJsonType, typename CompatibleObjectType,
4733 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4734 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4735 {
4736 using std::begin;
4737 using std::end;
4738
4739 j.m_value.destroy(j.m_type);
4740 j.m_type = value_t::object;
4741 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4742 j.set_parents();
4743 j.assert_invariant();
4744 }
4745};
4746
4748// to_json //
4750
4751template<typename BasicJsonType, typename T,
4752 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4753void to_json(BasicJsonType& j, T b) noexcept
4754{
4756}
4757
4758template<typename BasicJsonType, typename CompatibleString,
4759 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4760void to_json(BasicJsonType& j, const CompatibleString& s)
4761{
4763}
4764
4765template<typename BasicJsonType>
4766void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4767{
4769}
4770
4771template<typename BasicJsonType, typename FloatType,
4772 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4773void to_json(BasicJsonType& j, FloatType val) noexcept
4774{
4775 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4776}
4777
4778template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4779 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4780void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4781{
4782 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4783}
4784
4785template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4786 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4787void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4788{
4789 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4790}
4791
4792template<typename BasicJsonType, typename EnumType,
4793 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4794void to_json(BasicJsonType& j, EnumType e) noexcept
4795{
4796 using underlying_type = typename std::underlying_type<EnumType>::type;
4797 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4798}
4799
4800template<typename BasicJsonType>
4801void to_json(BasicJsonType& j, const std::vector<bool>& e)
4802{
4804}
4805
4806template < typename BasicJsonType, typename CompatibleArrayType,
4807 enable_if_t < is_compatible_array_type<BasicJsonType,
4808 CompatibleArrayType>::value&&
4809 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4811 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4812 !is_basic_json<CompatibleArrayType>::value,
4813 int > = 0 >
4814void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4815{
4817}
4818
4819template<typename BasicJsonType>
4820void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4821{
4823}
4824
4825template<typename BasicJsonType, typename T,
4826 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4827void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4828{
4830}
4831
4832template<typename BasicJsonType>
4833void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4834{
4836}
4837
4838template < typename BasicJsonType, typename CompatibleObjectType,
4839 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4840void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4841{
4843}
4844
4845template<typename BasicJsonType>
4846void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4847{
4849}
4850
4851template <
4852 typename BasicJsonType, typename T, std::size_t N,
4853 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4854 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4855 int > = 0 >
4856void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4857{
4859}
4860
4861template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4862void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4863{
4864 j = { p.first, p.second };
4865}
4866
4867// for https://github.com/nlohmann/json/pull/1134
4868template<typename BasicJsonType, typename T,
4869 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4870void to_json(BasicJsonType& j, const T& b)
4871{
4872 j = { {b.key(), b.value()} };
4873}
4874
4875template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4876void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4877{
4878 j = { std::get<Idx>(t)... };
4879}
4880
4881template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4882void to_json(BasicJsonType& j, const T& t)
4883{
4884 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4885}
4886
4887#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
4888template<typename BasicJsonType>
4889void to_json(BasicJsonType& j, const std_fs::path& p)
4890{
4891 j = p.string();
4892}
4893#endif
4894
4896{
4897 template<typename BasicJsonType, typename T>
4898 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4899 -> decltype(to_json(j, std::forward<T>(val)), void())
4900 {
4901 return to_json(j, std::forward<T>(val));
4902 }
4903};
4904} // namespace detail
4905
4909namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4910{
4911constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4912} // namespace
4913} // namespace nlohmann
4914
4915// #include <nlohmann/detail/meta/identity_tag.hpp>
4916
4917// #include <nlohmann/detail/meta/type_traits.hpp>
4918
4919
4920namespace nlohmann
4921{
4922
4924template<typename ValueType, typename>
4926{
4929 template<typename BasicJsonType, typename TargetType = ValueType>
4930 static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
4931 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4932 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4933 {
4934 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4935 }
4936
4939 template<typename BasicJsonType, typename TargetType = ValueType>
4940 static auto from_json(BasicJsonType && j) noexcept(
4941 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
4942 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
4943 {
4944 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
4945 }
4946
4949 template<typename BasicJsonType, typename TargetType = ValueType>
4950 static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
4951 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
4952 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
4953 {
4954 ::nlohmann::to_json(j, std::forward<TargetType>(val));
4955 }
4956};
4957} // namespace nlohmann
4958
4959// #include <nlohmann/byte_container_with_subtype.hpp>
4960
4961
4962#include <cstdint> // uint8_t, uint64_t
4963#include <tuple> // tie
4964#include <utility> // move
4965
4966namespace nlohmann
4967{
4968
4971template<typename BinaryType>
4972class byte_container_with_subtype : public BinaryType
4973{
4974 public:
4975 using container_type = BinaryType;
4976 using subtype_type = std::uint64_t;
4977
4980 : container_type()
4981 {}
4982
4985 : container_type(b)
4986 {}
4987
4989 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
4990 : container_type(std::move(b))
4991 {}
4992
4995 : container_type(b)
4996 , m_subtype(subtype_)
4997 , m_has_subtype(true)
4998 {}
4999
5001 byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5002 : container_type(std::move(b))
5003 , m_subtype(subtype_)
5004 , m_has_subtype(true)
5005 {}
5006
5008 {
5009 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5010 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5011 }
5012
5014 {
5015 return !(rhs == *this);
5016 }
5017
5020 void set_subtype(subtype_type subtype_) noexcept
5021 {
5022 m_subtype = subtype_;
5023 m_has_subtype = true;
5024 }
5025
5028 constexpr subtype_type subtype() const noexcept
5029 {
5030 return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
5031 }
5032
5035 constexpr bool has_subtype() const noexcept
5036 {
5037 return m_has_subtype;
5038 }
5039
5042 void clear_subtype() noexcept
5043 {
5044 m_subtype = 0;
5045 m_has_subtype = false;
5046 }
5047
5048 private:
5050 bool m_has_subtype = false;
5051};
5052
5053} // namespace nlohmann
5054
5055// #include <nlohmann/detail/conversions/from_json.hpp>
5056
5057// #include <nlohmann/detail/conversions/to_json.hpp>
5058
5059// #include <nlohmann/detail/exceptions.hpp>
5060
5061// #include <nlohmann/detail/hash.hpp>
5062
5063
5064#include <cstdint> // uint8_t
5065#include <cstddef> // size_t
5066#include <functional> // hash
5067
5068// #include <nlohmann/detail/macro_scope.hpp>
5069
5070// #include <nlohmann/detail/value_t.hpp>
5071
5072
5073namespace nlohmann
5074{
5075namespace detail
5076{
5077
5078// boost::hash_combine
5079inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5080{
5081 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5082 return seed;
5083}
5084
5096template<typename BasicJsonType>
5097std::size_t hash(const BasicJsonType& j)
5098{
5099 using string_t = typename BasicJsonType::string_t;
5100 using number_integer_t = typename BasicJsonType::number_integer_t;
5101 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5102 using number_float_t = typename BasicJsonType::number_float_t;
5103
5104 const auto type = static_cast<std::size_t>(j.type());
5105 switch (j.type())
5106 {
5107 case BasicJsonType::value_t::null:
5108 case BasicJsonType::value_t::discarded:
5109 {
5110 return combine(type, 0);
5111 }
5112
5113 case BasicJsonType::value_t::object:
5114 {
5115 auto seed = combine(type, j.size());
5116 for (const auto& element : j.items())
5117 {
5118 const auto h = std::hash<string_t> {}(element.key());
5119 seed = combine(seed, h);
5120 seed = combine(seed, hash(element.value()));
5121 }
5122 return seed;
5123 }
5124
5125 case BasicJsonType::value_t::array:
5126 {
5127 auto seed = combine(type, j.size());
5128 for (const auto& element : j)
5129 {
5130 seed = combine(seed, hash(element));
5131 }
5132 return seed;
5133 }
5134
5135 case BasicJsonType::value_t::string:
5136 {
5137 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5138 return combine(type, h);
5139 }
5140
5141 case BasicJsonType::value_t::boolean:
5142 {
5143 const auto h = std::hash<bool> {}(j.template get<bool>());
5144 return combine(type, h);
5145 }
5146
5147 case BasicJsonType::value_t::number_integer:
5148 {
5149 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5150 return combine(type, h);
5151 }
5152
5153 case BasicJsonType::value_t::number_unsigned:
5154 {
5155 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5156 return combine(type, h);
5157 }
5158
5159 case BasicJsonType::value_t::number_float:
5160 {
5161 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5162 return combine(type, h);
5163 }
5164
5165 case BasicJsonType::value_t::binary:
5166 {
5167 auto seed = combine(type, j.get_binary().size());
5168 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5169 seed = combine(seed, h);
5170 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5171 for (const auto byte : j.get_binary())
5172 {
5173 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5174 }
5175 return seed;
5176 }
5177
5178 default: // LCOV_EXCL_LINE
5179 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5180 return 0; // LCOV_EXCL_LINE
5181 }
5182}
5183
5184} // namespace detail
5185} // namespace nlohmann
5186
5187// #include <nlohmann/detail/input/binary_reader.hpp>
5188
5189
5190#include <algorithm> // generate_n
5191#include <array> // array
5192#include <cmath> // ldexp
5193#include <cstddef> // size_t
5194#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5195#include <cstdio> // snprintf
5196#include <cstring> // memcpy
5197#include <iterator> // back_inserter
5198#include <limits> // numeric_limits
5199#include <string> // char_traits, string
5200#include <utility> // make_pair, move
5201#include <vector> // vector
5202
5203// #include <nlohmann/detail/exceptions.hpp>
5204
5205// #include <nlohmann/detail/input/input_adapters.hpp>
5206
5207
5208#include <array> // array
5209#include <cstddef> // size_t
5210#include <cstring> // strlen
5211#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5212#include <memory> // shared_ptr, make_shared, addressof
5213#include <numeric> // accumulate
5214#include <string> // string, char_traits
5215#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5216#include <utility> // pair, declval
5217
5218#ifndef JSON_NO_IO
5219 #include <cstdio> // FILE *
5220 #include <istream> // istream
5221#endif // JSON_NO_IO
5222
5223// #include <nlohmann/detail/iterators/iterator_traits.hpp>
5224
5225// #include <nlohmann/detail/macro_scope.hpp>
5226
5227
5228namespace nlohmann
5229{
5230namespace detail
5231{
5234
5236// input adapters //
5238
5239#ifndef JSON_NO_IO
5245{
5246 public:
5247 using char_type = char;
5248
5250 explicit file_input_adapter(std::FILE* f) noexcept
5251 : m_file(f)
5252 {}
5253
5254 // make class move-only
5257 file_input_adapter& operator=(const file_input_adapter&) = delete;
5260
5261 std::char_traits<char>::int_type get_character() noexcept
5262 {
5263 return std::fgetc(m_file);
5264 }
5265
5266 private:
5268 std::FILE* m_file;
5269};
5270
5271
5282{
5283 public:
5284 using char_type = char;
5285
5287 {
5288 // clear stream flags; we use underlying streambuf I/O, do not
5289 // maintain ifstream flags, except eof
5290 if (is != nullptr)
5291 {
5292 is->clear(is->rdstate() & std::ios::eofbit);
5293 }
5294 }
5295
5296 explicit input_stream_adapter(std::istream& i)
5297 : is(&i), sb(i.rdbuf())
5298 {}
5299
5300 // delete because of pointer members
5304
5306 : is(rhs.is), sb(rhs.sb)
5307 {
5308 rhs.is = nullptr;
5309 rhs.sb = nullptr;
5310 }
5311
5312 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5313 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5314 // end up as the same value, e.g. 0xFFFFFFFF.
5315 std::char_traits<char>::int_type get_character()
5316 {
5317 auto res = sb->sbumpc();
5318 // set eof manually, as we don't use the istream interface.
5319 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5320 {
5321 is->clear(is->rdstate() | std::ios::eofbit);
5322 }
5323 return res;
5324 }
5325
5326 private:
5328 std::istream* is = nullptr;
5329 std::streambuf* sb = nullptr;
5330};
5331#endif // JSON_NO_IO
5332
5333// General-purpose iterator-based adapter. It might not be as fast as
5334// theoretically possible for some containers, but it is extremely versatile.
5335template<typename IteratorType>
5337{
5338 public:
5339 using char_type = typename std::iterator_traits<IteratorType>::value_type;
5340
5341 iterator_input_adapter(IteratorType first, IteratorType last)
5342 : current(std::move(first)), end(std::move(last))
5343 {}
5344
5345 typename std::char_traits<char_type>::int_type get_character()
5346 {
5348 {
5349 auto result = std::char_traits<char_type>::to_int_type(*current);
5350 std::advance(current, 1);
5351 return result;
5352 }
5353
5354 return std::char_traits<char_type>::eof();
5355 }
5356
5357 private:
5358 IteratorType current;
5359 IteratorType end;
5360
5361 template<typename BaseInputAdapter, size_t T>
5363
5364 bool empty() const
5365 {
5366 return current == end;
5367 }
5368};
5369
5370
5371template<typename BaseInputAdapter, size_t T>
5373
5374template<typename BaseInputAdapter>
5375struct wide_string_input_helper<BaseInputAdapter, 4>
5376{
5377 // UTF-32
5378 static void fill_buffer(BaseInputAdapter& input,
5379 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5380 size_t& utf8_bytes_index,
5381 size_t& utf8_bytes_filled)
5382 {
5383 utf8_bytes_index = 0;
5384
5385 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5386 {
5387 utf8_bytes[0] = std::char_traits<char>::eof();
5388 utf8_bytes_filled = 1;
5389 }
5390 else
5391 {
5392 // get the current character
5393 const auto wc = input.get_character();
5394
5395 // UTF-32 to UTF-8 encoding
5396 if (wc < 0x80)
5397 {
5398 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5399 utf8_bytes_filled = 1;
5400 }
5401 else if (wc <= 0x7FF)
5402 {
5403 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5404 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5405 utf8_bytes_filled = 2;
5406 }
5407 else if (wc <= 0xFFFF)
5408 {
5409 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5410 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5411 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5412 utf8_bytes_filled = 3;
5413 }
5414 else if (wc <= 0x10FFFF)
5415 {
5416 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5417 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5418 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5419 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5420 utf8_bytes_filled = 4;
5421 }
5422 else
5423 {
5424 // unknown character
5425 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5426 utf8_bytes_filled = 1;
5427 }
5428 }
5429 }
5430};
5431
5432template<typename BaseInputAdapter>
5433struct wide_string_input_helper<BaseInputAdapter, 2>
5434{
5435 // UTF-16
5436 static void fill_buffer(BaseInputAdapter& input,
5437 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5438 size_t& utf8_bytes_index,
5439 size_t& utf8_bytes_filled)
5440 {
5441 utf8_bytes_index = 0;
5442
5443 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5444 {
5445 utf8_bytes[0] = std::char_traits<char>::eof();
5446 utf8_bytes_filled = 1;
5447 }
5448 else
5449 {
5450 // get the current character
5451 const auto wc = input.get_character();
5452
5453 // UTF-16 to UTF-8 encoding
5454 if (wc < 0x80)
5455 {
5456 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5457 utf8_bytes_filled = 1;
5458 }
5459 else if (wc <= 0x7FF)
5460 {
5461 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5462 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5463 utf8_bytes_filled = 2;
5464 }
5465 else if (0xD800 > wc || wc >= 0xE000)
5466 {
5467 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5468 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5469 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5470 utf8_bytes_filled = 3;
5471 }
5472 else
5473 {
5474 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5475 {
5476 const auto wc2 = static_cast<unsigned int>(input.get_character());
5477 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5478 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5479 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5480 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5481 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5482 utf8_bytes_filled = 4;
5483 }
5484 else
5485 {
5486 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5487 utf8_bytes_filled = 1;
5488 }
5489 }
5490 }
5491 }
5492};
5493
5494// Wraps another input apdater to convert wide character types into individual bytes.
5495template<typename BaseInputAdapter, typename WideCharType>
5497{
5498 public:
5499 using char_type = char;
5500
5501 wide_string_input_adapter(BaseInputAdapter base)
5502 : base_adapter(base) {}
5503
5504 typename std::char_traits<char>::int_type get_character() noexcept
5505 {
5506 // check if buffer needs to be filled
5508 {
5509 fill_buffer<sizeof(WideCharType)>();
5510
5513 }
5514
5515 // use buffer
5518 return utf8_bytes[utf8_bytes_index++];
5519 }
5520
5521 private:
5522 BaseInputAdapter base_adapter;
5523
5524 template<size_t T>
5529
5531 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5532
5534 std::size_t utf8_bytes_index = 0;
5536 std::size_t utf8_bytes_filled = 0;
5537};
5538
5539
5540template<typename IteratorType, typename Enable = void>
5542{
5543 using iterator_type = IteratorType;
5544 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5546
5547 static adapter_type create(IteratorType first, IteratorType last)
5548 {
5549 return adapter_type(std::move(first), std::move(last));
5550 }
5551};
5552
5553template<typename T>
5555{
5556 using value_type = typename std::iterator_traits<T>::value_type;
5557 enum
5558 {
5559 value = sizeof(value_type) > 1
5560 };
5561};
5562
5563template<typename IteratorType>
5565{
5566 using iterator_type = IteratorType;
5567 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5570
5571 static adapter_type create(IteratorType first, IteratorType last)
5572 {
5573 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5574 }
5575};
5576
5577// General purpose iterator-based input
5578template<typename IteratorType>
5580{
5582 return factory_type::create(first, last);
5583}
5584
5585// Convenience shorthand from container to iterator
5586// Enables ADL on begin(container) and end(container)
5587// Encloses the using declarations in namespace for not to leak them to outside scope
5588
5589namespace container_input_adapter_factory_impl
5590{
5591
5592using std::begin;
5593using std::end;
5594
5595template<typename ContainerType, typename Enable = void>
5597
5598template<typename ContainerType>
5600 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5601 {
5602 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5603
5604 static adapter_type create(const ContainerType& container)
5605{
5606 return input_adapter(begin(container), end(container));
5607}
5608 };
5609
5610} // namespace container_input_adapter_factory_impl
5611
5612template<typename ContainerType>
5617
5618#ifndef JSON_NO_IO
5619// Special cases with fast paths
5620inline file_input_adapter input_adapter(std::FILE* file)
5621{
5622 return file_input_adapter(file);
5623}
5624
5625inline input_stream_adapter input_adapter(std::istream& stream)
5626{
5627 return input_stream_adapter(stream);
5628}
5629
5630inline input_stream_adapter input_adapter(std::istream&& stream)
5631{
5632 return input_stream_adapter(stream);
5633}
5634#endif // JSON_NO_IO
5635
5636using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5637
5638// Null-delimited strings, and the like.
5639template < typename CharT,
5640 typename std::enable_if <
5641 std::is_pointer<CharT>::value&&
5642 !std::is_array<CharT>::value&&
5643 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5644 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5645 int >::type = 0 >
5647{
5648 auto length = std::strlen(reinterpret_cast<const char*>(b));
5649 const auto* ptr = reinterpret_cast<const char*>(b);
5650 return input_adapter(ptr, ptr + length);
5651}
5652
5653template<typename T, std::size_t N>
5654auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5655{
5656 return input_adapter(array, array + N);
5657}
5658
5659// This class only handles inputs of input_buffer_adapter type.
5660// It's required so that expressions like {ptr, len} can be implicitly cast
5661// to the correct adapter.
5663{
5664 public:
5665 template < typename CharT,
5666 typename std::enable_if <
5667 std::is_pointer<CharT>::value&&
5668 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5669 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5670 int >::type = 0 >
5671 span_input_adapter(CharT b, std::size_t l)
5672 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5673
5674 template<class IteratorType,
5675 typename std::enable_if<
5676 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5677 int>::type = 0>
5678 span_input_adapter(IteratorType first, IteratorType last)
5679 : ia(input_adapter(first, last)) {}
5680
5682 {
5683 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5684 }
5685
5686 private:
5688};
5689} // namespace detail
5690} // namespace nlohmann
5691
5692// #include <nlohmann/detail/input/json_sax.hpp>
5693
5694
5695#include <cstddef>
5696#include <string> // string
5697#include <utility> // move
5698#include <vector> // vector
5699
5700// #include <nlohmann/detail/exceptions.hpp>
5701
5702// #include <nlohmann/detail/macro_scope.hpp>
5703
5704
5705namespace nlohmann
5706{
5707
5716template<typename BasicJsonType>
5718{
5719 using number_integer_t = typename BasicJsonType::number_integer_t;
5720 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5721 using number_float_t = typename BasicJsonType::number_float_t;
5722 using string_t = typename BasicJsonType::string_t;
5723 using binary_t = typename BasicJsonType::binary_t;
5724
5729 virtual bool null() = 0;
5730
5736 virtual bool boolean(bool val) = 0;
5737
5743 virtual bool number_integer(number_integer_t val) = 0;
5744
5750 virtual bool number_unsigned(number_unsigned_t val) = 0;
5751
5758 virtual bool number_float(number_float_t val, const string_t& s) = 0;
5759
5766 virtual bool string(string_t& val) = 0;
5767
5774 virtual bool binary(binary_t& val) = 0;
5775
5782 virtual bool start_object(std::size_t elements) = 0;
5783
5790 virtual bool key(string_t& val) = 0;
5791
5796 virtual bool end_object() = 0;
5797
5804 virtual bool start_array(std::size_t elements) = 0;
5805
5810 virtual bool end_array() = 0;
5811
5819 virtual bool parse_error(std::size_t position,
5820 const std::string& last_token,
5821 const detail::exception& ex) = 0;
5822
5823 json_sax() = default;
5824 json_sax(const json_sax&) = default;
5825 json_sax(json_sax&&) noexcept = default;
5826 json_sax& operator=(const json_sax&) = default;
5827 json_sax& operator=(json_sax&&) noexcept = default;
5828 virtual ~json_sax() = default;
5829};
5830
5831
5832namespace detail
5833{
5847template<typename BasicJsonType>
5849{
5850 public:
5851 using number_integer_t = typename BasicJsonType::number_integer_t;
5852 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5853 using number_float_t = typename BasicJsonType::number_float_t;
5854 using string_t = typename BasicJsonType::string_t;
5855 using binary_t = typename BasicJsonType::binary_t;
5856
5862 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5863 : root(r), allow_exceptions(allow_exceptions_)
5864 {}
5865
5866 // make class move-only
5868 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5870 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5872
5873 bool null()
5874 {
5875 handle_value(nullptr);
5876 return true;
5877 }
5878
5879 bool boolean(bool val)
5880 {
5881 handle_value(val);
5882 return true;
5883 }
5884
5886 {
5887 handle_value(val);
5888 return true;
5889 }
5890
5892 {
5893 handle_value(val);
5894 return true;
5895 }
5896
5897 bool number_float(number_float_t val, const string_t& /*unused*/)
5898 {
5899 handle_value(val);
5900 return true;
5901 }
5902
5903 bool string(string_t& val)
5904 {
5905 handle_value(val);
5906 return true;
5907 }
5908
5909 bool binary(binary_t& val)
5910 {
5911 handle_value(std::move(val));
5912 return true;
5913 }
5914
5915 bool start_object(std::size_t len)
5916 {
5917 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
5918
5919 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
5920 {
5921 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
5922 }
5923
5924 return true;
5925 }
5926
5927 bool key(string_t& val)
5928 {
5929 // add null at given key and store the reference for later
5930 object_element = &(ref_stack.back()->m_value.object->operator[](val));
5931 return true;
5932 }
5933
5935 {
5936 ref_stack.back()->set_parents();
5937 ref_stack.pop_back();
5938 return true;
5939 }
5940
5941 bool start_array(std::size_t len)
5942 {
5943 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
5944
5945 if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
5946 {
5947 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
5948 }
5949
5950 return true;
5951 }
5952
5954 {
5955 ref_stack.back()->set_parents();
5956 ref_stack.pop_back();
5957 return true;
5958 }
5959
5960 template<class Exception>
5961 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
5962 const Exception& ex)
5963 {
5964 errored = true;
5965 static_cast<void>(ex);
5966 if (allow_exceptions)
5967 {
5968 JSON_THROW(ex);
5969 }
5970 return false;
5971 }
5972
5973 constexpr bool is_errored() const
5974 {
5975 return errored;
5976 }
5977
5978 private:
5985 template<typename Value>
5987 BasicJsonType* handle_value(Value&& v)
5988 {
5989 if (ref_stack.empty())
5990 {
5991 root = BasicJsonType(std::forward<Value>(v));
5992 return &root;
5993 }
5994
5995 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
5996
5997 if (ref_stack.back()->is_array())
5998 {
5999 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6000 return &(ref_stack.back()->m_value.array->back());
6001 }
6002
6003 JSON_ASSERT(ref_stack.back()->is_object());
6004 JSON_ASSERT(object_element);
6005 *object_element = BasicJsonType(std::forward<Value>(v));
6006 return object_element;
6007 }
6008
6010 BasicJsonType& root;
6012 std::vector<BasicJsonType*> ref_stack {};
6014 BasicJsonType* object_element = nullptr;
6016 bool errored = false;
6018 const bool allow_exceptions = true;
6019};
6020
6021template<typename BasicJsonType>
6023{
6024 public:
6025 using number_integer_t = typename BasicJsonType::number_integer_t;
6026 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6027 using number_float_t = typename BasicJsonType::number_float_t;
6028 using string_t = typename BasicJsonType::string_t;
6029 using binary_t = typename BasicJsonType::binary_t;
6030 using parser_callback_t = typename BasicJsonType::parser_callback_t;
6031 using parse_event_t = typename BasicJsonType::parse_event_t;
6032
6034 const parser_callback_t cb,
6035 const bool allow_exceptions_ = true)
6036 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6037 {
6038 keep_stack.push_back(true);
6039 }
6040
6041 // make class move-only
6043 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6045 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6047
6048 bool null()
6049 {
6050 handle_value(nullptr);
6051 return true;
6052 }
6053
6054 bool boolean(bool val)
6055 {
6056 handle_value(val);
6057 return true;
6058 }
6059
6061 {
6062 handle_value(val);
6063 return true;
6064 }
6065
6067 {
6068 handle_value(val);
6069 return true;
6070 }
6071
6072 bool number_float(number_float_t val, const string_t& /*unused*/)
6073 {
6074 handle_value(val);
6075 return true;
6076 }
6077
6078 bool string(string_t& val)
6079 {
6080 handle_value(val);
6081 return true;
6082 }
6083
6084 bool binary(binary_t& val)
6085 {
6086 handle_value(std::move(val));
6087 return true;
6088 }
6089
6090 bool start_object(std::size_t len)
6091 {
6092 // check callback for object start
6093 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6094 keep_stack.push_back(keep);
6095
6096 auto val = handle_value(BasicJsonType::value_t::object, true);
6097 ref_stack.push_back(val.second);
6098
6099 // check object limit
6100 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6101 {
6102 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6103 }
6104
6105 return true;
6106 }
6107
6108 bool key(string_t& val)
6109 {
6110 BasicJsonType k = BasicJsonType(val);
6111
6112 // check callback for key
6113 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6114 key_keep_stack.push_back(keep);
6115
6116 // add discarded value at given key and store the reference for later
6117 if (keep && ref_stack.back())
6118 {
6119 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6120 }
6121
6122 return true;
6123 }
6124
6126 {
6127 if (ref_stack.back())
6128 {
6129 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6130 {
6131 // discard object
6132 *ref_stack.back() = discarded;
6133 }
6134 else
6135 {
6136 ref_stack.back()->set_parents();
6137 }
6138 }
6139
6140 JSON_ASSERT(!ref_stack.empty());
6141 JSON_ASSERT(!keep_stack.empty());
6142 ref_stack.pop_back();
6143 keep_stack.pop_back();
6144
6145 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6146 {
6147 // remove discarded value
6148 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6149 {
6150 if (it->is_discarded())
6151 {
6152 ref_stack.back()->erase(it);
6153 break;
6154 }
6155 }
6156 }
6157
6158 return true;
6159 }
6160
6161 bool start_array(std::size_t len)
6162 {
6163 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6164 keep_stack.push_back(keep);
6165
6166 auto val = handle_value(BasicJsonType::value_t::array, true);
6167 ref_stack.push_back(val.second);
6168
6169 // check array limit
6170 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6171 {
6172 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6173 }
6174
6175 return true;
6176 }
6177
6179 {
6180 bool keep = true;
6181
6182 if (ref_stack.back())
6183 {
6184 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6185 if (keep)
6186 {
6187 ref_stack.back()->set_parents();
6188 }
6189 else
6190 {
6191 // discard array
6192 *ref_stack.back() = discarded;
6193 }
6194 }
6195
6196 JSON_ASSERT(!ref_stack.empty());
6197 JSON_ASSERT(!keep_stack.empty());
6198 ref_stack.pop_back();
6199 keep_stack.pop_back();
6200
6201 // remove discarded value
6202 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6203 {
6204 ref_stack.back()->m_value.array->pop_back();
6205 }
6206
6207 return true;
6208 }
6209
6210 template<class Exception>
6211 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6212 const Exception& ex)
6213 {
6214 errored = true;
6215 static_cast<void>(ex);
6216 if (allow_exceptions)
6217 {
6218 JSON_THROW(ex);
6219 }
6220 return false;
6221 }
6222
6223 constexpr bool is_errored() const
6224 {
6225 return errored;
6226 }
6227
6228 private:
6244 template<typename Value>
6245 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6246 {
6247 JSON_ASSERT(!keep_stack.empty());
6248
6249 // do not handle this value if we know it would be added to a discarded
6250 // container
6251 if (!keep_stack.back())
6252 {
6253 return {false, nullptr};
6254 }
6255
6256 // create value
6257 auto value = BasicJsonType(std::forward<Value>(v));
6258
6259 // check callback
6260 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6261
6262 // do not handle this value if we just learnt it shall be discarded
6263 if (!keep)
6264 {
6265 return {false, nullptr};
6266 }
6267
6268 if (ref_stack.empty())
6269 {
6270 root = std::move(value);
6271 return {true, &root};
6272 }
6273
6274 // skip this value if we already decided to skip the parent
6275 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6276 if (!ref_stack.back())
6277 {
6278 return {false, nullptr};
6279 }
6280
6281 // we now only expect arrays and objects
6282 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6283
6284 // array
6285 if (ref_stack.back()->is_array())
6286 {
6287 ref_stack.back()->m_value.array->emplace_back(std::move(value));
6288 return {true, &(ref_stack.back()->m_value.array->back())};
6289 }
6290
6291 // object
6292 JSON_ASSERT(ref_stack.back()->is_object());
6293 // check if we should store an element for the current key
6294 JSON_ASSERT(!key_keep_stack.empty());
6295 const bool store_element = key_keep_stack.back();
6296 key_keep_stack.pop_back();
6297
6298 if (!store_element)
6299 {
6300 return {false, nullptr};
6301 }
6302
6303 JSON_ASSERT(object_element);
6304 *object_element = std::move(value);
6305 return {true, object_element};
6306 }
6307
6309 BasicJsonType& root;
6311 std::vector<BasicJsonType*> ref_stack {};
6313 std::vector<bool> keep_stack {};
6315 std::vector<bool> key_keep_stack {};
6317 BasicJsonType* object_element = nullptr;
6319 bool errored = false;
6321 const parser_callback_t callback = nullptr;
6323 const bool allow_exceptions = true;
6325 BasicJsonType discarded = BasicJsonType::value_t::discarded;
6326};
6327
6328template<typename BasicJsonType>
6330{
6331 public:
6332 using number_integer_t = typename BasicJsonType::number_integer_t;
6333 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6334 using number_float_t = typename BasicJsonType::number_float_t;
6335 using string_t = typename BasicJsonType::string_t;
6336 using binary_t = typename BasicJsonType::binary_t;
6337
6338 bool null()
6339 {
6340 return true;
6341 }
6342
6343 bool boolean(bool /*unused*/)
6344 {
6345 return true;
6346 }
6347
6349 {
6350 return true;
6351 }
6352
6354 {
6355 return true;
6356 }
6357
6358 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6359 {
6360 return true;
6361 }
6362
6363 bool string(string_t& /*unused*/)
6364 {
6365 return true;
6366 }
6367
6368 bool binary(binary_t& /*unused*/)
6369 {
6370 return true;
6371 }
6372
6373 bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
6374 {
6375 return true;
6376 }
6377
6378 bool key(string_t& /*unused*/)
6379 {
6380 return true;
6381 }
6382
6384 {
6385 return true;
6386 }
6387
6388 bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
6389 {
6390 return true;
6391 }
6392
6394 {
6395 return true;
6396 }
6397
6398 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6399 {
6400 return false;
6401 }
6402};
6403} // namespace detail
6404
6405} // namespace nlohmann
6406
6407// #include <nlohmann/detail/input/lexer.hpp>
6408
6409
6410#include <array> // array
6411#include <clocale> // localeconv
6412#include <cstddef> // size_t
6413#include <cstdio> // snprintf
6414#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6415#include <initializer_list> // initializer_list
6416#include <string> // char_traits, string
6417#include <utility> // move
6418#include <vector> // vector
6419
6420// #include <nlohmann/detail/input/input_adapters.hpp>
6421
6422// #include <nlohmann/detail/input/position_t.hpp>
6423
6424// #include <nlohmann/detail/macro_scope.hpp>
6425
6426
6427namespace nlohmann
6428{
6429namespace detail
6430{
6432// lexer //
6434
6435template<typename BasicJsonType>
6437{
6438 public:
6460
6464 static const char* token_type_name(const token_type t) noexcept
6465 {
6466 switch (t)
6467 {
6469 return "<uninitialized>";
6471 return "true literal";
6473 return "false literal";
6475 return "null literal";
6477 return "string literal";
6481 return "number literal";
6483 return "'['";
6485 return "'{'";
6487 return "']'";
6489 return "'}'";
6491 return "':'";
6493 return "','";
6495 return "<parse error>";
6497 return "end of input";
6499 return "'[', '{', or a literal";
6500 // LCOV_EXCL_START
6501 default: // catch non-enum values
6502 return "unknown token";
6503 // LCOV_EXCL_STOP
6504 }
6505 }
6506};
6512template<typename BasicJsonType, typename InputAdapterType>
6513class lexer : public lexer_base<BasicJsonType>
6514{
6515 using number_integer_t = typename BasicJsonType::number_integer_t;
6516 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6517 using number_float_t = typename BasicJsonType::number_float_t;
6518 using string_t = typename BasicJsonType::string_t;
6519 using char_type = typename InputAdapterType::char_type;
6520 using char_int_type = typename std::char_traits<char_type>::int_type;
6521
6522 public:
6524
6525 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6526 : ia(std::move(adapter))
6527 , ignore_comments(ignore_comments_)
6529 {}
6530
6531 // delete because of pointer members
6532 lexer(const lexer&) = delete;
6533 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6534 lexer& operator=(lexer&) = delete;
6535 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6536 ~lexer() = default;
6537
6538 private:
6540 // locales
6542
6545 static char get_decimal_point() noexcept
6546 {
6547 const auto* loc = localeconv();
6548 JSON_ASSERT(loc != nullptr);
6549 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6550 }
6551
6553 // scan functions
6555
6572 {
6573 // this function only makes sense after reading `\u`
6574 JSON_ASSERT(current == 'u');
6575 int codepoint = 0;
6576
6577 const auto factors = { 12u, 8u, 4u, 0u };
6578 for (const auto factor : factors)
6579 {
6580 get();
6581
6582 if (current >= '0' && current <= '9')
6583 {
6584 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6585 }
6586 else if (current >= 'A' && current <= 'F')
6587 {
6588 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6589 }
6590 else if (current >= 'a' && current <= 'f')
6591 {
6592 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6593 }
6594 else
6595 {
6596 return -1;
6597 }
6598 }
6599
6600 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6601 return codepoint;
6602 }
6603
6619 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6620 {
6621 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6622 add(current);
6623
6624 for (auto range = ranges.begin(); range != ranges.end(); ++range)
6625 {
6626 get();
6627 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6628 {
6629 add(current);
6630 }
6631 else
6632 {
6633 error_message = "invalid string: ill-formed UTF-8 byte";
6634 return false;
6635 }
6636 }
6637
6638 return true;
6639 }
6640
6657 {
6658 // reset token_buffer (ignore opening quote)
6659 reset();
6660
6661 // we entered the function by reading an open quote
6662 JSON_ASSERT(current == '\"');
6663
6664 while (true)
6665 {
6666 // get next character
6667 switch (get())
6668 {
6669 // end of file while parsing string
6670 case std::char_traits<char_type>::eof():
6671 {
6672 error_message = "invalid string: missing closing quote";
6673 return token_type::parse_error;
6674 }
6675
6676 // closing quote
6677 case '\"':
6678 {
6679 return token_type::value_string;
6680 }
6681
6682 // escapes
6683 case '\\':
6684 {
6685 switch (get())
6686 {
6687 // quotation mark
6688 case '\"':
6689 add('\"');
6690 break;
6691 // reverse solidus
6692 case '\\':
6693 add('\\');
6694 break;
6695 // solidus
6696 case '/':
6697 add('/');
6698 break;
6699 // backspace
6700 case 'b':
6701 add('\b');
6702 break;
6703 // form feed
6704 case 'f':
6705 add('\f');
6706 break;
6707 // line feed
6708 case 'n':
6709 add('\n');
6710 break;
6711 // carriage return
6712 case 'r':
6713 add('\r');
6714 break;
6715 // tab
6716 case 't':
6717 add('\t');
6718 break;
6719
6720 // unicode escapes
6721 case 'u':
6722 {
6723 const int codepoint1 = get_codepoint();
6724 int codepoint = codepoint1; // start with codepoint1
6725
6726 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6727 {
6728 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6729 return token_type::parse_error;
6730 }
6731
6732 // check if code point is a high surrogate
6733 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6734 {
6735 // expect next \uxxxx entry
6736 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6737 {
6738 const int codepoint2 = get_codepoint();
6739
6740 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6741 {
6742 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6743 return token_type::parse_error;
6744 }
6745
6746 // check if codepoint2 is a low surrogate
6747 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6748 {
6749 // overwrite codepoint
6750 codepoint = static_cast<int>(
6751 // high surrogate occupies the most significant 22 bits
6752 (static_cast<unsigned int>(codepoint1) << 10u)
6753 // low surrogate occupies the least significant 15 bits
6754 + static_cast<unsigned int>(codepoint2)
6755 // there is still the 0xD800, 0xDC00 and 0x10000 noise
6756 // in the result, so we have to subtract with:
6757 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6758 - 0x35FDC00u);
6759 }
6760 else
6761 {
6762 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6763 return token_type::parse_error;
6764 }
6765 }
6766 else
6767 {
6768 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6769 return token_type::parse_error;
6770 }
6771 }
6772 else
6773 {
6774 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6775 {
6776 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6777 return token_type::parse_error;
6778 }
6779 }
6780
6781 // result of the above calculation yields a proper codepoint
6782 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6783
6784 // translate codepoint into bytes
6785 if (codepoint < 0x80)
6786 {
6787 // 1-byte characters: 0xxxxxxx (ASCII)
6788 add(static_cast<char_int_type>(codepoint));
6789 }
6790 else if (codepoint <= 0x7FF)
6791 {
6792 // 2-byte characters: 110xxxxx 10xxxxxx
6793 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6794 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6795 }
6796 else if (codepoint <= 0xFFFF)
6797 {
6798 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6799 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6800 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6801 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6802 }
6803 else
6804 {
6805 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6806 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6807 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
6808 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6809 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6810 }
6811
6812 break;
6813 }
6814
6815 // other characters after escape
6816 default:
6817 error_message = "invalid string: forbidden character after backslash";
6818 return token_type::parse_error;
6819 }
6820
6821 break;
6822 }
6823
6824 // invalid control characters
6825 case 0x00:
6826 {
6827 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6828 return token_type::parse_error;
6829 }
6830
6831 case 0x01:
6832 {
6833 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6834 return token_type::parse_error;
6835 }
6836
6837 case 0x02:
6838 {
6839 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6840 return token_type::parse_error;
6841 }
6842
6843 case 0x03:
6844 {
6845 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6846 return token_type::parse_error;
6847 }
6848
6849 case 0x04:
6850 {
6851 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6852 return token_type::parse_error;
6853 }
6854
6855 case 0x05:
6856 {
6857 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6858 return token_type::parse_error;
6859 }
6860
6861 case 0x06:
6862 {
6863 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6864 return token_type::parse_error;
6865 }
6866
6867 case 0x07:
6868 {
6869 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6870 return token_type::parse_error;
6871 }
6872
6873 case 0x08:
6874 {
6875 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
6876 return token_type::parse_error;
6877 }
6878
6879 case 0x09:
6880 {
6881 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
6882 return token_type::parse_error;
6883 }
6884
6885 case 0x0A:
6886 {
6887 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
6888 return token_type::parse_error;
6889 }
6890
6891 case 0x0B:
6892 {
6893 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
6894 return token_type::parse_error;
6895 }
6896
6897 case 0x0C:
6898 {
6899 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
6900 return token_type::parse_error;
6901 }
6902
6903 case 0x0D:
6904 {
6905 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
6906 return token_type::parse_error;
6907 }
6908
6909 case 0x0E:
6910 {
6911 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
6912 return token_type::parse_error;
6913 }
6914
6915 case 0x0F:
6916 {
6917 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
6918 return token_type::parse_error;
6919 }
6920
6921 case 0x10:
6922 {
6923 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
6924 return token_type::parse_error;
6925 }
6926
6927 case 0x11:
6928 {
6929 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
6930 return token_type::parse_error;
6931 }
6932
6933 case 0x12:
6934 {
6935 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
6936 return token_type::parse_error;
6937 }
6938
6939 case 0x13:
6940 {
6941 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
6942 return token_type::parse_error;
6943 }
6944
6945 case 0x14:
6946 {
6947 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
6948 return token_type::parse_error;
6949 }
6950
6951 case 0x15:
6952 {
6953 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
6954 return token_type::parse_error;
6955 }
6956
6957 case 0x16:
6958 {
6959 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
6960 return token_type::parse_error;
6961 }
6962
6963 case 0x17:
6964 {
6965 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
6966 return token_type::parse_error;
6967 }
6968
6969 case 0x18:
6970 {
6971 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
6972 return token_type::parse_error;
6973 }
6974
6975 case 0x19:
6976 {
6977 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
6978 return token_type::parse_error;
6979 }
6980
6981 case 0x1A:
6982 {
6983 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
6984 return token_type::parse_error;
6985 }
6986
6987 case 0x1B:
6988 {
6989 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
6990 return token_type::parse_error;
6991 }
6992
6993 case 0x1C:
6994 {
6995 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
6996 return token_type::parse_error;
6997 }
6998
6999 case 0x1D:
7000 {
7001 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7002 return token_type::parse_error;
7003 }
7004
7005 case 0x1E:
7006 {
7007 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7008 return token_type::parse_error;
7009 }
7010
7011 case 0x1F:
7012 {
7013 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7014 return token_type::parse_error;
7015 }
7016
7017 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7018 case 0x20:
7019 case 0x21:
7020 case 0x23:
7021 case 0x24:
7022 case 0x25:
7023 case 0x26:
7024 case 0x27:
7025 case 0x28:
7026 case 0x29:
7027 case 0x2A:
7028 case 0x2B:
7029 case 0x2C:
7030 case 0x2D:
7031 case 0x2E:
7032 case 0x2F:
7033 case 0x30:
7034 case 0x31:
7035 case 0x32:
7036 case 0x33:
7037 case 0x34:
7038 case 0x35:
7039 case 0x36:
7040 case 0x37:
7041 case 0x38:
7042 case 0x39:
7043 case 0x3A:
7044 case 0x3B:
7045 case 0x3C:
7046 case 0x3D:
7047 case 0x3E:
7048 case 0x3F:
7049 case 0x40:
7050 case 0x41:
7051 case 0x42:
7052 case 0x43:
7053 case 0x44:
7054 case 0x45:
7055 case 0x46:
7056 case 0x47:
7057 case 0x48:
7058 case 0x49:
7059 case 0x4A:
7060 case 0x4B:
7061 case 0x4C:
7062 case 0x4D:
7063 case 0x4E:
7064 case 0x4F:
7065 case 0x50:
7066 case 0x51:
7067 case 0x52:
7068 case 0x53:
7069 case 0x54:
7070 case 0x55:
7071 case 0x56:
7072 case 0x57:
7073 case 0x58:
7074 case 0x59:
7075 case 0x5A:
7076 case 0x5B:
7077 case 0x5D:
7078 case 0x5E:
7079 case 0x5F:
7080 case 0x60:
7081 case 0x61:
7082 case 0x62:
7083 case 0x63:
7084 case 0x64:
7085 case 0x65:
7086 case 0x66:
7087 case 0x67:
7088 case 0x68:
7089 case 0x69:
7090 case 0x6A:
7091 case 0x6B:
7092 case 0x6C:
7093 case 0x6D:
7094 case 0x6E:
7095 case 0x6F:
7096 case 0x70:
7097 case 0x71:
7098 case 0x72:
7099 case 0x73:
7100 case 0x74:
7101 case 0x75:
7102 case 0x76:
7103 case 0x77:
7104 case 0x78:
7105 case 0x79:
7106 case 0x7A:
7107 case 0x7B:
7108 case 0x7C:
7109 case 0x7D:
7110 case 0x7E:
7111 case 0x7F:
7112 {
7113 add(current);
7114 break;
7115 }
7116
7117 // U+0080..U+07FF: bytes C2..DF 80..BF
7118 case 0xC2:
7119 case 0xC3:
7120 case 0xC4:
7121 case 0xC5:
7122 case 0xC6:
7123 case 0xC7:
7124 case 0xC8:
7125 case 0xC9:
7126 case 0xCA:
7127 case 0xCB:
7128 case 0xCC:
7129 case 0xCD:
7130 case 0xCE:
7131 case 0xCF:
7132 case 0xD0:
7133 case 0xD1:
7134 case 0xD2:
7135 case 0xD3:
7136 case 0xD4:
7137 case 0xD5:
7138 case 0xD6:
7139 case 0xD7:
7140 case 0xD8:
7141 case 0xD9:
7142 case 0xDA:
7143 case 0xDB:
7144 case 0xDC:
7145 case 0xDD:
7146 case 0xDE:
7147 case 0xDF:
7148 {
7149 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7150 {
7151 return token_type::parse_error;
7152 }
7153 break;
7154 }
7155
7156 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7157 case 0xE0:
7158 {
7159 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7160 {
7161 return token_type::parse_error;
7162 }
7163 break;
7164 }
7165
7166 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7167 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7168 case 0xE1:
7169 case 0xE2:
7170 case 0xE3:
7171 case 0xE4:
7172 case 0xE5:
7173 case 0xE6:
7174 case 0xE7:
7175 case 0xE8:
7176 case 0xE9:
7177 case 0xEA:
7178 case 0xEB:
7179 case 0xEC:
7180 case 0xEE:
7181 case 0xEF:
7182 {
7183 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7184 {
7185 return token_type::parse_error;
7186 }
7187 break;
7188 }
7189
7190 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7191 case 0xED:
7192 {
7193 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7194 {
7195 return token_type::parse_error;
7196 }
7197 break;
7198 }
7199
7200 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7201 case 0xF0:
7202 {
7203 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7204 {
7205 return token_type::parse_error;
7206 }
7207 break;
7208 }
7209
7210 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7211 case 0xF1:
7212 case 0xF2:
7213 case 0xF3:
7214 {
7215 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7216 {
7217 return token_type::parse_error;
7218 }
7219 break;
7220 }
7221
7222 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7223 case 0xF4:
7224 {
7225 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7226 {
7227 return token_type::parse_error;
7228 }
7229 break;
7230 }
7231
7232 // remaining bytes (80..C1 and F5..FF) are ill-formed
7233 default:
7234 {
7235 error_message = "invalid string: ill-formed UTF-8 byte";
7236 return token_type::parse_error;
7237 }
7238 }
7239 }
7240 }
7241
7247 {
7248 switch (get())
7249 {
7250 // single-line comments skip input until a newline or EOF is read
7251 case '/':
7252 {
7253 while (true)
7254 {
7255 switch (get())
7256 {
7257 case '\n':
7258 case '\r':
7259 case std::char_traits<char_type>::eof():
7260 case '\0':
7261 return true;
7262
7263 default:
7264 break;
7265 }
7266 }
7267 }
7268
7269 // multi-line comments skip input until */ is read
7270 case '*':
7271 {
7272 while (true)
7273 {
7274 switch (get())
7275 {
7276 case std::char_traits<char_type>::eof():
7277 case '\0':
7278 {
7279 error_message = "invalid comment; missing closing '*/'";
7280 return false;
7281 }
7282
7283 case '*':
7284 {
7285 switch (get())
7286 {
7287 case '/':
7288 return true;
7289
7290 default:
7291 {
7292 unget();
7293 continue;
7294 }
7295 }
7296 }
7297
7298 default:
7299 continue;
7300 }
7301 }
7302 }
7303
7304 // unexpected character after reading '/'
7305 default:
7306 {
7307 error_message = "invalid comment; expecting '/' or '*' after '/'";
7308 return false;
7309 }
7310 }
7311 }
7312
7314 static void strtof(float& f, const char* str, char** endptr) noexcept
7315 {
7316 f = std::strtof(str, endptr);
7317 }
7318
7320 static void strtof(double& f, const char* str, char** endptr) noexcept
7321 {
7322 f = std::strtod(str, endptr);
7323 }
7324
7326 static void strtof(long double& f, const char* str, char** endptr) noexcept
7327 {
7328 f = std::strtold(str, endptr);
7329 }
7330
7371 token_type scan_number() // lgtm [cpp/use-of-goto]
7372 {
7373 // reset token_buffer to store the number's bytes
7374 reset();
7375
7376 // the type of the parsed number; initially set to unsigned; will be
7377 // changed if minus sign, decimal point or exponent is read
7378 token_type number_type = token_type::value_unsigned;
7379
7380 // state (init): we just found out we need to scan a number
7381 switch (current)
7382 {
7383 case '-':
7384 {
7385 add(current);
7386 goto scan_number_minus;
7387 }
7388
7389 case '0':
7390 {
7391 add(current);
7392 goto scan_number_zero;
7393 }
7394
7395 case '1':
7396 case '2':
7397 case '3':
7398 case '4':
7399 case '5':
7400 case '6':
7401 case '7':
7402 case '8':
7403 case '9':
7404 {
7405 add(current);
7406 goto scan_number_any1;
7407 }
7408
7409 // all other characters are rejected outside scan_number()
7410 default: // LCOV_EXCL_LINE
7411 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7412 }
7413
7414scan_number_minus:
7415 // state: we just parsed a leading minus sign
7416 number_type = token_type::value_integer;
7417 switch (get())
7418 {
7419 case '0':
7420 {
7421 add(current);
7422 goto scan_number_zero;
7423 }
7424
7425 case '1':
7426 case '2':
7427 case '3':
7428 case '4':
7429 case '5':
7430 case '6':
7431 case '7':
7432 case '8':
7433 case '9':
7434 {
7435 add(current);
7436 goto scan_number_any1;
7437 }
7438
7439 default:
7440 {
7441 error_message = "invalid number; expected digit after '-'";
7442 return token_type::parse_error;
7443 }
7444 }
7445
7446scan_number_zero:
7447 // state: we just parse a zero (maybe with a leading minus sign)
7448 switch (get())
7449 {
7450 case '.':
7451 {
7453 goto scan_number_decimal1;
7454 }
7455
7456 case 'e':
7457 case 'E':
7458 {
7459 add(current);
7460 goto scan_number_exponent;
7461 }
7462
7463 default:
7464 goto scan_number_done;
7465 }
7466
7467scan_number_any1:
7468 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7469 switch (get())
7470 {
7471 case '0':
7472 case '1':
7473 case '2':
7474 case '3':
7475 case '4':
7476 case '5':
7477 case '6':
7478 case '7':
7479 case '8':
7480 case '9':
7481 {
7482 add(current);
7483 goto scan_number_any1;
7484 }
7485
7486 case '.':
7487 {
7489 goto scan_number_decimal1;
7490 }
7491
7492 case 'e':
7493 case 'E':
7494 {
7495 add(current);
7496 goto scan_number_exponent;
7497 }
7498
7499 default:
7500 goto scan_number_done;
7501 }
7502
7503scan_number_decimal1:
7504 // state: we just parsed a decimal point
7505 number_type = token_type::value_float;
7506 switch (get())
7507 {
7508 case '0':
7509 case '1':
7510 case '2':
7511 case '3':
7512 case '4':
7513 case '5':
7514 case '6':
7515 case '7':
7516 case '8':
7517 case '9':
7518 {
7519 add(current);
7520 goto scan_number_decimal2;
7521 }
7522
7523 default:
7524 {
7525 error_message = "invalid number; expected digit after '.'";
7526 return token_type::parse_error;
7527 }
7528 }
7529
7530scan_number_decimal2:
7531 // we just parsed at least one number after a decimal point
7532 switch (get())
7533 {
7534 case '0':
7535 case '1':
7536 case '2':
7537 case '3':
7538 case '4':
7539 case '5':
7540 case '6':
7541 case '7':
7542 case '8':
7543 case '9':
7544 {
7545 add(current);
7546 goto scan_number_decimal2;
7547 }
7548
7549 case 'e':
7550 case 'E':
7551 {
7552 add(current);
7553 goto scan_number_exponent;
7554 }
7555
7556 default:
7557 goto scan_number_done;
7558 }
7559
7560scan_number_exponent:
7561 // we just parsed an exponent
7562 number_type = token_type::value_float;
7563 switch (get())
7564 {
7565 case '+':
7566 case '-':
7567 {
7568 add(current);
7569 goto scan_number_sign;
7570 }
7571
7572 case '0':
7573 case '1':
7574 case '2':
7575 case '3':
7576 case '4':
7577 case '5':
7578 case '6':
7579 case '7':
7580 case '8':
7581 case '9':
7582 {
7583 add(current);
7584 goto scan_number_any2;
7585 }
7586
7587 default:
7588 {
7590 "invalid number; expected '+', '-', or digit after exponent";
7591 return token_type::parse_error;
7592 }
7593 }
7594
7595scan_number_sign:
7596 // we just parsed an exponent sign
7597 switch (get())
7598 {
7599 case '0':
7600 case '1':
7601 case '2':
7602 case '3':
7603 case '4':
7604 case '5':
7605 case '6':
7606 case '7':
7607 case '8':
7608 case '9':
7609 {
7610 add(current);
7611 goto scan_number_any2;
7612 }
7613
7614 default:
7615 {
7616 error_message = "invalid number; expected digit after exponent sign";
7617 return token_type::parse_error;
7618 }
7619 }
7620
7621scan_number_any2:
7622 // we just parsed a number after the exponent or exponent sign
7623 switch (get())
7624 {
7625 case '0':
7626 case '1':
7627 case '2':
7628 case '3':
7629 case '4':
7630 case '5':
7631 case '6':
7632 case '7':
7633 case '8':
7634 case '9':
7635 {
7636 add(current);
7637 goto scan_number_any2;
7638 }
7639
7640 default:
7641 goto scan_number_done;
7642 }
7643
7644scan_number_done:
7645 // unget the character after the number (we only read it to know that
7646 // we are done scanning a number)
7647 unget();
7648
7649 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7650 errno = 0;
7651
7652 // try to parse integers first and fall back to floats
7653 if (number_type == token_type::value_unsigned)
7654 {
7655 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7656
7657 // we checked the number format before
7658 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7659
7660 if (errno == 0)
7661 {
7662 value_unsigned = static_cast<number_unsigned_t>(x);
7663 if (value_unsigned == x)
7664 {
7665 return token_type::value_unsigned;
7666 }
7667 }
7668 }
7669 else if (number_type == token_type::value_integer)
7670 {
7671 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7672
7673 // we checked the number format before
7674 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7675
7676 if (errno == 0)
7677 {
7678 value_integer = static_cast<number_integer_t>(x);
7679 if (value_integer == x)
7680 {
7681 return token_type::value_integer;
7682 }
7683 }
7684 }
7685
7686 // this code is reached if we parse a floating-point number or if an
7687 // integer conversion above failed
7688 strtof(value_float, token_buffer.data(), &endptr);
7689
7690 // we checked the number format before
7691 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7692
7693 return token_type::value_float;
7694 }
7695
7702 token_type scan_literal(const char_type* literal_text, const std::size_t length,
7703 token_type return_type)
7704 {
7705 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7706 for (std::size_t i = 1; i < length; ++i)
7707 {
7708 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7709 {
7710 error_message = "invalid literal";
7711 return token_type::parse_error;
7712 }
7713 }
7714 return return_type;
7715 }
7716
7718 // input management
7720
7722 void reset() noexcept
7723 {
7724 token_buffer.clear();
7725 token_string.clear();
7726 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7727 }
7728
7729 /*
7730 @brief get next character from the input
7731
7732 This function provides the interface to the used input adapter. It does
7733 not throw in case the input reached EOF, but returns a
7734 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7735 for use in error messages.
7736
7737 @return character read from the input
7738 */
7740 {
7743
7744 if (next_unget)
7745 {
7746 // just reset the next_unget variable and work with current
7747 next_unget = false;
7748 }
7749 else
7750 {
7751 current = ia.get_character();
7752 }
7753
7754 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7755 {
7756 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7757 }
7758
7759 if (current == '\n')
7760 {
7763 }
7764
7765 return current;
7766 }
7767
7776 void unget()
7777 {
7778 next_unget = true;
7779
7781
7782 // in case we "unget" a newline, we have to also decrement the lines_read
7784 {
7785 if (position.lines_read > 0)
7786 {
7788 }
7789 }
7790 else
7791 {
7793 }
7794
7795 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7796 {
7797 JSON_ASSERT(!token_string.empty());
7798 token_string.pop_back();
7799 }
7800 }
7801
7804 {
7805 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7806 }
7807
7808 public:
7810 // value getters
7812
7814 constexpr number_integer_t get_number_integer() const noexcept
7815 {
7816 return value_integer;
7817 }
7818
7820 constexpr number_unsigned_t get_number_unsigned() const noexcept
7821 {
7822 return value_unsigned;
7823 }
7824
7826 constexpr number_float_t get_number_float() const noexcept
7827 {
7828 return value_float;
7829 }
7830
7833 {
7834 return token_buffer;
7835 }
7836
7838 // diagnostics
7840
7842 constexpr position_t get_position() const noexcept
7843 {
7844 return position;
7845 }
7846
7850 std::string get_token_string() const
7851 {
7852 // escape control characters
7853 std::string result;
7854 for (const auto c : token_string)
7855 {
7856 if (static_cast<unsigned char>(c) <= '\x1F')
7857 {
7858 // escape control characters
7859 std::array<char, 9> cs{{}};
7860 static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7861 result += cs.data();
7862 }
7863 else
7864 {
7865 // add character as is
7866 result.push_back(static_cast<std::string::value_type>(c));
7867 }
7868 }
7869
7870 return result;
7871 }
7872
7875 constexpr const char* get_error_message() const noexcept
7876 {
7877 return error_message;
7878 }
7879
7881 // actual scanner
7883
7889 {
7890 if (get() == 0xEF)
7891 {
7892 // check if we completely parse the BOM
7893 return get() == 0xBB && get() == 0xBF;
7894 }
7895
7896 // the first character is not the beginning of the BOM; unget it to
7897 // process is later
7898 unget();
7899 return true;
7900 }
7901
7903 {
7904 do
7905 {
7906 get();
7907 }
7908 while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
7909 }
7910
7912 {
7913 // initially, skip the BOM
7914 if (position.chars_read_total == 0 && !skip_bom())
7915 {
7916 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
7917 return token_type::parse_error;
7918 }
7919
7920 // read next character and ignore whitespace
7922
7923 // ignore comments
7924 while (ignore_comments && current == '/')
7925 {
7926 if (!scan_comment())
7927 {
7928 return token_type::parse_error;
7929 }
7930
7931 // skip following whitespace
7933 }
7934
7935 switch (current)
7936 {
7937 // structural characters
7938 case '[':
7939 return token_type::begin_array;
7940 case ']':
7941 return token_type::end_array;
7942 case '{':
7943 return token_type::begin_object;
7944 case '}':
7945 return token_type::end_object;
7946 case ':':
7947 return token_type::name_separator;
7948 case ',':
7949 return token_type::value_separator;
7950
7951 // literals
7952 case 't':
7953 {
7954 std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}};
7955 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
7956 }
7957 case 'f':
7958 {
7959 std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}};
7960 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
7961 }
7962 case 'n':
7963 {
7964 std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}};
7965 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
7966 }
7967
7968 // string
7969 case '\"':
7970 return scan_string();
7971
7972 // number
7973 case '-':
7974 case '0':
7975 case '1':
7976 case '2':
7977 case '3':
7978 case '4':
7979 case '5':
7980 case '6':
7981 case '7':
7982 case '8':
7983 case '9':
7984 return scan_number();
7985
7986 // end of input (the null byte is needed when parsing from
7987 // string literals)
7988 case '\0':
7989 case std::char_traits<char_type>::eof():
7990 return token_type::end_of_input;
7991
7992 // error
7993 default:
7994 error_message = "invalid literal";
7995 return token_type::parse_error;
7996 }
7997 }
7998
7999 private:
8001 InputAdapterType ia;
8002
8004 const bool ignore_comments = false;
8005
8007 char_int_type current = std::char_traits<char_type>::eof();
8008
8010 bool next_unget = false;
8011
8014
8016 std::vector<char_type> token_string {};
8017
8020
8022 const char* error_message = "";
8023
8024 // number values
8028
8031};
8032} // namespace detail
8033} // namespace nlohmann
8034
8035// #include <nlohmann/detail/macro_scope.hpp>
8036
8037// #include <nlohmann/detail/meta/is_sax.hpp>
8038
8039
8040#include <cstdint> // size_t
8041#include <utility> // declval
8042#include <string> // string
8043
8044// #include <nlohmann/detail/meta/detected.hpp>
8045
8046// #include <nlohmann/detail/meta/type_traits.hpp>
8047
8048
8049namespace nlohmann
8050{
8051namespace detail
8052{
8053template<typename T>
8054using null_function_t = decltype(std::declval<T&>().null());
8055
8056template<typename T>
8058 decltype(std::declval<T&>().boolean(std::declval<bool>()));
8059
8060template<typename T, typename Integer>
8062 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8063
8064template<typename T, typename Unsigned>
8066 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8067
8068template<typename T, typename Float, typename String>
8069using number_float_function_t = decltype(std::declval<T&>().number_float(
8070 std::declval<Float>(), std::declval<const String&>()));
8071
8072template<typename T, typename String>
8074 decltype(std::declval<T&>().string(std::declval<String&>()));
8075
8076template<typename T, typename Binary>
8078 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8079
8080template<typename T>
8082 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8083
8084template<typename T, typename String>
8086 decltype(std::declval<T&>().key(std::declval<String&>()));
8087
8088template<typename T>
8089using end_object_function_t = decltype(std::declval<T&>().end_object());
8090
8091template<typename T>
8093 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8094
8095template<typename T>
8096using end_array_function_t = decltype(std::declval<T&>().end_array());
8097
8098template<typename T, typename Exception>
8099using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8100 std::declval<std::size_t>(), std::declval<const std::string&>(),
8101 std::declval<const Exception&>()));
8102
8103template<typename SAX, typename BasicJsonType>
8105{
8106 private:
8108 "BasicJsonType must be of type basic_json<...>");
8109
8110 using number_integer_t = typename BasicJsonType::number_integer_t;
8111 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8112 using number_float_t = typename BasicJsonType::number_float_t;
8113 using string_t = typename BasicJsonType::string_t;
8114 using binary_t = typename BasicJsonType::binary_t;
8115 using exception_t = typename BasicJsonType::exception;
8116
8117 public:
8118 static constexpr bool value =
8132};
8133
8134template<typename SAX, typename BasicJsonType>
8136{
8137 private:
8139 "BasicJsonType must be of type basic_json<...>");
8140
8141 using number_integer_t = typename BasicJsonType::number_integer_t;
8142 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8143 using number_float_t = typename BasicJsonType::number_float_t;
8144 using string_t = typename BasicJsonType::string_t;
8145 using binary_t = typename BasicJsonType::binary_t;
8146 using exception_t = typename BasicJsonType::exception;
8147
8148 public:
8150 "Missing/invalid function: bool null()");
8152 "Missing/invalid function: bool boolean(bool)");
8154 "Missing/invalid function: bool boolean(bool)");
8155 static_assert(
8158 "Missing/invalid function: bool number_integer(number_integer_t)");
8159 static_assert(
8162 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8163 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8165 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8166 static_assert(
8168 "Missing/invalid function: bool string(string_t&)");
8169 static_assert(
8171 "Missing/invalid function: bool binary(binary_t&)");
8173 "Missing/invalid function: bool start_object(std::size_t)");
8175 "Missing/invalid function: bool key(string_t&)");
8177 "Missing/invalid function: bool end_object()");
8179 "Missing/invalid function: bool start_array(std::size_t)");
8181 "Missing/invalid function: bool end_array()");
8182 static_assert(
8184 "Missing/invalid function: bool parse_error(std::size_t, const "
8185 "std::string&, const exception&)");
8186};
8187} // namespace detail
8188} // namespace nlohmann
8189
8190// #include <nlohmann/detail/meta/type_traits.hpp>
8191
8192// #include <nlohmann/detail/value_t.hpp>
8193
8194
8195namespace nlohmann
8196{
8197namespace detail
8198{
8199
8202{
8203 error,
8204 ignore,
8205 store
8206};
8207
8215static inline bool little_endianness(int num = 1) noexcept
8216{
8217 return *reinterpret_cast<char*>(&num) == 1;
8218}
8219
8220
8222// binary reader //
8224
8228template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8230{
8231 using number_integer_t = typename BasicJsonType::number_integer_t;
8232 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8233 using number_float_t = typename BasicJsonType::number_float_t;
8234 using string_t = typename BasicJsonType::string_t;
8235 using binary_t = typename BasicJsonType::binary_t;
8236 using json_sax_t = SAX;
8237 using char_type = typename InputAdapterType::char_type;
8238 using char_int_type = typename std::char_traits<char_type>::int_type;
8239
8240 public:
8246 explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
8247 {
8249 }
8250
8251 // make class move-only
8253 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8255 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8256 ~binary_reader() = default;
8257
8267 bool sax_parse(const input_format_t format,
8268 json_sax_t* sax_,
8269 const bool strict = true,
8270 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8271 {
8272 sax = sax_;
8273 bool result = false;
8274
8275 switch (format)
8276 {
8278 result = parse_bson_internal();
8279 break;
8280
8282 result = parse_cbor_internal(true, tag_handler);
8283 break;
8284
8286 result = parse_msgpack_internal();
8287 break;
8288
8290 result = parse_ubjson_internal();
8291 break;
8292
8293 case input_format_t::json: // LCOV_EXCL_LINE
8294 default: // LCOV_EXCL_LINE
8295 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8296 }
8297
8298 // strict mode: next byte must be EOF
8299 if (result && strict)
8300 {
8301 if (format == input_format_t::ubjson)
8302 {
8304 }
8305 else
8306 {
8307 get();
8308 }
8309
8310 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8311 {
8312 return sax->parse_error(chars_read, get_token_string(),
8313 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
8314 }
8315 }
8316
8317 return result;
8318 }
8319
8320 private:
8322 // BSON //
8324
8330 {
8331 std::int32_t document_size{};
8332 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8333
8334 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
8335 {
8336 return false;
8337 }
8338
8339 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8340 {
8341 return false;
8342 }
8343
8344 return sax->end_object();
8345 }
8346
8355 {
8356 auto out = std::back_inserter(result);
8357 while (true)
8358 {
8359 get();
8361 {
8362 return false;
8363 }
8364 if (current == 0x00)
8365 {
8366 return true;
8367 }
8368 *out++ = static_cast<typename string_t::value_type>(current);
8369 }
8370 }
8371
8383 template<typename NumberType>
8384 bool get_bson_string(const NumberType len, string_t& result)
8385 {
8386 if (JSON_HEDLEY_UNLIKELY(len < 1))
8387 {
8388 auto last_token = get_token_string();
8389 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()));
8390 }
8391
8392 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8393 }
8394
8404 template<typename NumberType>
8405 bool get_bson_binary(const NumberType len, binary_t& result)
8406 {
8407 if (JSON_HEDLEY_UNLIKELY(len < 0))
8408 {
8409 auto last_token = get_token_string();
8410 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()));
8411 }
8412
8413 // All BSON binary values have a subtype
8414 std::uint8_t subtype{};
8415 get_number<std::uint8_t>(input_format_t::bson, subtype);
8416 result.set_subtype(subtype);
8417
8418 return get_binary(input_format_t::bson, len, result);
8419 }
8420
8432 const std::size_t element_type_parse_position)
8433 {
8434 switch (element_type)
8435 {
8436 case 0x01: // double
8437 {
8438 double number{};
8439 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8440 }
8441
8442 case 0x02: // string
8443 {
8444 std::int32_t len{};
8446 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8447 }
8448
8449 case 0x03: // object
8450 {
8451 return parse_bson_internal();
8452 }
8453
8454 case 0x04: // array
8455 {
8456 return parse_bson_array();
8457 }
8458
8459 case 0x05: // binary
8460 {
8461 std::int32_t len{};
8463 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8464 }
8465
8466 case 0x08: // boolean
8467 {
8468 return sax->boolean(get() != 0);
8469 }
8470
8471 case 0x0A: // null
8472 {
8473 return sax->null();
8474 }
8475
8476 case 0x10: // int32
8477 {
8478 std::int32_t value{};
8479 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8480 }
8481
8482 case 0x12: // int64
8483 {
8484 std::int64_t value{};
8485 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8486 }
8487
8488 default: // anything else not supported (yet)
8489 {
8490 std::array<char, 3> cr{{}};
8491 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8492 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()));
8493 }
8494 }
8495 }
8496
8509 bool parse_bson_element_list(const bool is_array)
8510 {
8511 string_t key;
8512
8513 while (auto element_type = get())
8514 {
8516 {
8517 return false;
8518 }
8519
8520 const std::size_t element_type_parse_position = chars_read;
8522 {
8523 return false;
8524 }
8525
8526 if (!is_array && !sax->key(key))
8527 {
8528 return false;
8529 }
8530
8531 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8532 {
8533 return false;
8534 }
8535
8536 // get_bson_cstr only appends
8537 key.clear();
8538 }
8539
8540 return true;
8541 }
8542
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_array(static_cast<std::size_t>(-1))))
8553 {
8554 return false;
8555 }
8556
8557 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8558 {
8559 return false;
8560 }
8561
8562 return sax->end_array();
8563 }
8564
8566 // CBOR //
8568
8577 bool parse_cbor_internal(const bool get_char,
8578 const cbor_tag_handler_t tag_handler)
8579 {
8580 switch (get_char ? get() : current)
8581 {
8582 // EOF
8583 case std::char_traits<char_type>::eof():
8584 return unexpect_eof(input_format_t::cbor, "value");
8585
8586 // Integer 0x00..0x17 (0..23)
8587 case 0x00:
8588 case 0x01:
8589 case 0x02:
8590 case 0x03:
8591 case 0x04:
8592 case 0x05:
8593 case 0x06:
8594 case 0x07:
8595 case 0x08:
8596 case 0x09:
8597 case 0x0A:
8598 case 0x0B:
8599 case 0x0C:
8600 case 0x0D:
8601 case 0x0E:
8602 case 0x0F:
8603 case 0x10:
8604 case 0x11:
8605 case 0x12:
8606 case 0x13:
8607 case 0x14:
8608 case 0x15:
8609 case 0x16:
8610 case 0x17:
8611 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8612
8613 case 0x18: // Unsigned integer (one-byte uint8_t follows)
8614 {
8615 std::uint8_t number{};
8616 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8617 }
8618
8619 case 0x19: // Unsigned integer (two-byte uint16_t follows)
8620 {
8621 std::uint16_t number{};
8622 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8623 }
8624
8625 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8626 {
8627 std::uint32_t number{};
8628 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8629 }
8630
8631 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8632 {
8633 std::uint64_t number{};
8634 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8635 }
8636
8637 // Negative integer -1-0x00..-1-0x17 (-1..-24)
8638 case 0x20:
8639 case 0x21:
8640 case 0x22:
8641 case 0x23:
8642 case 0x24:
8643 case 0x25:
8644 case 0x26:
8645 case 0x27:
8646 case 0x28:
8647 case 0x29:
8648 case 0x2A:
8649 case 0x2B:
8650 case 0x2C:
8651 case 0x2D:
8652 case 0x2E:
8653 case 0x2F:
8654 case 0x30:
8655 case 0x31:
8656 case 0x32:
8657 case 0x33:
8658 case 0x34:
8659 case 0x35:
8660 case 0x36:
8661 case 0x37:
8662 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8663
8664 case 0x38: // Negative integer (one-byte uint8_t follows)
8665 {
8666 std::uint8_t number{};
8667 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8668 }
8669
8670 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8671 {
8672 std::uint16_t number{};
8673 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8674 }
8675
8676 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8677 {
8678 std::uint32_t number{};
8679 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8680 }
8681
8682 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8683 {
8684 std::uint64_t number{};
8685 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8686 - static_cast<number_integer_t>(number));
8687 }
8688
8689 // Binary data (0x00..0x17 bytes follow)
8690 case 0x40:
8691 case 0x41:
8692 case 0x42:
8693 case 0x43:
8694 case 0x44:
8695 case 0x45:
8696 case 0x46:
8697 case 0x47:
8698 case 0x48:
8699 case 0x49:
8700 case 0x4A:
8701 case 0x4B:
8702 case 0x4C:
8703 case 0x4D:
8704 case 0x4E:
8705 case 0x4F:
8706 case 0x50:
8707 case 0x51:
8708 case 0x52:
8709 case 0x53:
8710 case 0x54:
8711 case 0x55:
8712 case 0x56:
8713 case 0x57:
8714 case 0x58: // Binary data (one-byte uint8_t for n follows)
8715 case 0x59: // Binary data (two-byte uint16_t for n follow)
8716 case 0x5A: // Binary data (four-byte uint32_t for n follow)
8717 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8718 case 0x5F: // Binary data (indefinite length)
8719 {
8720 binary_t b;
8721 return get_cbor_binary(b) && sax->binary(b);
8722 }
8723
8724 // UTF-8 string (0x00..0x17 bytes follow)
8725 case 0x60:
8726 case 0x61:
8727 case 0x62:
8728 case 0x63:
8729 case 0x64:
8730 case 0x65:
8731 case 0x66:
8732 case 0x67:
8733 case 0x68:
8734 case 0x69:
8735 case 0x6A:
8736 case 0x6B:
8737 case 0x6C:
8738 case 0x6D:
8739 case 0x6E:
8740 case 0x6F:
8741 case 0x70:
8742 case 0x71:
8743 case 0x72:
8744 case 0x73:
8745 case 0x74:
8746 case 0x75:
8747 case 0x76:
8748 case 0x77:
8749 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8750 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8751 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8752 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8753 case 0x7F: // UTF-8 string (indefinite length)
8754 {
8755 string_t s;
8756 return get_cbor_string(s) && sax->string(s);
8757 }
8758
8759 // array (0x00..0x17 data items follow)
8760 case 0x80:
8761 case 0x81:
8762 case 0x82:
8763 case 0x83:
8764 case 0x84:
8765 case 0x85:
8766 case 0x86:
8767 case 0x87:
8768 case 0x88:
8769 case 0x89:
8770 case 0x8A:
8771 case 0x8B:
8772 case 0x8C:
8773 case 0x8D:
8774 case 0x8E:
8775 case 0x8F:
8776 case 0x90:
8777 case 0x91:
8778 case 0x92:
8779 case 0x93:
8780 case 0x94:
8781 case 0x95:
8782 case 0x96:
8783 case 0x97:
8784 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8785
8786 case 0x98: // array (one-byte uint8_t for n follows)
8787 {
8788 std::uint8_t len{};
8789 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8790 }
8791
8792 case 0x99: // array (two-byte uint16_t for n follow)
8793 {
8794 std::uint16_t len{};
8795 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8796 }
8797
8798 case 0x9A: // array (four-byte uint32_t for n follow)
8799 {
8800 std::uint32_t len{};
8801 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8802 }
8803
8804 case 0x9B: // array (eight-byte uint64_t for n follow)
8805 {
8806 std::uint64_t len{};
8807 return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
8808 }
8809
8810 case 0x9F: // array (indefinite length)
8811 return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);
8812
8813 // map (0x00..0x17 pairs of data items follow)
8814 case 0xA0:
8815 case 0xA1:
8816 case 0xA2:
8817 case 0xA3:
8818 case 0xA4:
8819 case 0xA5:
8820 case 0xA6:
8821 case 0xA7:
8822 case 0xA8:
8823 case 0xA9:
8824 case 0xAA:
8825 case 0xAB:
8826 case 0xAC:
8827 case 0xAD:
8828 case 0xAE:
8829 case 0xAF:
8830 case 0xB0:
8831 case 0xB1:
8832 case 0xB2:
8833 case 0xB3:
8834 case 0xB4:
8835 case 0xB5:
8836 case 0xB6:
8837 case 0xB7:
8838 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8839
8840 case 0xB8: // map (one-byte uint8_t for n follows)
8841 {
8842 std::uint8_t len{};
8843 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8844 }
8845
8846 case 0xB9: // map (two-byte uint16_t for n follow)
8847 {
8848 std::uint16_t len{};
8849 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8850 }
8851
8852 case 0xBA: // map (four-byte uint32_t for n follow)
8853 {
8854 std::uint32_t len{};
8855 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8856 }
8857
8858 case 0xBB: // map (eight-byte uint64_t for n follow)
8859 {
8860 std::uint64_t len{};
8861 return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
8862 }
8863
8864 case 0xBF: // map (indefinite length)
8865 return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);
8866
8867 case 0xC6: // tagged item
8868 case 0xC7:
8869 case 0xC8:
8870 case 0xC9:
8871 case 0xCA:
8872 case 0xCB:
8873 case 0xCC:
8874 case 0xCD:
8875 case 0xCE:
8876 case 0xCF:
8877 case 0xD0:
8878 case 0xD1:
8879 case 0xD2:
8880 case 0xD3:
8881 case 0xD4:
8882 case 0xD8: // tagged item (1 bytes follow)
8883 case 0xD9: // tagged item (2 bytes follow)
8884 case 0xDA: // tagged item (4 bytes follow)
8885 case 0xDB: // tagged item (8 bytes follow)
8886 {
8887 switch (tag_handler)
8888 {
8890 {
8891 auto last_token = get_token_string();
8892 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()));
8893 }
8894
8896 {
8897 // ignore binary subtype
8898 switch (current)
8899 {
8900 case 0xD8:
8901 {
8902 std::uint8_t subtype_to_ignore{};
8903 get_number(input_format_t::cbor, subtype_to_ignore);
8904 break;
8905 }
8906 case 0xD9:
8907 {
8908 std::uint16_t subtype_to_ignore{};
8909 get_number(input_format_t::cbor, subtype_to_ignore);
8910 break;
8911 }
8912 case 0xDA:
8913 {
8914 std::uint32_t subtype_to_ignore{};
8915 get_number(input_format_t::cbor, subtype_to_ignore);
8916 break;
8917 }
8918 case 0xDB:
8919 {
8920 std::uint64_t subtype_to_ignore{};
8921 get_number(input_format_t::cbor, subtype_to_ignore);
8922 break;
8923 }
8924 default:
8925 break;
8926 }
8927 return parse_cbor_internal(true, tag_handler);
8928 }
8929
8931 {
8932 binary_t b;
8933 // use binary subtype and store in binary container
8934 switch (current)
8935 {
8936 case 0xD8:
8937 {
8938 std::uint8_t subtype{};
8940 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
8941 break;
8942 }
8943 case 0xD9:
8944 {
8945 std::uint16_t subtype{};
8947 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
8948 break;
8949 }
8950 case 0xDA:
8951 {
8952 std::uint32_t subtype{};
8954 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
8955 break;
8956 }
8957 case 0xDB:
8958 {
8959 std::uint64_t subtype{};
8961 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
8962 break;
8963 }
8964 default:
8965 return parse_cbor_internal(true, tag_handler);
8966 }
8967 get();
8968 return get_cbor_binary(b) && sax->binary(b);
8969 }
8970
8971 default: // LCOV_EXCL_LINE
8972 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8973 return false; // LCOV_EXCL_LINE
8974 }
8975 }
8976
8977 case 0xF4: // false
8978 return sax->boolean(false);
8979
8980 case 0xF5: // true
8981 return sax->boolean(true);
8982
8983 case 0xF6: // null
8984 return sax->null();
8985
8986 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
8987 {
8988 const auto byte1_raw = get();
8990 {
8991 return false;
8992 }
8993 const auto byte2_raw = get();
8995 {
8996 return false;
8997 }
8998
8999 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9000 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9001
9002 // code from RFC 7049, Appendix D, Figure 3:
9003 // As half-precision floating-point numbers were only added
9004 // to IEEE 754 in 2008, today's programming platforms often
9005 // still only have limited support for them. It is very
9006 // easy to include at least decoding support for them even
9007 // without such support. An example of a small decoder for
9008 // half-precision floating-point numbers in the C language
9009 // is shown in Fig. 3.
9010 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9011 const double val = [&half]
9012 {
9013 const int exp = (half >> 10u) & 0x1Fu;
9014 const unsigned int mant = half & 0x3FFu;
9015 JSON_ASSERT(0 <= exp&& exp <= 32);
9016 JSON_ASSERT(mant <= 1024);
9017 switch (exp)
9018 {
9019 case 0:
9020 return std::ldexp(mant, -24);
9021 case 31:
9022 return (mant == 0)
9023 ? std::numeric_limits<double>::infinity()
9024 : std::numeric_limits<double>::quiet_NaN();
9025 default:
9026 return std::ldexp(mant + 1024, exp - 25);
9027 }
9028 }();
9029 return sax->number_float((half & 0x8000u) != 0
9030 ? static_cast<number_float_t>(-val)
9031 : static_cast<number_float_t>(val), "");
9032 }
9033
9034 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9035 {
9036 float number{};
9037 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9038 }
9039
9040 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9041 {
9042 double number{};
9043 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9044 }
9045
9046 default: // anything else (0xFF is handled inside the other types)
9047 {
9048 auto last_token = get_token_string();
9049 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()));
9050 }
9051 }
9052 }
9053
9066 {
9068 {
9069 return false;
9070 }
9071
9072 switch (current)
9073 {
9074 // UTF-8 string (0x00..0x17 bytes follow)
9075 case 0x60:
9076 case 0x61:
9077 case 0x62:
9078 case 0x63:
9079 case 0x64:
9080 case 0x65:
9081 case 0x66:
9082 case 0x67:
9083 case 0x68:
9084 case 0x69:
9085 case 0x6A:
9086 case 0x6B:
9087 case 0x6C:
9088 case 0x6D:
9089 case 0x6E:
9090 case 0x6F:
9091 case 0x70:
9092 case 0x71:
9093 case 0x72:
9094 case 0x73:
9095 case 0x74:
9096 case 0x75:
9097 case 0x76:
9098 case 0x77:
9099 {
9100 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9101 }
9102
9103 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9104 {
9105 std::uint8_t len{};
9106 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9107 }
9108
9109 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9110 {
9111 std::uint16_t len{};
9112 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9113 }
9114
9115 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9116 {
9117 std::uint32_t len{};
9118 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9119 }
9120
9121 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9122 {
9123 std::uint64_t len{};
9124 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9125 }
9126
9127 case 0x7F: // UTF-8 string (indefinite length)
9128 {
9129 while (get() != 0xFF)
9130 {
9131 string_t chunk;
9132 if (!get_cbor_string(chunk))
9133 {
9134 return false;
9135 }
9136 result.append(chunk);
9137 }
9138 return true;
9139 }
9140
9141 default:
9142 {
9143 auto last_token = get_token_string();
9144 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()));
9145 }
9146 }
9147 }
9148
9161 {
9163 {
9164 return false;
9165 }
9166
9167 switch (current)
9168 {
9169 // Binary data (0x00..0x17 bytes follow)
9170 case 0x40:
9171 case 0x41:
9172 case 0x42:
9173 case 0x43:
9174 case 0x44:
9175 case 0x45:
9176 case 0x46:
9177 case 0x47:
9178 case 0x48:
9179 case 0x49:
9180 case 0x4A:
9181 case 0x4B:
9182 case 0x4C:
9183 case 0x4D:
9184 case 0x4E:
9185 case 0x4F:
9186 case 0x50:
9187 case 0x51:
9188 case 0x52:
9189 case 0x53:
9190 case 0x54:
9191 case 0x55:
9192 case 0x56:
9193 case 0x57:
9194 {
9195 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9196 }
9197
9198 case 0x58: // Binary data (one-byte uint8_t for n follows)
9199 {
9200 std::uint8_t len{};
9201 return get_number(input_format_t::cbor, len) &&
9202 get_binary(input_format_t::cbor, len, result);
9203 }
9204
9205 case 0x59: // Binary data (two-byte uint16_t for n follow)
9206 {
9207 std::uint16_t len{};
9208 return get_number(input_format_t::cbor, len) &&
9209 get_binary(input_format_t::cbor, len, result);
9210 }
9211
9212 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9213 {
9214 std::uint32_t len{};
9215 return get_number(input_format_t::cbor, len) &&
9216 get_binary(input_format_t::cbor, len, result);
9217 }
9218
9219 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9220 {
9221 std::uint64_t len{};
9222 return get_number(input_format_t::cbor, len) &&
9223 get_binary(input_format_t::cbor, len, result);
9224 }
9225
9226 case 0x5F: // Binary data (indefinite length)
9227 {
9228 while (get() != 0xFF)
9229 {
9230 binary_t chunk;
9231 if (!get_cbor_binary(chunk))
9232 {
9233 return false;
9234 }
9235 result.insert(result.end(), chunk.begin(), chunk.end());
9236 }
9237 return true;
9238 }
9239
9240 default:
9241 {
9242 auto last_token = get_token_string();
9243 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()));
9244 }
9245 }
9246 }
9247
9254 bool get_cbor_array(const std::size_t len,
9255 const cbor_tag_handler_t tag_handler)
9256 {
9257 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9258 {
9259 return false;
9260 }
9261
9262 if (len != static_cast<std::size_t>(-1))
9263 {
9264 for (std::size_t i = 0; i < len; ++i)
9265 {
9266 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9267 {
9268 return false;
9269 }
9270 }
9271 }
9272 else
9273 {
9274 while (get() != 0xFF)
9275 {
9276 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9277 {
9278 return false;
9279 }
9280 }
9281 }
9282
9283 return sax->end_array();
9284 }
9285
9292 bool get_cbor_object(const std::size_t len,
9293 const cbor_tag_handler_t tag_handler)
9294 {
9295 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9296 {
9297 return false;
9298 }
9299
9300 if (len != 0)
9301 {
9302 string_t key;
9303 if (len != static_cast<std::size_t>(-1))
9304 {
9305 for (std::size_t i = 0; i < len; ++i)
9306 {
9307 get();
9309 {
9310 return false;
9311 }
9312
9313 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9314 {
9315 return false;
9316 }
9317 key.clear();
9318 }
9319 }
9320 else
9321 {
9322 while (get() != 0xFF)
9323 {
9325 {
9326 return false;
9327 }
9328
9329 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9330 {
9331 return false;
9332 }
9333 key.clear();
9334 }
9335 }
9336 }
9337
9338 return sax->end_object();
9339 }
9340
9342 // MsgPack //
9344
9349 {
9350 switch (get())
9351 {
9352 // EOF
9353 case std::char_traits<char_type>::eof():
9354 return unexpect_eof(input_format_t::msgpack, "value");
9355
9356 // positive fixint
9357 case 0x00:
9358 case 0x01:
9359 case 0x02:
9360 case 0x03:
9361 case 0x04:
9362 case 0x05:
9363 case 0x06:
9364 case 0x07:
9365 case 0x08:
9366 case 0x09:
9367 case 0x0A:
9368 case 0x0B:
9369 case 0x0C:
9370 case 0x0D:
9371 case 0x0E:
9372 case 0x0F:
9373 case 0x10:
9374 case 0x11:
9375 case 0x12:
9376 case 0x13:
9377 case 0x14:
9378 case 0x15:
9379 case 0x16:
9380 case 0x17:
9381 case 0x18:
9382 case 0x19:
9383 case 0x1A:
9384 case 0x1B:
9385 case 0x1C:
9386 case 0x1D:
9387 case 0x1E:
9388 case 0x1F:
9389 case 0x20:
9390 case 0x21:
9391 case 0x22:
9392 case 0x23:
9393 case 0x24:
9394 case 0x25:
9395 case 0x26:
9396 case 0x27:
9397 case 0x28:
9398 case 0x29:
9399 case 0x2A:
9400 case 0x2B:
9401 case 0x2C:
9402 case 0x2D:
9403 case 0x2E:
9404 case 0x2F:
9405 case 0x30:
9406 case 0x31:
9407 case 0x32:
9408 case 0x33:
9409 case 0x34:
9410 case 0x35:
9411 case 0x36:
9412 case 0x37:
9413 case 0x38:
9414 case 0x39:
9415 case 0x3A:
9416 case 0x3B:
9417 case 0x3C:
9418 case 0x3D:
9419 case 0x3E:
9420 case 0x3F:
9421 case 0x40:
9422 case 0x41:
9423 case 0x42:
9424 case 0x43:
9425 case 0x44:
9426 case 0x45:
9427 case 0x46:
9428 case 0x47:
9429 case 0x48:
9430 case 0x49:
9431 case 0x4A:
9432 case 0x4B:
9433 case 0x4C:
9434 case 0x4D:
9435 case 0x4E:
9436 case 0x4F:
9437 case 0x50:
9438 case 0x51:
9439 case 0x52:
9440 case 0x53:
9441 case 0x54:
9442 case 0x55:
9443 case 0x56:
9444 case 0x57:
9445 case 0x58:
9446 case 0x59:
9447 case 0x5A:
9448 case 0x5B:
9449 case 0x5C:
9450 case 0x5D:
9451 case 0x5E:
9452 case 0x5F:
9453 case 0x60:
9454 case 0x61:
9455 case 0x62:
9456 case 0x63:
9457 case 0x64:
9458 case 0x65:
9459 case 0x66:
9460 case 0x67:
9461 case 0x68:
9462 case 0x69:
9463 case 0x6A:
9464 case 0x6B:
9465 case 0x6C:
9466 case 0x6D:
9467 case 0x6E:
9468 case 0x6F:
9469 case 0x70:
9470 case 0x71:
9471 case 0x72:
9472 case 0x73:
9473 case 0x74:
9474 case 0x75:
9475 case 0x76:
9476 case 0x77:
9477 case 0x78:
9478 case 0x79:
9479 case 0x7A:
9480 case 0x7B:
9481 case 0x7C:
9482 case 0x7D:
9483 case 0x7E:
9484 case 0x7F:
9485 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9486
9487 // fixmap
9488 case 0x80:
9489 case 0x81:
9490 case 0x82:
9491 case 0x83:
9492 case 0x84:
9493 case 0x85:
9494 case 0x86:
9495 case 0x87:
9496 case 0x88:
9497 case 0x89:
9498 case 0x8A:
9499 case 0x8B:
9500 case 0x8C:
9501 case 0x8D:
9502 case 0x8E:
9503 case 0x8F:
9504 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9505
9506 // fixarray
9507 case 0x90:
9508 case 0x91:
9509 case 0x92:
9510 case 0x93:
9511 case 0x94:
9512 case 0x95:
9513 case 0x96:
9514 case 0x97:
9515 case 0x98:
9516 case 0x99:
9517 case 0x9A:
9518 case 0x9B:
9519 case 0x9C:
9520 case 0x9D:
9521 case 0x9E:
9522 case 0x9F:
9523 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9524
9525 // fixstr
9526 case 0xA0:
9527 case 0xA1:
9528 case 0xA2:
9529 case 0xA3:
9530 case 0xA4:
9531 case 0xA5:
9532 case 0xA6:
9533 case 0xA7:
9534 case 0xA8:
9535 case 0xA9:
9536 case 0xAA:
9537 case 0xAB:
9538 case 0xAC:
9539 case 0xAD:
9540 case 0xAE:
9541 case 0xAF:
9542 case 0xB0:
9543 case 0xB1:
9544 case 0xB2:
9545 case 0xB3:
9546 case 0xB4:
9547 case 0xB5:
9548 case 0xB6:
9549 case 0xB7:
9550 case 0xB8:
9551 case 0xB9:
9552 case 0xBA:
9553 case 0xBB:
9554 case 0xBC:
9555 case 0xBD:
9556 case 0xBE:
9557 case 0xBF:
9558 case 0xD9: // str 8
9559 case 0xDA: // str 16
9560 case 0xDB: // str 32
9561 {
9562 string_t s;
9563 return get_msgpack_string(s) && sax->string(s);
9564 }
9565
9566 case 0xC0: // nil
9567 return sax->null();
9568
9569 case 0xC2: // false
9570 return sax->boolean(false);
9571
9572 case 0xC3: // true
9573 return sax->boolean(true);
9574
9575 case 0xC4: // bin 8
9576 case 0xC5: // bin 16
9577 case 0xC6: // bin 32
9578 case 0xC7: // ext 8
9579 case 0xC8: // ext 16
9580 case 0xC9: // ext 32
9581 case 0xD4: // fixext 1
9582 case 0xD5: // fixext 2
9583 case 0xD6: // fixext 4
9584 case 0xD7: // fixext 8
9585 case 0xD8: // fixext 16
9586 {
9587 binary_t b;
9588 return get_msgpack_binary(b) && sax->binary(b);
9589 }
9590
9591 case 0xCA: // float 32
9592 {
9593 float number{};
9594 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9595 }
9596
9597 case 0xCB: // float 64
9598 {
9599 double number{};
9600 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9601 }
9602
9603 case 0xCC: // uint 8
9604 {
9605 std::uint8_t number{};
9606 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9607 }
9608
9609 case 0xCD: // uint 16
9610 {
9611 std::uint16_t number{};
9612 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9613 }
9614
9615 case 0xCE: // uint 32
9616 {
9617 std::uint32_t number{};
9618 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9619 }
9620
9621 case 0xCF: // uint 64
9622 {
9623 std::uint64_t number{};
9624 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9625 }
9626
9627 case 0xD0: // int 8
9628 {
9629 std::int8_t number{};
9630 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9631 }
9632
9633 case 0xD1: // int 16
9634 {
9635 std::int16_t number{};
9636 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9637 }
9638
9639 case 0xD2: // int 32
9640 {
9641 std::int32_t number{};
9642 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9643 }
9644
9645 case 0xD3: // int 64
9646 {
9647 std::int64_t number{};
9648 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9649 }
9650
9651 case 0xDC: // array 16
9652 {
9653 std::uint16_t len{};
9654 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9655 }
9656
9657 case 0xDD: // array 32
9658 {
9659 std::uint32_t len{};
9660 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9661 }
9662
9663 case 0xDE: // map 16
9664 {
9665 std::uint16_t len{};
9666 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9667 }
9668
9669 case 0xDF: // map 32
9670 {
9671 std::uint32_t len{};
9672 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9673 }
9674
9675 // negative fixint
9676 case 0xE0:
9677 case 0xE1:
9678 case 0xE2:
9679 case 0xE3:
9680 case 0xE4:
9681 case 0xE5:
9682 case 0xE6:
9683 case 0xE7:
9684 case 0xE8:
9685 case 0xE9:
9686 case 0xEA:
9687 case 0xEB:
9688 case 0xEC:
9689 case 0xED:
9690 case 0xEE:
9691 case 0xEF:
9692 case 0xF0:
9693 case 0xF1:
9694 case 0xF2:
9695 case 0xF3:
9696 case 0xF4:
9697 case 0xF5:
9698 case 0xF6:
9699 case 0xF7:
9700 case 0xF8:
9701 case 0xF9:
9702 case 0xFA:
9703 case 0xFB:
9704 case 0xFC:
9705 case 0xFD:
9706 case 0xFE:
9707 case 0xFF:
9708 return sax->number_integer(static_cast<std::int8_t>(current));
9709
9710 default: // anything else
9711 {
9712 auto last_token = get_token_string();
9713 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()));
9714 }
9715 }
9716 }
9717
9729 {
9731 {
9732 return false;
9733 }
9734
9735 switch (current)
9736 {
9737 // fixstr
9738 case 0xA0:
9739 case 0xA1:
9740 case 0xA2:
9741 case 0xA3:
9742 case 0xA4:
9743 case 0xA5:
9744 case 0xA6:
9745 case 0xA7:
9746 case 0xA8:
9747 case 0xA9:
9748 case 0xAA:
9749 case 0xAB:
9750 case 0xAC:
9751 case 0xAD:
9752 case 0xAE:
9753 case 0xAF:
9754 case 0xB0:
9755 case 0xB1:
9756 case 0xB2:
9757 case 0xB3:
9758 case 0xB4:
9759 case 0xB5:
9760 case 0xB6:
9761 case 0xB7:
9762 case 0xB8:
9763 case 0xB9:
9764 case 0xBA:
9765 case 0xBB:
9766 case 0xBC:
9767 case 0xBD:
9768 case 0xBE:
9769 case 0xBF:
9770 {
9771 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9772 }
9773
9774 case 0xD9: // str 8
9775 {
9776 std::uint8_t len{};
9778 }
9779
9780 case 0xDA: // str 16
9781 {
9782 std::uint16_t len{};
9784 }
9785
9786 case 0xDB: // str 32
9787 {
9788 std::uint32_t len{};
9790 }
9791
9792 default:
9793 {
9794 auto last_token = get_token_string();
9795 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()));
9796 }
9797 }
9798 }
9799
9811 {
9812 // helper function to set the subtype
9813 auto assign_and_return_true = [&result](std::int8_t subtype)
9814 {
9815 result.set_subtype(static_cast<std::uint8_t>(subtype));
9816 return true;
9817 };
9818
9819 switch (current)
9820 {
9821 case 0xC4: // bin 8
9822 {
9823 std::uint8_t len{};
9824 return get_number(input_format_t::msgpack, len) &&
9825 get_binary(input_format_t::msgpack, len, result);
9826 }
9827
9828 case 0xC5: // bin 16
9829 {
9830 std::uint16_t len{};
9831 return get_number(input_format_t::msgpack, len) &&
9832 get_binary(input_format_t::msgpack, len, result);
9833 }
9834
9835 case 0xC6: // bin 32
9836 {
9837 std::uint32_t len{};
9838 return get_number(input_format_t::msgpack, len) &&
9839 get_binary(input_format_t::msgpack, len, result);
9840 }
9841
9842 case 0xC7: // ext 8
9843 {
9844 std::uint8_t len{};
9845 std::int8_t subtype{};
9846 return get_number(input_format_t::msgpack, len) &&
9848 get_binary(input_format_t::msgpack, len, result) &&
9849 assign_and_return_true(subtype);
9850 }
9851
9852 case 0xC8: // ext 16
9853 {
9854 std::uint16_t len{};
9855 std::int8_t subtype{};
9856 return get_number(input_format_t::msgpack, len) &&
9858 get_binary(input_format_t::msgpack, len, result) &&
9859 assign_and_return_true(subtype);
9860 }
9861
9862 case 0xC9: // ext 32
9863 {
9864 std::uint32_t len{};
9865 std::int8_t subtype{};
9866 return get_number(input_format_t::msgpack, len) &&
9868 get_binary(input_format_t::msgpack, len, result) &&
9869 assign_and_return_true(subtype);
9870 }
9871
9872 case 0xD4: // fixext 1
9873 {
9874 std::int8_t subtype{};
9875 return get_number(input_format_t::msgpack, subtype) &&
9876 get_binary(input_format_t::msgpack, 1, result) &&
9877 assign_and_return_true(subtype);
9878 }
9879
9880 case 0xD5: // fixext 2
9881 {
9882 std::int8_t subtype{};
9883 return get_number(input_format_t::msgpack, subtype) &&
9884 get_binary(input_format_t::msgpack, 2, result) &&
9885 assign_and_return_true(subtype);
9886 }
9887
9888 case 0xD6: // fixext 4
9889 {
9890 std::int8_t subtype{};
9891 return get_number(input_format_t::msgpack, subtype) &&
9892 get_binary(input_format_t::msgpack, 4, result) &&
9893 assign_and_return_true(subtype);
9894 }
9895
9896 case 0xD7: // fixext 8
9897 {
9898 std::int8_t subtype{};
9899 return get_number(input_format_t::msgpack, subtype) &&
9900 get_binary(input_format_t::msgpack, 8, result) &&
9901 assign_and_return_true(subtype);
9902 }
9903
9904 case 0xD8: // fixext 16
9905 {
9906 std::int8_t subtype{};
9907 return get_number(input_format_t::msgpack, subtype) &&
9908 get_binary(input_format_t::msgpack, 16, result) &&
9909 assign_and_return_true(subtype);
9910 }
9911
9912 default: // LCOV_EXCL_LINE
9913 return false; // LCOV_EXCL_LINE
9914 }
9915 }
9916
9921 bool get_msgpack_array(const std::size_t len)
9922 {
9923 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9924 {
9925 return false;
9926 }
9927
9928 for (std::size_t i = 0; i < len; ++i)
9929 {
9931 {
9932 return false;
9933 }
9934 }
9935
9936 return sax->end_array();
9937 }
9938
9943 bool get_msgpack_object(const std::size_t len)
9944 {
9945 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9946 {
9947 return false;
9948 }
9949
9950 string_t key;
9951 for (std::size_t i = 0; i < len; ++i)
9952 {
9953 get();
9955 {
9956 return false;
9957 }
9958
9960 {
9961 return false;
9962 }
9963 key.clear();
9964 }
9965
9966 return sax->end_object();
9967 }
9968
9970 // UBJSON //
9972
9980 bool parse_ubjson_internal(const bool get_char = true)
9981 {
9982 return get_ubjson_value(get_char ? get_ignore_noop() : current);
9983 }
9984
9999 bool get_ubjson_string(string_t& result, const bool get_char = true)
10000 {
10001 if (get_char)
10002 {
10003 get(); // TODO(niels): may we ignore N here?
10004 }
10005
10007 {
10008 return false;
10009 }
10010
10011 switch (current)
10012 {
10013 case 'U':
10014 {
10015 std::uint8_t len{};
10017 }
10018
10019 case 'i':
10020 {
10021 std::int8_t len{};
10023 }
10024
10025 case 'I':
10026 {
10027 std::int16_t len{};
10029 }
10030
10031 case 'l':
10032 {
10033 std::int32_t len{};
10035 }
10036
10037 case 'L':
10038 {
10039 std::int64_t len{};
10041 }
10042
10043 default:
10044 auto last_token = get_token_string();
10045 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()));
10046 }
10047 }
10048
10053 bool get_ubjson_size_value(std::size_t& result)
10054 {
10055 switch (get_ignore_noop())
10056 {
10057 case 'U':
10058 {
10059 std::uint8_t number{};
10061 {
10062 return false;
10063 }
10064 result = static_cast<std::size_t>(number);
10065 return true;
10066 }
10067
10068 case 'i':
10069 {
10070 std::int8_t number{};
10072 {
10073 return false;
10074 }
10075 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10076 return true;
10077 }
10078
10079 case 'I':
10080 {
10081 std::int16_t number{};
10083 {
10084 return false;
10085 }
10086 result = static_cast<std::size_t>(number);
10087 return true;
10088 }
10089
10090 case 'l':
10091 {
10092 std::int32_t number{};
10094 {
10095 return false;
10096 }
10097 result = static_cast<std::size_t>(number);
10098 return true;
10099 }
10100
10101 case 'L':
10102 {
10103 std::int64_t number{};
10105 {
10106 return false;
10107 }
10108 result = static_cast<std::size_t>(number);
10109 return true;
10110 }
10111
10112 default:
10113 {
10114 auto last_token = get_token_string();
10115 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()));
10116 }
10117 }
10118 }
10119
10130 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
10131 {
10132 result.first = string_t::npos; // size
10133 result.second = 0; // type
10134
10136
10137 if (current == '$')
10138 {
10139 result.second = get(); // must not ignore 'N', because 'N' maybe the type
10141 {
10142 return false;
10143 }
10144
10146 if (JSON_HEDLEY_UNLIKELY(current != '#'))
10147 {
10149 {
10150 return false;
10151 }
10152 auto last_token = get_token_string();
10153 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()));
10154 }
10155
10156 return get_ubjson_size_value(result.first);
10157 }
10158
10159 if (current == '#')
10160 {
10161 return get_ubjson_size_value(result.first);
10162 }
10163
10164 return true;
10165 }
10166
10172 {
10173 switch (prefix)
10174 {
10175 case std::char_traits<char_type>::eof(): // EOF
10176 return unexpect_eof(input_format_t::ubjson, "value");
10177
10178 case 'T': // true
10179 return sax->boolean(true);
10180 case 'F': // false
10181 return sax->boolean(false);
10182
10183 case 'Z': // null
10184 return sax->null();
10185
10186 case 'U':
10187 {
10188 std::uint8_t number{};
10189 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
10190 }
10191
10192 case 'i':
10193 {
10194 std::int8_t number{};
10195 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10196 }
10197
10198 case 'I':
10199 {
10200 std::int16_t number{};
10201 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10202 }
10203
10204 case 'l':
10205 {
10206 std::int32_t number{};
10207 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10208 }
10209
10210 case 'L':
10211 {
10212 std::int64_t number{};
10213 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10214 }
10215
10216 case 'd':
10217 {
10218 float number{};
10219 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10220 }
10221
10222 case 'D':
10223 {
10224 double number{};
10225 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10226 }
10227
10228 case 'H':
10229 {
10231 }
10232
10233 case 'C': // char
10234 {
10235 get();
10237 {
10238 return false;
10239 }
10240 if (JSON_HEDLEY_UNLIKELY(current > 127))
10241 {
10242 auto last_token = get_token_string();
10243 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()));
10244 }
10245 string_t s(1, static_cast<typename string_t::value_type>(current));
10246 return sax->string(s);
10247 }
10248
10249 case 'S': // string
10250 {
10251 string_t s;
10252 return get_ubjson_string(s) && sax->string(s);
10253 }
10254
10255 case '[': // array
10256 return get_ubjson_array();
10257
10258 case '{': // object
10259 return get_ubjson_object();
10260
10261 default: // anything else
10262 {
10263 auto last_token = get_token_string();
10264 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()));
10265 }
10266 }
10267 }
10268
10273 {
10274 std::pair<std::size_t, char_int_type> size_and_type;
10275 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10276 {
10277 return false;
10278 }
10279
10280 if (size_and_type.first != string_t::npos)
10281 {
10282 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
10283 {
10284 return false;
10285 }
10286
10287 if (size_and_type.second != 0)
10288 {
10289 if (size_and_type.second != 'N')
10290 {
10291 for (std::size_t i = 0; i < size_and_type.first; ++i)
10292 {
10293 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10294 {
10295 return false;
10296 }
10297 }
10298 }
10299 }
10300 else
10301 {
10302 for (std::size_t i = 0; i < size_and_type.first; ++i)
10303 {
10305 {
10306 return false;
10307 }
10308 }
10309 }
10310 }
10311 else
10312 {
10313 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
10314 {
10315 return false;
10316 }
10317
10318 while (current != ']')
10319 {
10321 {
10322 return false;
10323 }
10325 }
10326 }
10327
10328 return sax->end_array();
10329 }
10330
10335 {
10336 std::pair<std::size_t, char_int_type> size_and_type;
10337 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10338 {
10339 return false;
10340 }
10341
10342 string_t key;
10343 if (size_and_type.first != string_t::npos)
10344 {
10345 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
10346 {
10347 return false;
10348 }
10349
10350 if (size_and_type.second != 0)
10351 {
10352 for (std::size_t i = 0; i < size_and_type.first; ++i)
10353 {
10355 {
10356 return false;
10357 }
10358 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10359 {
10360 return false;
10361 }
10362 key.clear();
10363 }
10364 }
10365 else
10366 {
10367 for (std::size_t i = 0; i < size_and_type.first; ++i)
10368 {
10370 {
10371 return false;
10372 }
10374 {
10375 return false;
10376 }
10377 key.clear();
10378 }
10379 }
10380 }
10381 else
10382 {
10383 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
10384 {
10385 return false;
10386 }
10387
10388 while (current != '}')
10389 {
10390 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
10391 {
10392 return false;
10393 }
10395 {
10396 return false;
10397 }
10399 key.clear();
10400 }
10401 }
10402
10403 return sax->end_object();
10404 }
10405
10406 // Note, no reader for UBJSON binary types is implemented because they do
10407 // not exist
10408
10410 {
10411 // get size of following number string
10412 std::size_t size{};
10413 auto res = get_ubjson_size_value(size);
10414 if (JSON_HEDLEY_UNLIKELY(!res))
10415 {
10416 return res;
10417 }
10418
10419 // get number string
10420 std::vector<char> number_vector;
10421 for (std::size_t i = 0; i < size; ++i)
10422 {
10423 get();
10425 {
10426 return false;
10427 }
10428 number_vector.push_back(static_cast<char>(current));
10429 }
10430
10431 // parse number string
10432 using ia_type = decltype(detail::input_adapter(number_vector));
10433 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
10434 const auto result_number = number_lexer.scan();
10435 const auto number_string = number_lexer.get_token_string();
10436 const auto result_remainder = number_lexer.scan();
10437
10438 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
10439
10440 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
10441 {
10442 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()));
10443 }
10444
10445 switch (result_number)
10446 {
10447 case token_type::value_integer:
10448 return sax->number_integer(number_lexer.get_number_integer());
10449 case token_type::value_unsigned:
10450 return sax->number_unsigned(number_lexer.get_number_unsigned());
10451 case token_type::value_float:
10452 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
10453 case token_type::uninitialized:
10454 case token_type::literal_true:
10455 case token_type::literal_false:
10456 case token_type::literal_null:
10457 case token_type::value_string:
10458 case token_type::begin_array:
10459 case token_type::begin_object:
10460 case token_type::end_array:
10461 case token_type::end_object:
10462 case token_type::name_separator:
10463 case token_type::value_separator:
10464 case token_type::parse_error:
10465 case token_type::end_of_input:
10466 case token_type::literal_or_value:
10467 default:
10468 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()));
10469 }
10470 }
10471
10473 // Utility functions //
10475
10486 {
10487 ++chars_read;
10488 return current = ia.get_character();
10489 }
10490
10495 {
10496 do
10497 {
10498 get();
10499 }
10500 while (current == 'N');
10501
10502 return current;
10503 }
10504
10505 /*
10506 @brief read a number from the input
10507
10508 @tparam NumberType the type of the number
10509 @param[in] format the current format (for diagnostics)
10510 @param[out] result number of type @a NumberType
10511
10512 @return whether conversion completed
10513
10514 @note This function needs to respect the system's endianness, because
10515 bytes in CBOR, MessagePack, and UBJSON are stored in network order
10516 (big endian) and therefore need reordering on little endian systems.
10517 */
10518 template<typename NumberType, bool InputIsLittleEndian = false>
10519 bool get_number(const input_format_t format, NumberType& result)
10520 {
10521 // step 1: read input into array with system's byte order
10522 std::array<std::uint8_t, sizeof(NumberType)> vec{};
10523 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
10524 {
10525 get();
10526 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10527 {
10528 return false;
10529 }
10530
10531 // reverse byte order prior to conversion if necessary
10532 if (is_little_endian != InputIsLittleEndian)
10533 {
10534 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10535 }
10536 else
10537 {
10538 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10539 }
10540 }
10541
10542 // step 2: convert array into number of type T and return
10543 std::memcpy(&result, vec.data(), sizeof(NumberType));
10544 return true;
10545 }
10546
10561 template<typename NumberType>
10562 bool get_string(const input_format_t format,
10563 const NumberType len,
10564 string_t& result)
10565 {
10566 bool success = true;
10567 for (NumberType i = 0; i < len; i++)
10568 {
10569 get();
10570 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10571 {
10572 success = false;
10573 break;
10574 }
10575 result.push_back(static_cast<typename string_t::value_type>(current));
10576 }
10577 return success;
10578 }
10579
10594 template<typename NumberType>
10595 bool get_binary(const input_format_t format,
10596 const NumberType len,
10597 binary_t& result)
10598 {
10599 bool success = true;
10600 for (NumberType i = 0; i < len; i++)
10601 {
10602 get();
10603 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10604 {
10605 success = false;
10606 break;
10607 }
10608 result.push_back(static_cast<std::uint8_t>(current));
10609 }
10610 return success;
10611 }
10612
10619 bool unexpect_eof(const input_format_t format, const char* context) const
10620 {
10621 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10622 {
10623 return sax->parse_error(chars_read, "<end of file>",
10624 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
10625 }
10626 return true;
10627 }
10628
10632 std::string get_token_string() const
10633 {
10634 std::array<char, 3> cr{{}};
10635 static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10636 return std::string{cr.data()};
10637 }
10638
10645 std::string exception_message(const input_format_t format,
10646 const std::string& detail,
10647 const std::string& context) const
10648 {
10649 std::string error_msg = "syntax error while parsing ";
10650
10651 switch (format)
10652 {
10654 error_msg += "CBOR";
10655 break;
10656
10658 error_msg += "MessagePack";
10659 break;
10660
10662 error_msg += "UBJSON";
10663 break;
10664
10666 error_msg += "BSON";
10667 break;
10668
10669 case input_format_t::json: // LCOV_EXCL_LINE
10670 default: // LCOV_EXCL_LINE
10671 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10672 }
10673
10674 return error_msg + " " + context + ": " + detail;
10675 }
10676
10677 private:
10679 InputAdapterType ia;
10680
10682 char_int_type current = std::char_traits<char_type>::eof();
10683
10685 std::size_t chars_read = 0;
10686
10689
10691 json_sax_t* sax = nullptr;
10692};
10693} // namespace detail
10694} // namespace nlohmann
10695
10696// #include <nlohmann/detail/input/input_adapters.hpp>
10697
10698// #include <nlohmann/detail/input/lexer.hpp>
10699
10700// #include <nlohmann/detail/input/parser.hpp>
10701
10702
10703#include <cmath> // isfinite
10704#include <cstdint> // uint8_t
10705#include <functional> // function
10706#include <string> // string
10707#include <utility> // move
10708#include <vector> // vector
10709
10710// #include <nlohmann/detail/exceptions.hpp>
10711
10712// #include <nlohmann/detail/input/input_adapters.hpp>
10713
10714// #include <nlohmann/detail/input/json_sax.hpp>
10715
10716// #include <nlohmann/detail/input/lexer.hpp>
10717
10718// #include <nlohmann/detail/macro_scope.hpp>
10719
10720// #include <nlohmann/detail/meta/is_sax.hpp>
10721
10722// #include <nlohmann/detail/value_t.hpp>
10723
10724
10725namespace nlohmann
10726{
10727namespace detail
10728{
10730// parser //
10732
10733enum class parse_event_t : std::uint8_t
10734{
10738 object_end,
10742 array_end,
10744 key,
10746 value
10747};
10748
10749template<typename BasicJsonType>
10751 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
10752
10758template<typename BasicJsonType, typename InputAdapterType>
10760{
10761 using number_integer_t = typename BasicJsonType::number_integer_t;
10762 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10763 using number_float_t = typename BasicJsonType::number_float_t;
10764 using string_t = typename BasicJsonType::string_t;
10767
10768 public:
10770 explicit parser(InputAdapterType&& adapter,
10771 const parser_callback_t<BasicJsonType> cb = nullptr,
10772 const bool allow_exceptions_ = true,
10773 const bool skip_comments = false)
10774 : callback(cb)
10775 , m_lexer(std::move(adapter), skip_comments)
10776 , allow_exceptions(allow_exceptions_)
10777 {
10778 // read first token
10779 get_token();
10780 }
10781
10792 void parse(const bool strict, BasicJsonType& result)
10793 {
10794 if (callback)
10795 {
10797 sax_parse_internal(&sdp);
10798
10799 // in strict mode, input must be completely read
10800 if (strict && (get_token() != token_type::end_of_input))
10801 {
10805 exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10806 }
10807
10808 // in case of an error, return discarded value
10809 if (sdp.is_errored())
10810 {
10811 result = value_t::discarded;
10812 return;
10813 }
10814
10815 // set top-level value to null if it was discarded by the callback
10816 // function
10817 if (result.is_discarded())
10818 {
10819 result = nullptr;
10820 }
10821 }
10822 else
10823 {
10825 sax_parse_internal(&sdp);
10826
10827 // in strict mode, input must be completely read
10828 if (strict && (get_token() != token_type::end_of_input))
10829 {
10832 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10833 }
10834
10835 // in case of an error, return discarded value
10836 if (sdp.is_errored())
10837 {
10838 result = value_t::discarded;
10839 return;
10840 }
10841 }
10842
10843 result.assert_invariant();
10844 }
10845
10852 bool accept(const bool strict = true)
10853 {
10855 return sax_parse(&sax_acceptor, strict);
10856 }
10857
10858 template<typename SAX>
10860 bool sax_parse(SAX* sax, const bool strict = true)
10861 {
10863 const bool result = sax_parse_internal(sax);
10864
10865 // strict mode: next byte must be EOF
10866 if (result && strict && (get_token() != token_type::end_of_input))
10867 {
10868 return sax->parse_error(m_lexer.get_position(),
10870 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10871 }
10872
10873 return result;
10874 }
10875
10876 private:
10877 template<typename SAX>
10879 bool sax_parse_internal(SAX* sax)
10880 {
10881 // stack to remember the hierarchy of structured values we are parsing
10882 // true = array; false = object
10883 std::vector<bool> states;
10884 // value to avoid a goto (see comment where set to true)
10885 bool skip_to_state_evaluation = false;
10886
10887 while (true)
10888 {
10889 if (!skip_to_state_evaluation)
10890 {
10891 // invariant: get_token() was called before each iteration
10892 switch (last_token)
10893 {
10894 case token_type::begin_object:
10895 {
10896 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
10897 {
10898 return false;
10899 }
10900
10901 // closing } -> we are done
10902 if (get_token() == token_type::end_object)
10903 {
10904 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
10905 {
10906 return false;
10907 }
10908 break;
10909 }
10910
10911 // parse key
10912 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
10913 {
10914 return sax->parse_error(m_lexer.get_position(),
10916 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
10917 }
10918 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
10919 {
10920 return false;
10921 }
10922
10923 // parse separator (:)
10924 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
10925 {
10926 return sax->parse_error(m_lexer.get_position(),
10928 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
10929 }
10930
10931 // remember we are now inside an object
10932 states.push_back(false);
10933
10934 // parse values
10935 get_token();
10936 continue;
10937 }
10938
10939 case token_type::begin_array:
10940 {
10941 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
10942 {
10943 return false;
10944 }
10945
10946 // closing ] -> we are done
10947 if (get_token() == token_type::end_array)
10948 {
10949 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
10950 {
10951 return false;
10952 }
10953 break;
10954 }
10955
10956 // remember we are now inside an array
10957 states.push_back(true);
10958
10959 // parse values (no need to call get_token)
10960 continue;
10961 }
10962
10963 case token_type::value_float:
10964 {
10965 const auto res = m_lexer.get_number_float();
10966
10967 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
10968 {
10969 return sax->parse_error(m_lexer.get_position(),
10971 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
10972 }
10973
10974 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
10975 {
10976 return false;
10977 }
10978
10979 break;
10980 }
10981
10982 case token_type::literal_false:
10983 {
10984 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
10985 {
10986 return false;
10987 }
10988 break;
10989 }
10990
10991 case token_type::literal_null:
10992 {
10993 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
10994 {
10995 return false;
10996 }
10997 break;
10998 }
10999
11000 case token_type::literal_true:
11001 {
11002 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11003 {
11004 return false;
11005 }
11006 break;
11007 }
11008
11009 case token_type::value_integer:
11010 {
11011 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11012 {
11013 return false;
11014 }
11015 break;
11016 }
11017
11018 case token_type::value_string:
11019 {
11020 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11021 {
11022 return false;
11023 }
11024 break;
11025 }
11026
11027 case token_type::value_unsigned:
11028 {
11029 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11030 {
11031 return false;
11032 }
11033 break;
11034 }
11035
11036 case token_type::parse_error:
11037 {
11038 // using "uninitialized" to avoid "expected" message
11039 return sax->parse_error(m_lexer.get_position(),
11041 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
11042 }
11043
11044 case token_type::uninitialized:
11045 case token_type::end_array:
11046 case token_type::end_object:
11047 case token_type::name_separator:
11048 case token_type::value_separator:
11049 case token_type::end_of_input:
11050 case token_type::literal_or_value:
11051 default: // the last token was unexpected
11052 {
11053 return sax->parse_error(m_lexer.get_position(),
11055 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
11056 }
11057 }
11058 }
11059 else
11060 {
11061 skip_to_state_evaluation = false;
11062 }
11063
11064 // we reached this line after we successfully parsed a value
11065 if (states.empty())
11066 {
11067 // empty stack: we reached the end of the hierarchy: done
11068 return true;
11069 }
11070
11071 if (states.back()) // array
11072 {
11073 // comma -> next value
11074 if (get_token() == token_type::value_separator)
11075 {
11076 // parse a new value
11077 get_token();
11078 continue;
11079 }
11080
11081 // closing ]
11082 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11083 {
11084 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11085 {
11086 return false;
11087 }
11088
11089 // We are done with this array. Before we can parse a
11090 // new value, we need to evaluate the new state first.
11091 // By setting skip_to_state_evaluation to false, we
11092 // are effectively jumping to the beginning of this if.
11093 JSON_ASSERT(!states.empty());
11094 states.pop_back();
11095 skip_to_state_evaluation = true;
11096 continue;
11097 }
11098
11099 return sax->parse_error(m_lexer.get_position(),
11101 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11102 }
11103
11104 // states.back() is false -> object
11105
11106 // comma -> next value
11107 if (get_token() == token_type::value_separator)
11108 {
11109 // parse key
11110 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11111 {
11112 return sax->parse_error(m_lexer.get_position(),
11114 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11115 }
11116
11117 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11118 {
11119 return false;
11120 }
11121
11122 // parse separator (:)
11123 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11124 {
11125 return sax->parse_error(m_lexer.get_position(),
11127 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11128 }
11129
11130 // parse values
11131 get_token();
11132 continue;
11133 }
11134
11135 // closing }
11136 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11137 {
11138 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11139 {
11140 return false;
11141 }
11142
11143 // We are done with this object. Before we can parse a
11144 // new value, we need to evaluate the new state first.
11145 // By setting skip_to_state_evaluation to false, we
11146 // are effectively jumping to the beginning of this if.
11147 JSON_ASSERT(!states.empty());
11148 states.pop_back();
11149 skip_to_state_evaluation = true;
11150 continue;
11151 }
11152
11153 return sax->parse_error(m_lexer.get_position(),
11155 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11156 }
11157 }
11158
11161 {
11162 return last_token = m_lexer.scan();
11163 }
11164
11165 std::string exception_message(const token_type expected, const std::string& context)
11166 {
11167 std::string error_msg = "syntax error ";
11168
11169 if (!context.empty())
11170 {
11171 error_msg += "while parsing " + context + " ";
11172 }
11173
11174 error_msg += "- ";
11175
11176 if (last_token == token_type::parse_error)
11177 {
11178 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
11179 m_lexer.get_token_string() + "'";
11180 }
11181 else
11182 {
11183 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
11184 }
11185
11186 if (expected != token_type::uninitialized)
11187 {
11188 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
11189 }
11190
11191 return error_msg;
11192 }
11193
11194 private:
11198 token_type last_token = token_type::uninitialized;
11202 const bool allow_exceptions = true;
11203};
11204
11205} // namespace detail
11206} // namespace nlohmann
11207
11208// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11209
11210
11211// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11212
11213
11214#include <cstddef> // ptrdiff_t
11215#include <limits> // numeric_limits
11216
11217// #include <nlohmann/detail/macro_scope.hpp>
11218
11219
11220namespace nlohmann
11221{
11222namespace detail
11223{
11224/*
11225@brief an iterator for primitive JSON types
11226
11227This class models an iterator for primitive JSON types (boolean, number,
11228string). It's only purpose is to allow the iterator/const_iterator classes
11229to "iterate" over primitive values. Internally, the iterator is modeled by
11230a `difference_type` variable. Value begin_value (`0`) models the begin,
11231end_value (`1`) models past the end.
11232*/
11234{
11235 private:
11236 using difference_type = std::ptrdiff_t;
11237 static constexpr difference_type begin_value = 0;
11238 static constexpr difference_type end_value = begin_value + 1;
11239
11242 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11243
11244 public:
11245 constexpr difference_type get_value() const noexcept
11246 {
11247 return m_it;
11248 }
11249
11251 void set_begin() noexcept
11252 {
11253 m_it = begin_value;
11254 }
11255
11257 void set_end() noexcept
11258 {
11259 m_it = end_value;
11260 }
11261
11263 constexpr bool is_begin() const noexcept
11264 {
11265 return m_it == begin_value;
11266 }
11267
11269 constexpr bool is_end() const noexcept
11270 {
11271 return m_it == end_value;
11272 }
11273
11274 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11275 {
11276 return lhs.m_it == rhs.m_it;
11277 }
11278
11279 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11280 {
11281 return lhs.m_it < rhs.m_it;
11282 }
11283
11285 {
11286 auto result = *this;
11287 result += n;
11288 return result;
11289 }
11290
11292 {
11293 return lhs.m_it - rhs.m_it;
11294 }
11295
11297 {
11298 ++m_it;
11299 return *this;
11300 }
11301
11302 primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
11303 {
11304 auto result = *this;
11305 ++m_it;
11306 return result;
11307 }
11308
11310 {
11311 --m_it;
11312 return *this;
11313 }
11314
11315 primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
11316 {
11317 auto result = *this;
11318 --m_it;
11319 return result;
11320 }
11321
11323 {
11324 m_it += n;
11325 return *this;
11326 }
11327
11329 {
11330 m_it -= n;
11331 return *this;
11332 }
11333};
11334} // namespace detail
11335} // namespace nlohmann
11336
11337
11338namespace nlohmann
11339{
11340namespace detail
11341{
11348template<typename BasicJsonType> struct internal_iterator
11349{
11351 typename BasicJsonType::object_t::iterator object_iterator {};
11353 typename BasicJsonType::array_t::iterator array_iterator {};
11356};
11357} // namespace detail
11358} // namespace nlohmann
11359
11360// #include <nlohmann/detail/iterators/iter_impl.hpp>
11361
11362
11363#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
11364#include <type_traits> // conditional, is_const, remove_const
11365
11366// #include <nlohmann/detail/exceptions.hpp>
11367
11368// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11369
11370// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11371
11372// #include <nlohmann/detail/macro_scope.hpp>
11373
11374// #include <nlohmann/detail/meta/cpp_future.hpp>
11375
11376// #include <nlohmann/detail/meta/type_traits.hpp>
11377
11378// #include <nlohmann/detail/value_t.hpp>
11379
11380
11381namespace nlohmann
11382{
11383namespace detail
11384{
11385// forward declare, to be able to friend it later on
11386template<typename IteratorType> class iteration_proxy;
11387template<typename IteratorType> class iteration_proxy_value;
11388
11405template<typename BasicJsonType>
11406class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
11407{
11409 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
11415
11416 using object_t = typename BasicJsonType::object_t;
11417 using array_t = typename BasicJsonType::array_t;
11418 // make sure BasicJsonType is basic_json or const basic_json
11420 "iter_impl only accepts (const) basic_json");
11421
11422 public:
11423
11429 using iterator_category = std::bidirectional_iterator_tag;
11430
11432 using value_type = typename BasicJsonType::value_type;
11434 using difference_type = typename BasicJsonType::difference_type;
11436 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
11437 typename BasicJsonType::const_pointer,
11438 typename BasicJsonType::pointer>::type;
11441 typename std::conditional<std::is_const<BasicJsonType>::value,
11442 typename BasicJsonType::const_reference,
11443 typename BasicJsonType::reference>::type;
11444
11445 iter_impl() = default;
11446 ~iter_impl() = default;
11447 iter_impl(iter_impl&&) noexcept = default;
11448 iter_impl& operator=(iter_impl&&) noexcept = default;
11449
11456 explicit iter_impl(pointer object) noexcept : m_object(object)
11457 {
11458 JSON_ASSERT(m_object != nullptr);
11459
11460 switch (m_object->m_type)
11461 {
11462 case value_t::object:
11463 {
11464 m_it.object_iterator = typename object_t::iterator();
11465 break;
11466 }
11467
11468 case value_t::array:
11469 {
11470 m_it.array_iterator = typename array_t::iterator();
11471 break;
11472 }
11473
11474 case value_t::null:
11475 case value_t::string:
11476 case value_t::boolean:
11480 case value_t::binary:
11481 case value_t::discarded:
11482 default:
11483 {
11485 break;
11486 }
11487 }
11488 }
11489
11507 : m_object(other.m_object), m_it(other.m_it)
11508 {}
11509
11517 {
11518 if (&other != this)
11519 {
11520 m_object = other.m_object;
11521 m_it = other.m_it;
11522 }
11523 return *this;
11524 }
11525
11531 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
11532 : m_object(other.m_object), m_it(other.m_it)
11533 {}
11534
11541 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
11542 {
11543 m_object = other.m_object;
11544 m_it = other.m_it;
11545 return *this;
11546 }
11547
11553 void set_begin() noexcept
11554 {
11555 JSON_ASSERT(m_object != nullptr);
11556
11557 switch (m_object->m_type)
11558 {
11559 case value_t::object:
11560 {
11561 m_it.object_iterator = m_object->m_value.object->begin();
11562 break;
11563 }
11564
11565 case value_t::array:
11566 {
11567 m_it.array_iterator = m_object->m_value.array->begin();
11568 break;
11569 }
11570
11571 case value_t::null:
11572 {
11573 // set to end so begin()==end() is true: null is empty
11575 break;
11576 }
11577
11578 case value_t::string:
11579 case value_t::boolean:
11583 case value_t::binary:
11584 case value_t::discarded:
11585 default:
11586 {
11588 break;
11589 }
11590 }
11591 }
11592
11597 void set_end() noexcept
11598 {
11599 JSON_ASSERT(m_object != nullptr);
11600
11601 switch (m_object->m_type)
11602 {
11603 case value_t::object:
11604 {
11605 m_it.object_iterator = m_object->m_value.object->end();
11606 break;
11607 }
11608
11609 case value_t::array:
11610 {
11611 m_it.array_iterator = m_object->m_value.array->end();
11612 break;
11613 }
11614
11615 case value_t::null:
11616 case value_t::string:
11617 case value_t::boolean:
11621 case value_t::binary:
11622 case value_t::discarded:
11623 default:
11624 {
11626 break;
11627 }
11628 }
11629 }
11630
11631 public:
11637 {
11638 JSON_ASSERT(m_object != nullptr);
11639
11640 switch (m_object->m_type)
11641 {
11642 case value_t::object:
11643 {
11644 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11645 return m_it.object_iterator->second;
11646 }
11647
11648 case value_t::array:
11649 {
11650 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11651 return *m_it.array_iterator;
11652 }
11653
11654 case value_t::null:
11655 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11656
11657 case value_t::string:
11658 case value_t::boolean:
11662 case value_t::binary:
11663 case value_t::discarded:
11664 default:
11665 {
11667 {
11668 return *m_object;
11669 }
11670
11671 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11672 }
11673 }
11674 }
11675
11681 {
11682 JSON_ASSERT(m_object != nullptr);
11683
11684 switch (m_object->m_type)
11685 {
11686 case value_t::object:
11687 {
11688 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11689 return &(m_it.object_iterator->second);
11690 }
11691
11692 case value_t::array:
11693 {
11694 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11695 return &*m_it.array_iterator;
11696 }
11697
11698 case value_t::null:
11699 case value_t::string:
11700 case value_t::boolean:
11704 case value_t::binary:
11705 case value_t::discarded:
11706 default:
11707 {
11709 {
11710 return m_object;
11711 }
11712
11713 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11714 }
11715 }
11716 }
11717
11722 iter_impl const operator++(int) // NOLINT(readability-const-return-type)
11723 {
11724 auto result = *this;
11725 ++(*this);
11726 return result;
11727 }
11728
11734 {
11735 JSON_ASSERT(m_object != nullptr);
11736
11737 switch (m_object->m_type)
11738 {
11739 case value_t::object:
11740 {
11741 std::advance(m_it.object_iterator, 1);
11742 break;
11743 }
11744
11745 case value_t::array:
11746 {
11747 std::advance(m_it.array_iterator, 1);
11748 break;
11749 }
11750
11751 case value_t::null:
11752 case value_t::string:
11753 case value_t::boolean:
11757 case value_t::binary:
11758 case value_t::discarded:
11759 default:
11760 {
11762 break;
11763 }
11764 }
11765
11766 return *this;
11767 }
11768
11773 iter_impl const operator--(int) // NOLINT(readability-const-return-type)
11774 {
11775 auto result = *this;
11776 --(*this);
11777 return result;
11778 }
11779
11785 {
11786 JSON_ASSERT(m_object != nullptr);
11787
11788 switch (m_object->m_type)
11789 {
11790 case value_t::object:
11791 {
11792 std::advance(m_it.object_iterator, -1);
11793 break;
11794 }
11795
11796 case value_t::array:
11797 {
11798 std::advance(m_it.array_iterator, -1);
11799 break;
11800 }
11801
11802 case value_t::null:
11803 case value_t::string:
11804 case value_t::boolean:
11808 case value_t::binary:
11809 case value_t::discarded:
11810 default:
11811 {
11813 break;
11814 }
11815 }
11816
11817 return *this;
11818 }
11819
11824 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 >
11825 bool operator==(const IterImpl& other) const
11826 {
11827 // if objects are not the same, the comparison is undefined
11828 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11829 {
11830 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
11831 }
11832
11833 JSON_ASSERT(m_object != nullptr);
11834
11835 switch (m_object->m_type)
11836 {
11837 case value_t::object:
11838 return (m_it.object_iterator == other.m_it.object_iterator);
11839
11840 case value_t::array:
11841 return (m_it.array_iterator == other.m_it.array_iterator);
11842
11843 case value_t::null:
11844 case value_t::string:
11845 case value_t::boolean:
11849 case value_t::binary:
11850 case value_t::discarded:
11851 default:
11852 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
11853 }
11854 }
11855
11860 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 >
11861 bool operator!=(const IterImpl& other) const
11862 {
11863 return !operator==(other);
11864 }
11865
11870 bool operator<(const iter_impl& other) const
11871 {
11872 // if objects are not the same, the comparison is undefined
11873 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11874 {
11875 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
11876 }
11877
11878 JSON_ASSERT(m_object != nullptr);
11879
11880 switch (m_object->m_type)
11881 {
11882 case value_t::object:
11883 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
11884
11885 case value_t::array:
11886 return (m_it.array_iterator < other.m_it.array_iterator);
11887
11888 case value_t::null:
11889 case value_t::string:
11890 case value_t::boolean:
11894 case value_t::binary:
11895 case value_t::discarded:
11896 default:
11898 }
11899 }
11900
11905 bool operator<=(const iter_impl& other) const
11906 {
11907 return !other.operator < (*this);
11908 }
11909
11914 bool operator>(const iter_impl& other) const
11915 {
11916 return !operator<=(other);
11917 }
11918
11923 bool operator>=(const iter_impl& other) const
11924 {
11925 return !operator<(other);
11926 }
11927
11933 {
11934 JSON_ASSERT(m_object != nullptr);
11935
11936 switch (m_object->m_type)
11937 {
11938 case value_t::object:
11939 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
11940
11941 case value_t::array:
11942 {
11943 std::advance(m_it.array_iterator, i);
11944 break;
11945 }
11946
11947 case value_t::null:
11948 case value_t::string:
11949 case value_t::boolean:
11953 case value_t::binary:
11954 case value_t::discarded:
11955 default:
11956 {
11958 break;
11959 }
11960 }
11961
11962 return *this;
11963 }
11964
11970 {
11971 return operator+=(-i);
11972 }
11973
11979 {
11980 auto result = *this;
11981 result += i;
11982 return result;
11983 }
11984
11990 {
11991 auto result = it;
11992 result += i;
11993 return result;
11994 }
11995
12001 {
12002 auto result = *this;
12003 result -= i;
12004 return result;
12005 }
12006
12012 {
12013 JSON_ASSERT(m_object != nullptr);
12014
12015 switch (m_object->m_type)
12016 {
12017 case value_t::object:
12018 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12019
12020 case value_t::array:
12021 return m_it.array_iterator - other.m_it.array_iterator;
12022
12023 case value_t::null:
12024 case value_t::string:
12025 case value_t::boolean:
12029 case value_t::binary:
12030 case value_t::discarded:
12031 default:
12033 }
12034 }
12035
12041 {
12042 JSON_ASSERT(m_object != nullptr);
12043
12044 switch (m_object->m_type)
12045 {
12046 case value_t::object:
12047 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
12048
12049 case value_t::array:
12050 return *std::next(m_it.array_iterator, n);
12051
12052 case value_t::null:
12053 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12054
12055 case value_t::string:
12056 case value_t::boolean:
12060 case value_t::binary:
12061 case value_t::discarded:
12062 default:
12063 {
12065 {
12066 return *m_object;
12067 }
12068
12069 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12070 }
12071 }
12072 }
12073
12078 const typename object_t::key_type& key() const
12079 {
12080 JSON_ASSERT(m_object != nullptr);
12081
12082 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
12083 {
12084 return m_it.object_iterator->first;
12085 }
12086
12087 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
12088 }
12089
12095 {
12096 return operator*();
12097 }
12098
12101 pointer m_object = nullptr;
12104};
12105} // namespace detail
12106} // namespace nlohmann
12107
12108// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12109
12110// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12111
12112
12113#include <cstddef> // ptrdiff_t
12114#include <iterator> // reverse_iterator
12115#include <utility> // declval
12116
12117namespace nlohmann
12118{
12119namespace detail
12120{
12122// reverse_iterator //
12124
12143template<typename Base>
12144class json_reverse_iterator : public std::reverse_iterator<Base>
12145{
12146 public:
12147 using difference_type = std::ptrdiff_t;
12149 using base_iterator = std::reverse_iterator<Base>;
12151 using reference = typename Base::reference;
12152
12154 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
12155 : base_iterator(it) {}
12156
12158 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12159
12161 json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
12162 {
12163 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12164 }
12165
12168 {
12169 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12170 }
12171
12173 json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
12174 {
12175 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12176 }
12177
12180 {
12181 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12182 }
12183
12186 {
12187 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12188 }
12189
12192 {
12193 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12194 }
12195
12198 {
12199 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12200 }
12201
12204 {
12205 return base_iterator(*this) - base_iterator(other);
12206 }
12207
12210 {
12211 return *(this->operator+(n));
12212 }
12213
12215 auto key() const -> decltype(std::declval<Base>().key())
12216 {
12217 auto it = --this->base();
12218 return it.key();
12219 }
12220
12223 {
12224 auto it = --this->base();
12225 return it.operator * ();
12226 }
12227};
12228} // namespace detail
12229} // namespace nlohmann
12230
12231// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12232
12233// #include <nlohmann/detail/json_pointer.hpp>
12234
12235
12236#include <algorithm> // all_of
12237#include <cctype> // isdigit
12238#include <limits> // max
12239#include <numeric> // accumulate
12240#include <string> // string
12241#include <utility> // move
12242#include <vector> // vector
12243
12244// #include <nlohmann/detail/exceptions.hpp>
12245
12246// #include <nlohmann/detail/macro_scope.hpp>
12247
12248// #include <nlohmann/detail/string_escape.hpp>
12249
12250// #include <nlohmann/detail/value_t.hpp>
12251
12252
12253namespace nlohmann
12254{
12255
12258template<typename BasicJsonType>
12260{
12261 // allow basic_json to access private members
12263 friend class basic_json;
12264
12265 public:
12268 explicit json_pointer(const std::string& s = "")
12270 {}
12271
12274 std::string to_string() const
12275 {
12276 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12277 std::string{},
12278 [](const std::string & a, const std::string & b)
12279 {
12280 return a + "/" + detail::escape(b);
12281 });
12282 }
12283
12286 operator std::string() const
12287 {
12288 return to_string();
12289 }
12290
12294 {
12296 ptr.reference_tokens.begin(),
12297 ptr.reference_tokens.end());
12298 return *this;
12299 }
12300
12303 json_pointer& operator/=(std::string token)
12304 {
12305 push_back(std::move(token));
12306 return *this;
12307 }
12308
12311 json_pointer& operator/=(std::size_t array_idx)
12312 {
12313 return *this /= std::to_string(array_idx);
12314 }
12315
12319 const json_pointer& rhs)
12320 {
12321 return json_pointer(lhs) /= rhs;
12322 }
12323
12326 friend json_pointer operator/(const json_pointer& lhs, std::string token) // NOLINT(performance-unnecessary-value-param)
12327 {
12328 return json_pointer(lhs) /= std::move(token);
12329 }
12330
12333 friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
12334 {
12335 return json_pointer(lhs) /= array_idx;
12336 }
12337
12341 {
12342 if (empty())
12343 {
12344 return *this;
12345 }
12346
12347 json_pointer res = *this;
12348 res.pop_back();
12349 return res;
12350 }
12351
12355 {
12357 {
12358 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12359 }
12360
12361 reference_tokens.pop_back();
12362 }
12363
12366 const std::string& back() const
12367 {
12369 {
12370 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12371 }
12372
12373 return reference_tokens.back();
12374 }
12375
12378 void push_back(const std::string& token)
12379 {
12380 reference_tokens.push_back(token);
12381 }
12382
12385 void push_back(std::string&& token)
12386 {
12387 reference_tokens.push_back(std::move(token));
12388 }
12389
12392 bool empty() const noexcept
12393 {
12394 return reference_tokens.empty();
12395 }
12396
12397 private:
12408 static typename BasicJsonType::size_type array_index(const std::string& s)
12409 {
12410 using size_type = typename BasicJsonType::size_type;
12411
12412 // error condition (cf. RFC 6901, Sect. 4)
12413 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
12414 {
12415 JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
12416 }
12417
12418 // error condition (cf. RFC 6901, Sect. 4)
12419 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
12420 {
12421 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
12422 }
12423
12424 std::size_t processed_chars = 0;
12425 unsigned long long res = 0; // NOLINT(runtime/int)
12426 JSON_TRY
12427 {
12428 res = std::stoull(s, &processed_chars);
12429 }
12430 JSON_CATCH(std::out_of_range&)
12431 {
12432 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12433 }
12434
12435 // check if the string was completely read
12436 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
12437 {
12438 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12439 }
12440
12441 // only triggered on special platforms (like 32bit), see also
12442 // https://github.com/nlohmann/json/pull/2203
12443 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
12444 {
12445 JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
12446 }
12447
12448 return static_cast<size_type>(res);
12449 }
12450
12452 json_pointer top() const
12453 {
12455 {
12456 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12457 }
12458
12461 return result;
12462 }
12463
12464 private:
12474 {
12475 auto* result = &j;
12476
12477 // in case no reference tokens exist, return a reference to the JSON value
12478 // j which will be overwritten by a primitive value
12479 for (const auto& reference_token : reference_tokens)
12480 {
12481 switch (result->type())
12482 {
12484 {
12485 if (reference_token == "0")
12486 {
12487 // start a new array if reference token is 0
12488 result = &result->operator[](0);
12489 }
12490 else
12491 {
12492 // start a new object otherwise
12493 result = &result->operator[](reference_token);
12494 }
12495 break;
12496 }
12497
12499 {
12500 // create an entry in the object
12501 result = &result->operator[](reference_token);
12502 break;
12503 }
12504
12506 {
12507 // create an entry in the array
12508 result = &result->operator[](array_index(reference_token));
12509 break;
12510 }
12511
12512 /*
12513 The following code is only reached if there exists a reference
12514 token _and_ the current value is primitive. In this case, we have
12515 an error situation, because primitive values may only occur as
12516 single value; that is, with an empty list of reference tokens.
12517 */
12525 default:
12526 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
12527 }
12528 }
12529
12530 return *result;
12531 }
12532
12553 {
12554 for (const auto& reference_token : reference_tokens)
12555 {
12556 // convert null values to arrays or objects before continuing
12557 if (ptr->is_null())
12558 {
12559 // check if reference token is a number
12560 const bool nums =
12561 std::all_of(reference_token.begin(), reference_token.end(),
12562 [](const unsigned char x)
12563 {
12564 return std::isdigit(x);
12565 });
12566
12567 // change value to array for numbers or "-" or to object otherwise
12568 *ptr = (nums || reference_token == "-")
12571 }
12572
12573 switch (ptr->type())
12574 {
12576 {
12577 // use unchecked object access
12578 ptr = &ptr->operator[](reference_token);
12579 break;
12580 }
12581
12583 {
12584 if (reference_token == "-")
12585 {
12586 // explicitly treat "-" as index beyond the end
12587 ptr = &ptr->operator[](ptr->m_value.array->size());
12588 }
12589 else
12590 {
12591 // convert array index to number; unchecked access
12592 ptr = &ptr->operator[](array_index(reference_token));
12593 }
12594 break;
12595 }
12596
12605 default:
12606 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12607 }
12608 }
12609
12610 return *ptr;
12611 }
12612
12620 {
12621 for (const auto& reference_token : reference_tokens)
12622 {
12623 switch (ptr->type())
12624 {
12626 {
12627 // note: at performs range check
12628 ptr = &ptr->at(reference_token);
12629 break;
12630 }
12631
12633 {
12634 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12635 {
12636 // "-" always fails the range check
12638 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12639 ") is out of range", *ptr));
12640 }
12641
12642 // note: at performs range check
12643 ptr = &ptr->at(array_index(reference_token));
12644 break;
12645 }
12646
12655 default:
12656 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12657 }
12658 }
12659
12660 return *ptr;
12661 }
12662
12677 {
12678 for (const auto& reference_token : reference_tokens)
12679 {
12680 switch (ptr->type())
12681 {
12683 {
12684 // use unchecked object access
12685 ptr = &ptr->operator[](reference_token);
12686 break;
12687 }
12688
12690 {
12691 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12692 {
12693 // "-" cannot be used for const access
12694 JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
12695 }
12696
12697 // use unchecked array access
12698 ptr = &ptr->operator[](array_index(reference_token));
12699 break;
12700 }
12701
12710 default:
12711 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12712 }
12713 }
12714
12715 return *ptr;
12716 }
12717
12724 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
12725 {
12726 for (const auto& reference_token : reference_tokens)
12727 {
12728 switch (ptr->type())
12729 {
12731 {
12732 // note: at performs range check
12733 ptr = &ptr->at(reference_token);
12734 break;
12735 }
12736
12738 {
12739 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12740 {
12741 // "-" always fails the range check
12743 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12744 ") is out of range", *ptr));
12745 }
12746
12747 // note: at performs range check
12748 ptr = &ptr->at(array_index(reference_token));
12749 break;
12750 }
12751
12760 default:
12761 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12762 }
12763 }
12764
12765 return *ptr;
12766 }
12767
12772 bool contains(const BasicJsonType* ptr) const
12773 {
12774 for (const auto& reference_token : reference_tokens)
12775 {
12776 switch (ptr->type())
12777 {
12779 {
12780 if (!ptr->contains(reference_token))
12781 {
12782 // we did not find the key in the object
12783 return false;
12784 }
12785
12786 ptr = &ptr->operator[](reference_token);
12787 break;
12788 }
12789
12791 {
12792 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12793 {
12794 // "-" always fails the range check
12795 return false;
12796 }
12797 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
12798 {
12799 // invalid char
12800 return false;
12801 }
12802 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
12803 {
12804 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
12805 {
12806 // first char should be between '1' and '9'
12807 return false;
12808 }
12809 for (std::size_t i = 1; i < reference_token.size(); i++)
12810 {
12811 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
12812 {
12813 // other char should be between '0' and '9'
12814 return false;
12815 }
12816 }
12817 }
12818
12819 const auto idx = array_index(reference_token);
12820 if (idx >= ptr->size())
12821 {
12822 // index out of range
12823 return false;
12824 }
12825
12826 ptr = &ptr->operator[](idx);
12827 break;
12828 }
12829
12838 default:
12839 {
12840 // we do not expect primitive values if there is still a
12841 // reference token to process
12842 return false;
12843 }
12844 }
12845 }
12846
12847 // no reference token left means we found a primitive value
12848 return true;
12849 }
12850
12860 static std::vector<std::string> split(const std::string& reference_string)
12861 {
12862 std::vector<std::string> result;
12863
12864 // special case: empty reference string -> no reference tokens
12865 if (reference_string.empty())
12866 {
12867 return result;
12868 }
12869
12870 // check if nonempty reference string begins with slash
12871 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
12872 {
12873 JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
12874 }
12875
12876 // extract the reference tokens:
12877 // - slash: position of the last read slash (or end of string)
12878 // - start: position after the previous slash
12879 for (
12880 // search for the first slash after the first character
12881 std::size_t slash = reference_string.find_first_of('/', 1),
12882 // set the beginning of the first reference token
12883 start = 1;
12884 // we can stop if start == 0 (if slash == std::string::npos)
12885 start != 0;
12886 // set the beginning of the next reference token
12887 // (will eventually be 0 if slash == std::string::npos)
12888 start = (slash == std::string::npos) ? 0 : slash + 1,
12889 // find next slash
12890 slash = reference_string.find_first_of('/', start))
12891 {
12892 // use the text between the beginning of the reference token
12893 // (start) and the last slash (slash).
12894 auto reference_token = reference_string.substr(start, slash - start);
12895
12896 // check reference tokens are properly escaped
12897 for (std::size_t pos = reference_token.find_first_of('~');
12898 pos != std::string::npos;
12899 pos = reference_token.find_first_of('~', pos + 1))
12900 {
12901 JSON_ASSERT(reference_token[pos] == '~');
12902
12903 // ~ must be followed by 0 or 1
12904 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
12905 (reference_token[pos + 1] != '0' &&
12906 reference_token[pos + 1] != '1')))
12907 {
12908 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
12909 }
12910 }
12911
12912 // finally, store the reference token
12913 detail::unescape(reference_token);
12914 result.push_back(reference_token);
12915 }
12916
12917 return result;
12918 }
12919
12920 private:
12928 static void flatten(const std::string& reference_string,
12929 const BasicJsonType& value,
12931 {
12932 switch (value.type())
12933 {
12935 {
12936 if (value.m_value.array->empty())
12937 {
12938 // flatten empty array as null
12939 result[reference_string] = nullptr;
12940 }
12941 else
12942 {
12943 // iterate array and use index as reference string
12944 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
12945 {
12946 flatten(reference_string + "/" + std::to_string(i),
12947 value.m_value.array->operator[](i), result);
12948 }
12949 }
12950 break;
12951 }
12952
12954 {
12955 if (value.m_value.object->empty())
12956 {
12957 // flatten empty object as null
12958 result[reference_string] = nullptr;
12959 }
12960 else
12961 {
12962 // iterate object and use keys as reference string
12963 for (const auto& element : *value.m_value.object)
12964 {
12965 flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
12966 }
12967 }
12968 break;
12969 }
12970
12979 default:
12980 {
12981 // add primitive value with its reference string
12982 result[reference_string] = value;
12983 break;
12984 }
12985 }
12986 }
12987
12998 static BasicJsonType
13000 {
13001 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
13002 {
13003 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
13004 }
13005
13007
13008 // iterate the JSON object values
13009 for (const auto& element : *value.m_value.object)
13010 {
13011 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
13012 {
13013 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
13014 }
13015
13016 // assign value to reference pointed to by JSON pointer; Note that if
13017 // the JSON pointer is "" (i.e., points to the whole value), function
13018 // get_and_create returns a reference to result itself. An assignment
13019 // will then create a primitive value.
13020 json_pointer(element.first).get_and_create(result) = element.second;
13021 }
13022
13023 return result;
13024 }
13025
13037 friend bool operator==(json_pointer const& lhs,
13038 json_pointer const& rhs) noexcept
13039 {
13040 return lhs.reference_tokens == rhs.reference_tokens;
13041 }
13042
13054 friend bool operator!=(json_pointer const& lhs,
13055 json_pointer const& rhs) noexcept
13056 {
13057 return !(lhs == rhs);
13058 }
13059
13061 std::vector<std::string> reference_tokens;
13062};
13063} // namespace nlohmann
13064
13065// #include <nlohmann/detail/json_ref.hpp>
13066
13067
13068#include <initializer_list>
13069#include <utility>
13070
13071// #include <nlohmann/detail/meta/type_traits.hpp>
13072
13073
13074namespace nlohmann
13075{
13076namespace detail
13077{
13078template<typename BasicJsonType>
13080{
13081 public:
13082 using value_type = BasicJsonType;
13083
13085 : owned_value(std::move(value))
13086 {}
13087
13089 : value_ref(&value)
13090 {}
13091
13092 json_ref(std::initializer_list<json_ref> init)
13093 : owned_value(init)
13094 {}
13095
13096 template <
13097 class... Args,
13098 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13099 json_ref(Args && ... args)
13100 : owned_value(std::forward<Args>(args)...)
13101 {}
13102
13103 // class should be movable only
13104 json_ref(json_ref&&) noexcept = default;
13105 json_ref(const json_ref&) = delete;
13106 json_ref& operator=(const json_ref&) = delete;
13107 json_ref& operator=(json_ref&&) = delete;
13108 ~json_ref() = default;
13109
13111 {
13112 if (value_ref == nullptr)
13113 {
13114 return std::move(owned_value);
13115 }
13116 return *value_ref;
13117 }
13118
13119 value_type const& operator*() const
13120 {
13121 return value_ref ? *value_ref : owned_value;
13122 }
13123
13124 value_type const* operator->() const
13125 {
13126 return &** this;
13127 }
13128
13129 private:
13130 mutable value_type owned_value = nullptr;
13131 value_type const* value_ref = nullptr;
13132};
13133} // namespace detail
13134} // namespace nlohmann
13135
13136// #include <nlohmann/detail/macro_scope.hpp>
13137
13138// #include <nlohmann/detail/string_escape.hpp>
13139
13140// #include <nlohmann/detail/meta/cpp_future.hpp>
13141
13142// #include <nlohmann/detail/meta/type_traits.hpp>
13143
13144// #include <nlohmann/detail/output/binary_writer.hpp>
13145
13146
13147#include <algorithm> // reverse
13148#include <array> // array
13149#include <cmath> // isnan, isinf
13150#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13151#include <cstring> // memcpy
13152#include <limits> // numeric_limits
13153#include <string> // string
13154#include <utility> // move
13155
13156// #include <nlohmann/detail/input/binary_reader.hpp>
13157
13158// #include <nlohmann/detail/macro_scope.hpp>
13159
13160// #include <nlohmann/detail/output/output_adapters.hpp>
13161
13162
13163#include <algorithm> // copy
13164#include <cstddef> // size_t
13165#include <iterator> // back_inserter
13166#include <memory> // shared_ptr, make_shared
13167#include <string> // basic_string
13168#include <vector> // vector
13169
13170#ifndef JSON_NO_IO
13171 #include <ios> // streamsize
13172 #include <ostream> // basic_ostream
13173#endif // JSON_NO_IO
13174
13175// #include <nlohmann/detail/macro_scope.hpp>
13176
13177
13178namespace nlohmann
13179{
13180namespace detail
13181{
13183template<typename CharType> struct output_adapter_protocol
13184{
13185 virtual void write_character(CharType c) = 0;
13186 virtual void write_characters(const CharType* s, std::size_t length) = 0;
13187 virtual ~output_adapter_protocol() = default;
13188
13193 output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
13194};
13195
13197template<typename CharType>
13198using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13199
13201template<typename CharType, typename AllocatorType = std::allocator<CharType>>
13203{
13204 public:
13205 explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
13206 : v(vec)
13207 {}
13208
13209 void write_character(CharType c) override
13210 {
13211 v.push_back(c);
13212 }
13213
13215 void write_characters(const CharType* s, std::size_t length) override
13216 {
13217 std::copy(s, s + length, std::back_inserter(v));
13218 }
13219
13220 private:
13221 std::vector<CharType, AllocatorType>& v;
13222};
13223
13224#ifndef JSON_NO_IO
13226template<typename CharType>
13228{
13229 public:
13230 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13231 : stream(s)
13232 {}
13233
13234 void write_character(CharType c) override
13235 {
13236 stream.put(c);
13237 }
13238
13240 void write_characters(const CharType* s, std::size_t length) override
13241 {
13242 stream.write(s, static_cast<std::streamsize>(length));
13243 }
13244
13245 private:
13246 std::basic_ostream<CharType>& stream;
13247};
13248#endif // JSON_NO_IO
13249
13251template<typename CharType, typename StringType = std::basic_string<CharType>>
13253{
13254 public:
13255 explicit output_string_adapter(StringType& s) noexcept
13256 : str(s)
13257 {}
13258
13259 void write_character(CharType c) override
13260 {
13261 str.push_back(c);
13262 }
13263
13265 void write_characters(const CharType* s, std::size_t length) override
13266 {
13267 str.append(s, length);
13268 }
13269
13270 private:
13271 StringType& str;
13272};
13273
13274template<typename CharType, typename StringType = std::basic_string<CharType>>
13276{
13277 public:
13278 template<typename AllocatorType = std::allocator<CharType>>
13279 output_adapter(std::vector<CharType, AllocatorType>& vec)
13280 : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
13281
13282#ifndef JSON_NO_IO
13283 output_adapter(std::basic_ostream<CharType>& s)
13284 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
13285#endif // JSON_NO_IO
13286
13287 output_adapter(StringType& s)
13288 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
13289
13291 {
13292 return oa;
13293 }
13294
13295 private:
13297};
13298} // namespace detail
13299} // namespace nlohmann
13300
13301
13302namespace nlohmann
13303{
13304namespace detail
13305{
13307// binary writer //
13309
13313template<typename BasicJsonType, typename CharType>
13315{
13316 using string_t = typename BasicJsonType::string_t;
13317 using binary_t = typename BasicJsonType::binary_t;
13318 using number_float_t = typename BasicJsonType::number_float_t;
13319
13320 public:
13326 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
13327 {
13328 JSON_ASSERT(oa);
13329 }
13330
13335 void write_bson(const BasicJsonType& j)
13336 {
13337 switch (j.type())
13338 {
13339 case value_t::object:
13340 {
13341 write_bson_object(*j.m_value.object);
13342 break;
13343 }
13344
13345 case value_t::null:
13346 case value_t::array:
13347 case value_t::string:
13348 case value_t::boolean:
13349 case value_t::number_integer:
13350 case value_t::number_unsigned:
13351 case value_t::number_float:
13352 case value_t::binary:
13353 case value_t::discarded:
13354 default:
13355 {
13356 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));
13357 }
13358 }
13359 }
13360
13364 void write_cbor(const BasicJsonType& j)
13365 {
13366 switch (j.type())
13367 {
13368 case value_t::null:
13369 {
13370 oa->write_character(to_char_type(0xF6));
13371 break;
13372 }
13373
13374 case value_t::boolean:
13375 {
13376 oa->write_character(j.m_value.boolean
13377 ? to_char_type(0xF5)
13378 : to_char_type(0xF4));
13379 break;
13380 }
13381
13382 case value_t::number_integer:
13383 {
13384 if (j.m_value.number_integer >= 0)
13385 {
13386 // CBOR does not differentiate between positive signed
13387 // integers and unsigned integers. Therefore, we used the
13388 // code from the value_t::number_unsigned case here.
13389 if (j.m_value.number_integer <= 0x17)
13390 {
13391 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13392 }
13393 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13394 {
13395 oa->write_character(to_char_type(0x18));
13396 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13397 }
13398 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
13399 {
13400 oa->write_character(to_char_type(0x19));
13401 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13402 }
13403 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
13404 {
13405 oa->write_character(to_char_type(0x1A));
13406 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13407 }
13408 else
13409 {
13410 oa->write_character(to_char_type(0x1B));
13411 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13412 }
13413 }
13414 else
13415 {
13416 // The conversions below encode the sign in the first
13417 // byte, and the value is converted to a positive number.
13418 const auto positive_number = -1 - j.m_value.number_integer;
13419 if (j.m_value.number_integer >= -24)
13420 {
13421 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
13422 }
13423 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
13424 {
13425 oa->write_character(to_char_type(0x38));
13426 write_number(static_cast<std::uint8_t>(positive_number));
13427 }
13428 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
13429 {
13430 oa->write_character(to_char_type(0x39));
13431 write_number(static_cast<std::uint16_t>(positive_number));
13432 }
13433 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
13434 {
13435 oa->write_character(to_char_type(0x3A));
13436 write_number(static_cast<std::uint32_t>(positive_number));
13437 }
13438 else
13439 {
13440 oa->write_character(to_char_type(0x3B));
13441 write_number(static_cast<std::uint64_t>(positive_number));
13442 }
13443 }
13444 break;
13445 }
13446
13447 case value_t::number_unsigned:
13448 {
13449 if (j.m_value.number_unsigned <= 0x17)
13450 {
13451 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13452 }
13453 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13454 {
13455 oa->write_character(to_char_type(0x18));
13456 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13457 }
13458 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13459 {
13460 oa->write_character(to_char_type(0x19));
13461 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
13462 }
13463 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13464 {
13465 oa->write_character(to_char_type(0x1A));
13466 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
13467 }
13468 else
13469 {
13470 oa->write_character(to_char_type(0x1B));
13471 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
13472 }
13473 break;
13474 }
13475
13476 case value_t::number_float:
13477 {
13478 if (std::isnan(j.m_value.number_float))
13479 {
13480 // NaN is 0xf97e00 in CBOR
13481 oa->write_character(to_char_type(0xF9));
13482 oa->write_character(to_char_type(0x7E));
13483 oa->write_character(to_char_type(0x00));
13484 }
13485 else if (std::isinf(j.m_value.number_float))
13486 {
13487 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
13488 oa->write_character(to_char_type(0xf9));
13489 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
13490 oa->write_character(to_char_type(0x00));
13491 }
13492 else
13493 {
13494 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
13495 }
13496 break;
13497 }
13498
13499 case value_t::string:
13500 {
13501 // step 1: write control byte and the string length
13502 const auto N = j.m_value.string->size();
13503 if (N <= 0x17)
13504 {
13505 write_number(static_cast<std::uint8_t>(0x60 + N));
13506 }
13507 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13508 {
13509 oa->write_character(to_char_type(0x78));
13510 write_number(static_cast<std::uint8_t>(N));
13511 }
13512 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13513 {
13514 oa->write_character(to_char_type(0x79));
13515 write_number(static_cast<std::uint16_t>(N));
13516 }
13517 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13518 {
13519 oa->write_character(to_char_type(0x7A));
13520 write_number(static_cast<std::uint32_t>(N));
13521 }
13522 // LCOV_EXCL_START
13523 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13524 {
13525 oa->write_character(to_char_type(0x7B));
13526 write_number(static_cast<std::uint64_t>(N));
13527 }
13528 // LCOV_EXCL_STOP
13529
13530 // step 2: write the string
13531 oa->write_characters(
13532 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13533 j.m_value.string->size());
13534 break;
13535 }
13536
13537 case value_t::array:
13538 {
13539 // step 1: write control byte and the array size
13540 const auto N = j.m_value.array->size();
13541 if (N <= 0x17)
13542 {
13543 write_number(static_cast<std::uint8_t>(0x80 + N));
13544 }
13545 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13546 {
13547 oa->write_character(to_char_type(0x98));
13548 write_number(static_cast<std::uint8_t>(N));
13549 }
13550 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13551 {
13552 oa->write_character(to_char_type(0x99));
13553 write_number(static_cast<std::uint16_t>(N));
13554 }
13555 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13556 {
13557 oa->write_character(to_char_type(0x9A));
13558 write_number(static_cast<std::uint32_t>(N));
13559 }
13560 // LCOV_EXCL_START
13561 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13562 {
13563 oa->write_character(to_char_type(0x9B));
13564 write_number(static_cast<std::uint64_t>(N));
13565 }
13566 // LCOV_EXCL_STOP
13567
13568 // step 2: write each element
13569 for (const auto& el : *j.m_value.array)
13570 {
13571 write_cbor(el);
13572 }
13573 break;
13574 }
13575
13576 case value_t::binary:
13577 {
13578 if (j.m_value.binary->has_subtype())
13579 {
13580 if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
13581 {
13582 write_number(static_cast<std::uint8_t>(0xd8));
13583 write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
13584 }
13585 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
13586 {
13587 write_number(static_cast<std::uint8_t>(0xd9));
13588 write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
13589 }
13590 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
13591 {
13592 write_number(static_cast<std::uint8_t>(0xda));
13593 write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
13594 }
13595 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
13596 {
13597 write_number(static_cast<std::uint8_t>(0xdb));
13598 write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
13599 }
13600 }
13601
13602 // step 1: write control byte and the binary array size
13603 const auto N = j.m_value.binary->size();
13604 if (N <= 0x17)
13605 {
13606 write_number(static_cast<std::uint8_t>(0x40 + N));
13607 }
13608 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13609 {
13610 oa->write_character(to_char_type(0x58));
13611 write_number(static_cast<std::uint8_t>(N));
13612 }
13613 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13614 {
13615 oa->write_character(to_char_type(0x59));
13616 write_number(static_cast<std::uint16_t>(N));
13617 }
13618 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13619 {
13620 oa->write_character(to_char_type(0x5A));
13621 write_number(static_cast<std::uint32_t>(N));
13622 }
13623 // LCOV_EXCL_START
13624 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13625 {
13626 oa->write_character(to_char_type(0x5B));
13627 write_number(static_cast<std::uint64_t>(N));
13628 }
13629 // LCOV_EXCL_STOP
13630
13631 // step 2: write each element
13632 oa->write_characters(
13633 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13634 N);
13635
13636 break;
13637 }
13638
13639 case value_t::object:
13640 {
13641 // step 1: write control byte and the object size
13642 const auto N = j.m_value.object->size();
13643 if (N <= 0x17)
13644 {
13645 write_number(static_cast<std::uint8_t>(0xA0 + N));
13646 }
13647 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13648 {
13649 oa->write_character(to_char_type(0xB8));
13650 write_number(static_cast<std::uint8_t>(N));
13651 }
13652 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13653 {
13654 oa->write_character(to_char_type(0xB9));
13655 write_number(static_cast<std::uint16_t>(N));
13656 }
13657 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13658 {
13659 oa->write_character(to_char_type(0xBA));
13660 write_number(static_cast<std::uint32_t>(N));
13661 }
13662 // LCOV_EXCL_START
13663 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13664 {
13665 oa->write_character(to_char_type(0xBB));
13666 write_number(static_cast<std::uint64_t>(N));
13667 }
13668 // LCOV_EXCL_STOP
13669
13670 // step 2: write each element
13671 for (const auto& el : *j.m_value.object)
13672 {
13673 write_cbor(el.first);
13674 write_cbor(el.second);
13675 }
13676 break;
13677 }
13678
13679 case value_t::discarded:
13680 default:
13681 break;
13682 }
13683 }
13684
13688 void write_msgpack(const BasicJsonType& j)
13689 {
13690 switch (j.type())
13691 {
13692 case value_t::null: // nil
13693 {
13694 oa->write_character(to_char_type(0xC0));
13695 break;
13696 }
13697
13698 case value_t::boolean: // true and false
13699 {
13700 oa->write_character(j.m_value.boolean
13701 ? to_char_type(0xC3)
13702 : to_char_type(0xC2));
13703 break;
13704 }
13705
13706 case value_t::number_integer:
13707 {
13708 if (j.m_value.number_integer >= 0)
13709 {
13710 // MessagePack does not differentiate between positive
13711 // signed integers and unsigned integers. Therefore, we used
13712 // the code from the value_t::number_unsigned case here.
13713 if (j.m_value.number_unsigned < 128)
13714 {
13715 // positive fixnum
13716 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13717 }
13718 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13719 {
13720 // uint 8
13721 oa->write_character(to_char_type(0xCC));
13722 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13723 }
13724 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13725 {
13726 // uint 16
13727 oa->write_character(to_char_type(0xCD));
13728 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13729 }
13730 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13731 {
13732 // uint 32
13733 oa->write_character(to_char_type(0xCE));
13734 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13735 }
13736 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13737 {
13738 // uint 64
13739 oa->write_character(to_char_type(0xCF));
13740 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13741 }
13742 }
13743 else
13744 {
13745 if (j.m_value.number_integer >= -32)
13746 {
13747 // negative fixnum
13748 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13749 }
13750 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
13751 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
13752 {
13753 // int 8
13754 oa->write_character(to_char_type(0xD0));
13755 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
13756 }
13757 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
13758 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
13759 {
13760 // int 16
13761 oa->write_character(to_char_type(0xD1));
13762 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
13763 }
13764 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
13765 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
13766 {
13767 // int 32
13768 oa->write_character(to_char_type(0xD2));
13769 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
13770 }
13771 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
13772 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
13773 {
13774 // int 64
13775 oa->write_character(to_char_type(0xD3));
13776 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
13777 }
13778 }
13779 break;
13780 }
13781
13782 case value_t::number_unsigned:
13783 {
13784 if (j.m_value.number_unsigned < 128)
13785 {
13786 // positive fixnum
13787 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13788 }
13789 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13790 {
13791 // uint 8
13792 oa->write_character(to_char_type(0xCC));
13793 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13794 }
13795 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13796 {
13797 // uint 16
13798 oa->write_character(to_char_type(0xCD));
13799 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13800 }
13801 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13802 {
13803 // uint 32
13804 oa->write_character(to_char_type(0xCE));
13805 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13806 }
13807 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
13808 {
13809 // uint 64
13810 oa->write_character(to_char_type(0xCF));
13811 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13812 }
13813 break;
13814 }
13815
13816 case value_t::number_float:
13817 {
13818 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
13819 break;
13820 }
13821
13822 case value_t::string:
13823 {
13824 // step 1: write control byte and the string length
13825 const auto N = j.m_value.string->size();
13826 if (N <= 31)
13827 {
13828 // fixstr
13829 write_number(static_cast<std::uint8_t>(0xA0 | N));
13830 }
13831 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13832 {
13833 // str 8
13834 oa->write_character(to_char_type(0xD9));
13835 write_number(static_cast<std::uint8_t>(N));
13836 }
13837 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13838 {
13839 // str 16
13840 oa->write_character(to_char_type(0xDA));
13841 write_number(static_cast<std::uint16_t>(N));
13842 }
13843 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13844 {
13845 // str 32
13846 oa->write_character(to_char_type(0xDB));
13847 write_number(static_cast<std::uint32_t>(N));
13848 }
13849
13850 // step 2: write the string
13851 oa->write_characters(
13852 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13853 j.m_value.string->size());
13854 break;
13855 }
13856
13857 case value_t::array:
13858 {
13859 // step 1: write control byte and the array size
13860 const auto N = j.m_value.array->size();
13861 if (N <= 15)
13862 {
13863 // fixarray
13864 write_number(static_cast<std::uint8_t>(0x90 | N));
13865 }
13866 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13867 {
13868 // array 16
13869 oa->write_character(to_char_type(0xDC));
13870 write_number(static_cast<std::uint16_t>(N));
13871 }
13872 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13873 {
13874 // array 32
13875 oa->write_character(to_char_type(0xDD));
13876 write_number(static_cast<std::uint32_t>(N));
13877 }
13878
13879 // step 2: write each element
13880 for (const auto& el : *j.m_value.array)
13881 {
13882 write_msgpack(el);
13883 }
13884 break;
13885 }
13886
13887 case value_t::binary:
13888 {
13889 // step 0: determine if the binary type has a set subtype to
13890 // determine whether or not to use the ext or fixext types
13891 const bool use_ext = j.m_value.binary->has_subtype();
13892
13893 // step 1: write control byte and the byte string length
13894 const auto N = j.m_value.binary->size();
13895 if (N <= (std::numeric_limits<std::uint8_t>::max)())
13896 {
13897 std::uint8_t output_type{};
13898 bool fixed = true;
13899 if (use_ext)
13900 {
13901 switch (N)
13902 {
13903 case 1:
13904 output_type = 0xD4; // fixext 1
13905 break;
13906 case 2:
13907 output_type = 0xD5; // fixext 2
13908 break;
13909 case 4:
13910 output_type = 0xD6; // fixext 4
13911 break;
13912 case 8:
13913 output_type = 0xD7; // fixext 8
13914 break;
13915 case 16:
13916 output_type = 0xD8; // fixext 16
13917 break;
13918 default:
13919 output_type = 0xC7; // ext 8
13920 fixed = false;
13921 break;
13922 }
13923
13924 }
13925 else
13926 {
13927 output_type = 0xC4; // bin 8
13928 fixed = false;
13929 }
13930
13931 oa->write_character(to_char_type(output_type));
13932 if (!fixed)
13933 {
13934 write_number(static_cast<std::uint8_t>(N));
13935 }
13936 }
13937 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13938 {
13939 std::uint8_t output_type = use_ext
13940 ? 0xC8 // ext 16
13941 : 0xC5; // bin 16
13942
13943 oa->write_character(to_char_type(output_type));
13944 write_number(static_cast<std::uint16_t>(N));
13945 }
13946 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13947 {
13948 std::uint8_t output_type = use_ext
13949 ? 0xC9 // ext 32
13950 : 0xC6; // bin 32
13951
13952 oa->write_character(to_char_type(output_type));
13953 write_number(static_cast<std::uint32_t>(N));
13954 }
13955
13956 // step 1.5: if this is an ext type, write the subtype
13957 if (use_ext)
13958 {
13959 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
13960 }
13961
13962 // step 2: write the byte string
13963 oa->write_characters(
13964 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13965 N);
13966
13967 break;
13968 }
13969
13970 case value_t::object:
13971 {
13972 // step 1: write control byte and the object size
13973 const auto N = j.m_value.object->size();
13974 if (N <= 15)
13975 {
13976 // fixmap
13977 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
13978 }
13979 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13980 {
13981 // map 16
13982 oa->write_character(to_char_type(0xDE));
13983 write_number(static_cast<std::uint16_t>(N));
13984 }
13985 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13986 {
13987 // map 32
13988 oa->write_character(to_char_type(0xDF));
13989 write_number(static_cast<std::uint32_t>(N));
13990 }
13991
13992 // step 2: write each element
13993 for (const auto& el : *j.m_value.object)
13994 {
13995 write_msgpack(el.first);
13996 write_msgpack(el.second);
13997 }
13998 break;
13999 }
14000
14001 case value_t::discarded:
14002 default:
14003 break;
14004 }
14005 }
14006
14013 void write_ubjson(const BasicJsonType& j, const bool use_count,
14014 const bool use_type, const bool add_prefix = true)
14015 {
14016 switch (j.type())
14017 {
14018 case value_t::null:
14019 {
14020 if (add_prefix)
14021 {
14022 oa->write_character(to_char_type('Z'));
14023 }
14024 break;
14025 }
14026
14027 case value_t::boolean:
14028 {
14029 if (add_prefix)
14030 {
14031 oa->write_character(j.m_value.boolean
14032 ? to_char_type('T')
14033 : to_char_type('F'));
14034 }
14035 break;
14036 }
14037
14038 case value_t::number_integer:
14039 {
14040 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
14041 break;
14042 }
14043
14044 case value_t::number_unsigned:
14045 {
14046 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
14047 break;
14048 }
14049
14050 case value_t::number_float:
14051 {
14052 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
14053 break;
14054 }
14055
14056 case value_t::string:
14057 {
14058 if (add_prefix)
14059 {
14060 oa->write_character(to_char_type('S'));
14061 }
14062 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
14063 oa->write_characters(
14064 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14065 j.m_value.string->size());
14066 break;
14067 }
14068
14069 case value_t::array:
14070 {
14071 if (add_prefix)
14072 {
14073 oa->write_character(to_char_type('['));
14074 }
14075
14076 bool prefix_required = true;
14077 if (use_type && !j.m_value.array->empty())
14078 {
14079 JSON_ASSERT(use_count);
14080 const CharType first_prefix = ubjson_prefix(j.front());
14081 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14082 [this, first_prefix](const BasicJsonType & v)
14083 {
14084 return ubjson_prefix(v) == first_prefix;
14085 });
14086
14087 if (same_prefix)
14088 {
14089 prefix_required = false;
14090 oa->write_character(to_char_type('$'));
14091 oa->write_character(first_prefix);
14092 }
14093 }
14094
14095 if (use_count)
14096 {
14097 oa->write_character(to_char_type('#'));
14098 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
14099 }
14100
14101 for (const auto& el : *j.m_value.array)
14102 {
14103 write_ubjson(el, use_count, use_type, prefix_required);
14104 }
14105
14106 if (!use_count)
14107 {
14108 oa->write_character(to_char_type(']'));
14109 }
14110
14111 break;
14112 }
14113
14114 case value_t::binary:
14115 {
14116 if (add_prefix)
14117 {
14118 oa->write_character(to_char_type('['));
14119 }
14120
14121 if (use_type && !j.m_value.binary->empty())
14122 {
14123 JSON_ASSERT(use_count);
14124 oa->write_character(to_char_type('$'));
14125 oa->write_character('U');
14126 }
14127
14128 if (use_count)
14129 {
14130 oa->write_character(to_char_type('#'));
14131 write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
14132 }
14133
14134 if (use_type)
14135 {
14136 oa->write_characters(
14137 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14138 j.m_value.binary->size());
14139 }
14140 else
14141 {
14142 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14143 {
14144 oa->write_character(to_char_type('U'));
14145 oa->write_character(j.m_value.binary->data()[i]);
14146 }
14147 }
14148
14149 if (!use_count)
14150 {
14151 oa->write_character(to_char_type(']'));
14152 }
14153
14154 break;
14155 }
14156
14157 case value_t::object:
14158 {
14159 if (add_prefix)
14160 {
14161 oa->write_character(to_char_type('{'));
14162 }
14163
14164 bool prefix_required = true;
14165 if (use_type && !j.m_value.object->empty())
14166 {
14167 JSON_ASSERT(use_count);
14168 const CharType first_prefix = ubjson_prefix(j.front());
14169 const bool same_prefix = std::all_of(j.begin(), j.end(),
14170 [this, first_prefix](const BasicJsonType & v)
14171 {
14172 return ubjson_prefix(v) == first_prefix;
14173 });
14174
14175 if (same_prefix)
14176 {
14177 prefix_required = false;
14178 oa->write_character(to_char_type('$'));
14179 oa->write_character(first_prefix);
14180 }
14181 }
14182
14183 if (use_count)
14184 {
14185 oa->write_character(to_char_type('#'));
14186 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
14187 }
14188
14189 for (const auto& el : *j.m_value.object)
14190 {
14191 write_number_with_ubjson_prefix(el.first.size(), true);
14192 oa->write_characters(
14193 reinterpret_cast<const CharType*>(el.first.c_str()),
14194 el.first.size());
14195 write_ubjson(el.second, use_count, use_type, prefix_required);
14196 }
14197
14198 if (!use_count)
14199 {
14200 oa->write_character(to_char_type('}'));
14201 }
14202
14203 break;
14204 }
14205
14206 case value_t::discarded:
14207 default:
14208 break;
14209 }
14210 }
14211
14212 private:
14214 // BSON //
14216
14221 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14222 {
14223 const auto it = name.find(static_cast<typename string_t::value_type>(0));
14224 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14225 {
14226 JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
14227 static_cast<void>(j);
14228 }
14229
14230 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14231 }
14232
14237 const std::uint8_t element_type)
14238 {
14239 oa->write_character(to_char_type(element_type)); // boolean
14240 oa->write_characters(
14241 reinterpret_cast<const CharType*>(name.c_str()),
14242 name.size() + 1u);
14243 }
14244
14249 const bool value)
14250 {
14251 write_bson_entry_header(name, 0x08);
14252 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
14253 }
14254
14258 void write_bson_double(const string_t& name,
14259 const double value)
14260 {
14261 write_bson_entry_header(name, 0x01);
14262 write_number<double, true>(value);
14263 }
14264
14268 static std::size_t calc_bson_string_size(const string_t& value)
14269 {
14270 return sizeof(std::int32_t) + value.size() + 1ul;
14271 }
14272
14276 void write_bson_string(const string_t& name,
14277 const string_t& value)
14278 {
14279 write_bson_entry_header(name, 0x02);
14280
14281 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
14282 oa->write_characters(
14283 reinterpret_cast<const CharType*>(value.c_str()),
14284 value.size() + 1);
14285 }
14286
14290 void write_bson_null(const string_t& name)
14291 {
14292 write_bson_entry_header(name, 0x0A);
14293 }
14294
14298 static std::size_t calc_bson_integer_size(const std::int64_t value)
14299 {
14300 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
14301 ? sizeof(std::int32_t)
14302 : sizeof(std::int64_t);
14303 }
14304
14309 const std::int64_t value)
14310 {
14311 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
14312 {
14313 write_bson_entry_header(name, 0x10); // int32
14314 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
14315 }
14316 else
14317 {
14318 write_bson_entry_header(name, 0x12); // int64
14319 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
14320 }
14321 }
14322
14326 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
14327 {
14328 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14329 ? sizeof(std::int32_t)
14330 : sizeof(std::int64_t);
14331 }
14332
14337 const BasicJsonType& j)
14338 {
14339 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14340 {
14341 write_bson_entry_header(name, 0x10 /* int32 */);
14342 write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
14343 }
14344 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14345 {
14346 write_bson_entry_header(name, 0x12 /* int64 */);
14347 write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
14348 }
14349 else
14350 {
14351 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));
14352 }
14353 }
14354
14359 const typename BasicJsonType::object_t& value)
14360 {
14361 write_bson_entry_header(name, 0x03); // object
14362 write_bson_object(value);
14363 }
14364
14368 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
14369 {
14370 std::size_t array_index = 0ul;
14371
14372 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
14373 {
14374 return result + calc_bson_element_size(std::to_string(array_index++), el);
14375 });
14376
14377 return sizeof(std::int32_t) + embedded_document_size + 1ul;
14378 }
14379
14383 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
14384 {
14385 return sizeof(std::int32_t) + value.size() + 1ul;
14386 }
14387
14391 void write_bson_array(const string_t& name,
14392 const typename BasicJsonType::array_t& value)
14393 {
14394 write_bson_entry_header(name, 0x04); // array
14395 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
14396
14397 std::size_t array_index = 0ul;
14398
14399 for (const auto& el : value)
14400 {
14401 write_bson_element(std::to_string(array_index++), el);
14402 }
14403
14404 oa->write_character(to_char_type(0x00));
14405 }
14406
14410 void write_bson_binary(const string_t& name,
14411 const binary_t& value)
14412 {
14413 write_bson_entry_header(name, 0x05);
14414
14415 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
14416 write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
14417
14418 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
14419 }
14420
14425 static std::size_t calc_bson_element_size(const string_t& name,
14426 const BasicJsonType& j)
14427 {
14428 const auto header_size = calc_bson_entry_header_size(name, j);
14429 switch (j.type())
14430 {
14431 case value_t::object:
14432 return header_size + calc_bson_object_size(*j.m_value.object);
14433
14434 case value_t::array:
14435 return header_size + calc_bson_array_size(*j.m_value.array);
14436
14437 case value_t::binary:
14438 return header_size + calc_bson_binary_size(*j.m_value.binary);
14439
14440 case value_t::boolean:
14441 return header_size + 1ul;
14442
14443 case value_t::number_float:
14444 return header_size + 8ul;
14445
14446 case value_t::number_integer:
14447 return header_size + calc_bson_integer_size(j.m_value.number_integer);
14448
14449 case value_t::number_unsigned:
14450 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
14451
14452 case value_t::string:
14453 return header_size + calc_bson_string_size(*j.m_value.string);
14454
14455 case value_t::null:
14456 return header_size + 0ul;
14457
14458 // LCOV_EXCL_START
14459 case value_t::discarded:
14460 default:
14461 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14462 return 0ul;
14463 // LCOV_EXCL_STOP
14464 }
14465 }
14466
14474 const BasicJsonType& j)
14475 {
14476 switch (j.type())
14477 {
14478 case value_t::object:
14479 return write_bson_object_entry(name, *j.m_value.object);
14480
14481 case value_t::array:
14482 return write_bson_array(name, *j.m_value.array);
14483
14484 case value_t::binary:
14485 return write_bson_binary(name, *j.m_value.binary);
14486
14487 case value_t::boolean:
14488 return write_bson_boolean(name, j.m_value.boolean);
14489
14490 case value_t::number_float:
14491 return write_bson_double(name, j.m_value.number_float);
14492
14493 case value_t::number_integer:
14494 return write_bson_integer(name, j.m_value.number_integer);
14495
14496 case value_t::number_unsigned:
14497 return write_bson_unsigned(name, j);
14498
14499 case value_t::string:
14500 return write_bson_string(name, *j.m_value.string);
14501
14502 case value_t::null:
14503 return write_bson_null(name);
14504
14505 // LCOV_EXCL_START
14506 case value_t::discarded:
14507 default:
14508 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14509 return;
14510 // LCOV_EXCL_STOP
14511 }
14512 }
14513
14520 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14521 {
14522 std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
14523 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14524 {
14525 return result += calc_bson_element_size(el.first, el.second);
14526 });
14527
14528 return sizeof(std::int32_t) + document_size + 1ul;
14529 }
14530
14535 void write_bson_object(const typename BasicJsonType::object_t& value)
14536 {
14537 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14538
14539 for (const auto& el : value)
14540 {
14541 write_bson_element(el.first, el.second);
14542 }
14543
14544 oa->write_character(to_char_type(0x00));
14545 }
14546
14548 // CBOR //
14550
14551 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14552 {
14553 return to_char_type(0xFA); // Single-Precision Float
14554 }
14555
14556 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14557 {
14558 return to_char_type(0xFB); // Double-Precision Float
14559 }
14560
14562 // MsgPack //
14564
14565 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14566 {
14567 return to_char_type(0xCA); // float 32
14568 }
14569
14570 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14571 {
14572 return to_char_type(0xCB); // float 64
14573 }
14574
14576 // UBJSON //
14578
14579 // UBJSON: write number (floating point)
14580 template<typename NumberType, typename std::enable_if<
14581 std::is_floating_point<NumberType>::value, int>::type = 0>
14582 void write_number_with_ubjson_prefix(const NumberType n,
14583 const bool add_prefix)
14584 {
14585 if (add_prefix)
14586 {
14587 oa->write_character(get_ubjson_float_prefix(n));
14588 }
14589 write_number(n);
14590 }
14591
14592 // UBJSON: write number (unsigned integer)
14593 template<typename NumberType, typename std::enable_if<
14594 std::is_unsigned<NumberType>::value, int>::type = 0>
14595 void write_number_with_ubjson_prefix(const NumberType n,
14596 const bool add_prefix)
14597 {
14598 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14599 {
14600 if (add_prefix)
14601 {
14602 oa->write_character(to_char_type('i')); // int8
14603 }
14604 write_number(static_cast<std::uint8_t>(n));
14605 }
14606 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14607 {
14608 if (add_prefix)
14609 {
14610 oa->write_character(to_char_type('U')); // uint8
14611 }
14612 write_number(static_cast<std::uint8_t>(n));
14613 }
14614 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14615 {
14616 if (add_prefix)
14617 {
14618 oa->write_character(to_char_type('I')); // int16
14619 }
14620 write_number(static_cast<std::int16_t>(n));
14621 }
14622 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14623 {
14624 if (add_prefix)
14625 {
14626 oa->write_character(to_char_type('l')); // int32
14627 }
14628 write_number(static_cast<std::int32_t>(n));
14629 }
14630 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14631 {
14632 if (add_prefix)
14633 {
14634 oa->write_character(to_char_type('L')); // int64
14635 }
14636 write_number(static_cast<std::int64_t>(n));
14637 }
14638 else
14639 {
14640 if (add_prefix)
14641 {
14642 oa->write_character(to_char_type('H')); // high-precision number
14643 }
14644
14645 const auto number = BasicJsonType(n).dump();
14646 write_number_with_ubjson_prefix(number.size(), true);
14647 for (std::size_t i = 0; i < number.size(); ++i)
14648 {
14649 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14650 }
14651 }
14652 }
14653
14654 // UBJSON: write number (signed integer)
14655 template < typename NumberType, typename std::enable_if <
14656 std::is_signed<NumberType>::value&&
14657 !std::is_floating_point<NumberType>::value, int >::type = 0 >
14658 void write_number_with_ubjson_prefix(const NumberType n,
14659 const bool add_prefix)
14660 {
14661 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
14662 {
14663 if (add_prefix)
14664 {
14665 oa->write_character(to_char_type('i')); // int8
14666 }
14667 write_number(static_cast<std::int8_t>(n));
14668 }
14669 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)()))
14670 {
14671 if (add_prefix)
14672 {
14673 oa->write_character(to_char_type('U')); // uint8
14674 }
14675 write_number(static_cast<std::uint8_t>(n));
14676 }
14677 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
14678 {
14679 if (add_prefix)
14680 {
14681 oa->write_character(to_char_type('I')); // int16
14682 }
14683 write_number(static_cast<std::int16_t>(n));
14684 }
14685 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
14686 {
14687 if (add_prefix)
14688 {
14689 oa->write_character(to_char_type('l')); // int32
14690 }
14691 write_number(static_cast<std::int32_t>(n));
14692 }
14693 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
14694 {
14695 if (add_prefix)
14696 {
14697 oa->write_character(to_char_type('L')); // int64
14698 }
14699 write_number(static_cast<std::int64_t>(n));
14700 }
14701 // LCOV_EXCL_START
14702 else
14703 {
14704 if (add_prefix)
14705 {
14706 oa->write_character(to_char_type('H')); // high-precision number
14707 }
14708
14709 const auto number = BasicJsonType(n).dump();
14710 write_number_with_ubjson_prefix(number.size(), true);
14711 for (std::size_t i = 0; i < number.size(); ++i)
14712 {
14713 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14714 }
14715 }
14716 // LCOV_EXCL_STOP
14717 }
14718
14722 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
14723 {
14724 switch (j.type())
14725 {
14726 case value_t::null:
14727 return 'Z';
14728
14729 case value_t::boolean:
14730 return j.m_value.boolean ? 'T' : 'F';
14731
14732 case value_t::number_integer:
14733 {
14734 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)())
14735 {
14736 return 'i';
14737 }
14738 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)())
14739 {
14740 return 'U';
14741 }
14742 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)())
14743 {
14744 return 'I';
14745 }
14746 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)())
14747 {
14748 return 'l';
14749 }
14750 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)())
14751 {
14752 return 'L';
14753 }
14754 // anything else is treated as high-precision number
14755 return 'H'; // LCOV_EXCL_LINE
14756 }
14757
14758 case value_t::number_unsigned:
14759 {
14760 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14761 {
14762 return 'i';
14763 }
14764 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
14765 {
14766 return 'U';
14767 }
14768 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14769 {
14770 return 'I';
14771 }
14772 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14773 {
14774 return 'l';
14775 }
14776 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14777 {
14778 return 'L';
14779 }
14780 // anything else is treated as high-precision number
14781 return 'H'; // LCOV_EXCL_LINE
14782 }
14783
14784 case value_t::number_float:
14785 return get_ubjson_float_prefix(j.m_value.number_float);
14786
14787 case value_t::string:
14788 return 'S';
14789
14790 case value_t::array: // fallthrough
14791 case value_t::binary:
14792 return '[';
14793
14794 case value_t::object:
14795 return '{';
14796
14797 case value_t::discarded:
14798 default: // discarded values
14799 return 'N';
14800 }
14801 }
14802
14803 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
14804 {
14805 return 'd'; // float 32
14806 }
14807
14808 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
14809 {
14810 return 'D'; // float 64
14811 }
14812
14814 // Utility functions //
14816
14817 /*
14818 @brief write a number to output input
14819 @param[in] n number of type @a NumberType
14820 @tparam NumberType the type of the number
14821 @tparam OutputIsLittleEndian Set to true if output data is
14822 required to be little endian
14823
14824 @note This function needs to respect the system's endianness, because bytes
14825 in CBOR, MessagePack, and UBJSON are stored in network order (big
14826 endian) and therefore need reordering on little endian systems.
14827 */
14828 template<typename NumberType, bool OutputIsLittleEndian = false>
14829 void write_number(const NumberType n)
14830 {
14831 // step 1: write number to array of length NumberType
14832 std::array<CharType, sizeof(NumberType)> vec{};
14833 std::memcpy(vec.data(), &n, sizeof(NumberType));
14834
14835 // step 2: write array to output (with possible reordering)
14836 if (is_little_endian != OutputIsLittleEndian)
14837 {
14838 // reverse byte order prior to conversion if necessary
14839 std::reverse(vec.begin(), vec.end());
14840 }
14841
14842 oa->write_characters(vec.data(), sizeof(NumberType));
14843 }
14844
14846 {
14847#ifdef __GNUC__
14848#pragma GCC diagnostic push
14849#pragma GCC diagnostic ignored "-Wfloat-equal"
14850#endif
14851 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
14852 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
14853 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
14854 {
14855 oa->write_character(format == detail::input_format_t::cbor
14856 ? get_cbor_float_prefix(static_cast<float>(n))
14857 : get_msgpack_float_prefix(static_cast<float>(n)));
14858 write_number(static_cast<float>(n));
14859 }
14860 else
14861 {
14862 oa->write_character(format == detail::input_format_t::cbor
14863 ? get_cbor_float_prefix(n)
14864 : get_msgpack_float_prefix(n));
14865 write_number(n);
14866 }
14867#ifdef __GNUC__
14868#pragma GCC diagnostic pop
14869#endif
14870 }
14871
14872 public:
14873 // The following to_char_type functions are implement the conversion
14874 // between uint8_t and CharType. In case CharType is not unsigned,
14875 // such a conversion is required to allow values greater than 128.
14876 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
14877 template < typename C = CharType,
14878 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
14879 static constexpr CharType to_char_type(std::uint8_t x) noexcept
14880 {
14881 return *reinterpret_cast<char*>(&x);
14882 }
14883
14884 template < typename C = CharType,
14885 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
14886 static CharType to_char_type(std::uint8_t x) noexcept
14887 {
14888 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
14889 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
14890 CharType result;
14891 std::memcpy(&result, &x, sizeof(x));
14892 return result;
14893 }
14894
14895 template<typename C = CharType,
14897 static constexpr CharType to_char_type(std::uint8_t x) noexcept
14898 {
14899 return x;
14900 }
14901
14902 template < typename InputCharType, typename C = CharType,
14903 enable_if_t <
14904 std::is_signed<C>::value &&
14905 std::is_signed<char>::value &&
14906 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
14907 > * = nullptr >
14908 static constexpr CharType to_char_type(InputCharType x) noexcept
14909 {
14910 return x;
14911 }
14912
14913 private:
14915 const bool is_little_endian = little_endianness();
14916
14919};
14920} // namespace detail
14921} // namespace nlohmann
14922
14923// #include <nlohmann/detail/output/output_adapters.hpp>
14924
14925// #include <nlohmann/detail/output/serializer.hpp>
14926
14927
14928#include <algorithm> // reverse, remove, fill, find, none_of
14929#include <array> // array
14930#include <clocale> // localeconv, lconv
14931#include <cmath> // labs, isfinite, isnan, signbit
14932#include <cstddef> // size_t, ptrdiff_t
14933#include <cstdint> // uint8_t
14934#include <cstdio> // snprintf
14935#include <limits> // numeric_limits
14936#include <string> // string, char_traits
14937#include <iomanip> // setfill, setw
14938#include <sstream> // stringstream
14939#include <type_traits> // is_same
14940#include <utility> // move
14941
14942// #include <nlohmann/detail/conversions/to_chars.hpp>
14943
14944
14945#include <array> // array
14946#include <cmath> // signbit, isfinite
14947#include <cstdint> // intN_t, uintN_t
14948#include <cstring> // memcpy, memmove
14949#include <limits> // numeric_limits
14950#include <type_traits> // conditional
14951
14952// #include <nlohmann/detail/macro_scope.hpp>
14953
14954
14955namespace nlohmann
14956{
14957namespace detail
14958{
14959
14979namespace dtoa_impl
14980{
14981
14982template<typename Target, typename Source>
14983Target reinterpret_bits(const Source source)
14984{
14985 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
14986
14987 Target target;
14988 std::memcpy(&target, &source, sizeof(Source));
14989 return target;
14990}
14991
14992struct diyfp // f * 2^e
14993{
14994 static constexpr int kPrecision = 64; // = q
14995
14996 std::uint64_t f = 0;
14997 int e = 0;
14998
14999 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
15000
15005 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
15006 {
15007 JSON_ASSERT(x.e == y.e);
15008 JSON_ASSERT(x.f >= y.f);
15009
15010 return {x.f - y.f, x.e};
15011 }
15012
15017 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
15018 {
15019 static_assert(kPrecision == 64, "internal error");
15020
15021 // Computes:
15022 // f = round((x.f * y.f) / 2^q)
15023 // e = x.e + y.e + q
15024
15025 // Emulate the 64-bit * 64-bit multiplication:
15026 //
15027 // p = u * v
15028 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15029 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
15030 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
15031 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
15032 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
15033 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
15034 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
15035 //
15036 // (Since Q might be larger than 2^32 - 1)
15037 //
15038 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15039 //
15040 // (Q_hi + H does not overflow a 64-bit int)
15041 //
15042 // = p_lo + 2^64 p_hi
15043
15044 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15045 const std::uint64_t u_hi = x.f >> 32u;
15046 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15047 const std::uint64_t v_hi = y.f >> 32u;
15048
15049 const std::uint64_t p0 = u_lo * v_lo;
15050 const std::uint64_t p1 = u_lo * v_hi;
15051 const std::uint64_t p2 = u_hi * v_lo;
15052 const std::uint64_t p3 = u_hi * v_hi;
15053
15054 const std::uint64_t p0_hi = p0 >> 32u;
15055 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15056 const std::uint64_t p1_hi = p1 >> 32u;
15057 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15058 const std::uint64_t p2_hi = p2 >> 32u;
15059
15060 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15061
15062 // The full product might now be computed as
15063 //
15064 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
15065 // p_lo = p0_lo + (Q << 32)
15066 //
15067 // But in this particular case here, the full p_lo is not required.
15068 // Effectively we only need to add the highest bit in p_lo to p_hi (and
15069 // Q_hi + 1 does not overflow).
15070
15071 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
15072
15073 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15074
15075 return {h, x.e + y.e + 64};
15076 }
15077
15082 static diyfp normalize(diyfp x) noexcept
15083 {
15084 JSON_ASSERT(x.f != 0);
15085
15086 while ((x.f >> 63u) == 0)
15087 {
15088 x.f <<= 1u;
15089 x.e--;
15090 }
15091
15092 return x;
15093 }
15094
15099 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
15100 {
15101 const int delta = x.e - target_exponent;
15102
15103 JSON_ASSERT(delta >= 0);
15104 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
15105
15106 return {x.f << delta, target_exponent};
15107 }
15108};
15109
15116
15123template<typename FloatType>
15125{
15126 JSON_ASSERT(std::isfinite(value));
15127 JSON_ASSERT(value > 0);
15128
15129 // Convert the IEEE representation into a diyfp.
15130 //
15131 // If v is denormal:
15132 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
15133 // If v is normalized:
15134 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
15135
15136 static_assert(std::numeric_limits<FloatType>::is_iec559,
15137 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
15138
15139 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
15140 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
15141 constexpr int kMinExp = 1 - kBias;
15142 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
15143
15144 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
15145
15146 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
15147 const std::uint64_t E = bits >> (kPrecision - 1);
15148 const std::uint64_t F = bits & (kHiddenBit - 1);
15149
15150 const bool is_denormal = E == 0;
15151 const diyfp v = is_denormal
15152 ? diyfp(F, kMinExp)
15153 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
15154
15155 // Compute the boundaries m- and m+ of the floating-point value
15156 // v = f * 2^e.
15157 //
15158 // Determine v- and v+, the floating-point predecessor and successor if v,
15159 // respectively.
15160 //
15161 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
15162 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
15163 //
15164 // v+ = v + 2^e
15165 //
15166 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
15167 // between m- and m+ round to v, regardless of how the input rounding
15168 // algorithm breaks ties.
15169 //
15170 // ---+-------------+-------------+-------------+-------------+--- (A)
15171 // v- m- v m+ v+
15172 //
15173 // -----------------+------+------+-------------+-------------+--- (B)
15174 // v- m- v m+ v+
15175
15176 const bool lower_boundary_is_closer = F == 0 && E > 1;
15177 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
15178 const diyfp m_minus = lower_boundary_is_closer
15179 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
15180 : diyfp(2 * v.f - 1, v.e - 1); // (A)
15181
15182 // Determine the normalized w+ = m+.
15183 const diyfp w_plus = diyfp::normalize(m_plus);
15184
15185 // Determine w- = m- such that e_(w-) = e_(w+).
15186 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
15187
15188 return {diyfp::normalize(v), w_minus, w_plus};
15189}
15190
15191// Given normalized diyfp w, Grisu needs to find a (normalized) cached
15192// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
15193// within a certain range [alpha, gamma] (Definition 3.2 from [1])
15194//
15195// alpha <= e = e_c + e_w + q <= gamma
15196//
15197// or
15198//
15199// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
15200// <= f_c * f_w * 2^gamma
15201//
15202// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
15203//
15204// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
15205//
15206// or
15207//
15208// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
15209//
15210// The choice of (alpha,gamma) determines the size of the table and the form of
15211// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
15212// in practice:
15213//
15214// The idea is to cut the number c * w = f * 2^e into two parts, which can be
15215// processed independently: An integral part p1, and a fractional part p2:
15216//
15217// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
15218// = (f div 2^-e) + (f mod 2^-e) * 2^e
15219// = p1 + p2 * 2^e
15220//
15221// The conversion of p1 into decimal form requires a series of divisions and
15222// modulos by (a power of) 10. These operations are faster for 32-bit than for
15223// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
15224// achieved by choosing
15225//
15226// -e >= 32 or e <= -32 := gamma
15227//
15228// In order to convert the fractional part
15229//
15230// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
15231//
15232// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
15233// d[-i] are extracted in order:
15234//
15235// (10 * p2) div 2^-e = d[-1]
15236// (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
15237//
15238// The multiplication by 10 must not overflow. It is sufficient to choose
15239//
15240// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
15241//
15242// Since p2 = f mod 2^-e < 2^-e,
15243//
15244// -e <= 60 or e >= -60 := alpha
15245
15246constexpr int kAlpha = -60;
15247constexpr int kGamma = -32;
15248
15249struct cached_power // c = f * 2^e ~= 10^k
15250{
15251 std::uint64_t f;
15252 int e;
15253 int k;
15254};
15255
15264{
15265 // Now
15266 //
15267 // alpha <= e_c + e + q <= gamma (1)
15268 // ==> f_c * 2^alpha <= c * 2^e * 2^q
15269 //
15270 // and since the c's are normalized, 2^(q-1) <= f_c,
15271 //
15272 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
15273 // ==> 2^(alpha - e - 1) <= c
15274 //
15275 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
15276 //
15277 // k = ceil( log_10( 2^(alpha - e - 1) ) )
15278 // = ceil( (alpha - e - 1) * log_10(2) )
15279 //
15280 // From the paper:
15281 // "In theory the result of the procedure could be wrong since c is rounded,
15282 // and the computation itself is approximated [...]. In practice, however,
15283 // this simple function is sufficient."
15284 //
15285 // For IEEE double precision floating-point numbers converted into
15286 // normalized diyfp's w = f * 2^e, with q = 64,
15287 //
15288 // e >= -1022 (min IEEE exponent)
15289 // -52 (p - 1)
15290 // -52 (p - 1, possibly normalize denormal IEEE numbers)
15291 // -11 (normalize the diyfp)
15292 // = -1137
15293 //
15294 // and
15295 //
15296 // e <= +1023 (max IEEE exponent)
15297 // -52 (p - 1)
15298 // -11 (normalize the diyfp)
15299 // = 960
15300 //
15301 // This binary exponent range [-1137,960] results in a decimal exponent
15302 // range [-307,324]. One does not need to store a cached power for each
15303 // k in this range. For each such k it suffices to find a cached power
15304 // such that the exponent of the product lies in [alpha,gamma].
15305 // This implies that the difference of the decimal exponents of adjacent
15306 // table entries must be less than or equal to
15307 //
15308 // floor( (gamma - alpha) * log_10(2) ) = 8.
15309 //
15310 // (A smaller distance gamma-alpha would require a larger table.)
15311
15312 // NB:
15313 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
15314
15315 constexpr int kCachedPowersMinDecExp = -300;
15316 constexpr int kCachedPowersDecStep = 8;
15317
15318 static constexpr std::array<cached_power, 79> kCachedPowers =
15319 {
15320 {
15321 { 0xAB70FE17C79AC6CA, -1060, -300 },
15322 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
15323 { 0xBE5691EF416BD60C, -1007, -284 },
15324 { 0x8DD01FAD907FFC3C, -980, -276 },
15325 { 0xD3515C2831559A83, -954, -268 },
15326 { 0x9D71AC8FADA6C9B5, -927, -260 },
15327 { 0xEA9C227723EE8BCB, -901, -252 },
15328 { 0xAECC49914078536D, -874, -244 },
15329 { 0x823C12795DB6CE57, -847, -236 },
15330 { 0xC21094364DFB5637, -821, -228 },
15331 { 0x9096EA6F3848984F, -794, -220 },
15332 { 0xD77485CB25823AC7, -768, -212 },
15333 { 0xA086CFCD97BF97F4, -741, -204 },
15334 { 0xEF340A98172AACE5, -715, -196 },
15335 { 0xB23867FB2A35B28E, -688, -188 },
15336 { 0x84C8D4DFD2C63F3B, -661, -180 },
15337 { 0xC5DD44271AD3CDBA, -635, -172 },
15338 { 0x936B9FCEBB25C996, -608, -164 },
15339 { 0xDBAC6C247D62A584, -582, -156 },
15340 { 0xA3AB66580D5FDAF6, -555, -148 },
15341 { 0xF3E2F893DEC3F126, -529, -140 },
15342 { 0xB5B5ADA8AAFF80B8, -502, -132 },
15343 { 0x87625F056C7C4A8B, -475, -124 },
15344 { 0xC9BCFF6034C13053, -449, -116 },
15345 { 0x964E858C91BA2655, -422, -108 },
15346 { 0xDFF9772470297EBD, -396, -100 },
15347 { 0xA6DFBD9FB8E5B88F, -369, -92 },
15348 { 0xF8A95FCF88747D94, -343, -84 },
15349 { 0xB94470938FA89BCF, -316, -76 },
15350 { 0x8A08F0F8BF0F156B, -289, -68 },
15351 { 0xCDB02555653131B6, -263, -60 },
15352 { 0x993FE2C6D07B7FAC, -236, -52 },
15353 { 0xE45C10C42A2B3B06, -210, -44 },
15354 { 0xAA242499697392D3, -183, -36 },
15355 { 0xFD87B5F28300CA0E, -157, -28 },
15356 { 0xBCE5086492111AEB, -130, -20 },
15357 { 0x8CBCCC096F5088CC, -103, -12 },
15358 { 0xD1B71758E219652C, -77, -4 },
15359 { 0x9C40000000000000, -50, 4 },
15360 { 0xE8D4A51000000000, -24, 12 },
15361 { 0xAD78EBC5AC620000, 3, 20 },
15362 { 0x813F3978F8940984, 30, 28 },
15363 { 0xC097CE7BC90715B3, 56, 36 },
15364 { 0x8F7E32CE7BEA5C70, 83, 44 },
15365 { 0xD5D238A4ABE98068, 109, 52 },
15366 { 0x9F4F2726179A2245, 136, 60 },
15367 { 0xED63A231D4C4FB27, 162, 68 },
15368 { 0xB0DE65388CC8ADA8, 189, 76 },
15369 { 0x83C7088E1AAB65DB, 216, 84 },
15370 { 0xC45D1DF942711D9A, 242, 92 },
15371 { 0x924D692CA61BE758, 269, 100 },
15372 { 0xDA01EE641A708DEA, 295, 108 },
15373 { 0xA26DA3999AEF774A, 322, 116 },
15374 { 0xF209787BB47D6B85, 348, 124 },
15375 { 0xB454E4A179DD1877, 375, 132 },
15376 { 0x865B86925B9BC5C2, 402, 140 },
15377 { 0xC83553C5C8965D3D, 428, 148 },
15378 { 0x952AB45CFA97A0B3, 455, 156 },
15379 { 0xDE469FBD99A05FE3, 481, 164 },
15380 { 0xA59BC234DB398C25, 508, 172 },
15381 { 0xF6C69A72A3989F5C, 534, 180 },
15382 { 0xB7DCBF5354E9BECE, 561, 188 },
15383 { 0x88FCF317F22241E2, 588, 196 },
15384 { 0xCC20CE9BD35C78A5, 614, 204 },
15385 { 0x98165AF37B2153DF, 641, 212 },
15386 { 0xE2A0B5DC971F303A, 667, 220 },
15387 { 0xA8D9D1535CE3B396, 694, 228 },
15388 { 0xFB9B7CD9A4A7443C, 720, 236 },
15389 { 0xBB764C4CA7A44410, 747, 244 },
15390 { 0x8BAB8EEFB6409C1A, 774, 252 },
15391 { 0xD01FEF10A657842C, 800, 260 },
15392 { 0x9B10A4E5E9913129, 827, 268 },
15393 { 0xE7109BFBA19C0C9D, 853, 276 },
15394 { 0xAC2820D9623BF429, 880, 284 },
15395 { 0x80444B5E7AA7CF85, 907, 292 },
15396 { 0xBF21E44003ACDD2D, 933, 300 },
15397 { 0x8E679C2F5E44FF8F, 960, 308 },
15398 { 0xD433179D9C8CB841, 986, 316 },
15399 { 0x9E19DB92B4E31BA9, 1013, 324 },
15400 }
15401 };
15402
15403 // This computation gives exactly the same results for k as
15404 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
15405 // for |e| <= 1500, but doesn't require floating-point operations.
15406 // NB: log_10(2) ~= 78913 / 2^18
15407 JSON_ASSERT(e >= -1500);
15408 JSON_ASSERT(e <= 1500);
15409 const int f = kAlpha - e - 1;
15410 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
15411
15412 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
15413 JSON_ASSERT(index >= 0);
15414 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
15415
15416 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
15417 JSON_ASSERT(kAlpha <= cached.e + e + 64);
15418 JSON_ASSERT(kGamma >= cached.e + e + 64);
15419
15420 return cached;
15421}
15422
15427inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
15428{
15429 // LCOV_EXCL_START
15430 if (n >= 1000000000)
15431 {
15432 pow10 = 1000000000;
15433 return 10;
15434 }
15435 // LCOV_EXCL_STOP
15436 if (n >= 100000000)
15437 {
15438 pow10 = 100000000;
15439 return 9;
15440 }
15441 if (n >= 10000000)
15442 {
15443 pow10 = 10000000;
15444 return 8;
15445 }
15446 if (n >= 1000000)
15447 {
15448 pow10 = 1000000;
15449 return 7;
15450 }
15451 if (n >= 100000)
15452 {
15453 pow10 = 100000;
15454 return 6;
15455 }
15456 if (n >= 10000)
15457 {
15458 pow10 = 10000;
15459 return 5;
15460 }
15461 if (n >= 1000)
15462 {
15463 pow10 = 1000;
15464 return 4;
15465 }
15466 if (n >= 100)
15467 {
15468 pow10 = 100;
15469 return 3;
15470 }
15471 if (n >= 10)
15472 {
15473 pow10 = 10;
15474 return 2;
15475 }
15476
15477 pow10 = 1;
15478 return 1;
15479}
15480
15481inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
15482 std::uint64_t rest, std::uint64_t ten_k)
15483{
15484 JSON_ASSERT(len >= 1);
15485 JSON_ASSERT(dist <= delta);
15486 JSON_ASSERT(rest <= delta);
15487 JSON_ASSERT(ten_k > 0);
15488
15489 // <--------------------------- delta ---->
15490 // <---- dist --------->
15491 // --------------[------------------+-------------------]--------------
15492 // M- w M+
15493 //
15494 // ten_k
15495 // <------>
15496 // <---- rest ---->
15497 // --------------[------------------+----+--------------]--------------
15498 // w V
15499 // = buf * 10^k
15500 //
15501 // ten_k represents a unit-in-the-last-place in the decimal representation
15502 // stored in buf.
15503 // Decrement buf by ten_k while this takes buf closer to w.
15504
15505 // The tests are written in this order to avoid overflow in unsigned
15506 // integer arithmetic.
15507
15508 while (rest < dist
15509 && delta - rest >= ten_k
15510 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
15511 {
15512 JSON_ASSERT(buf[len - 1] != '0');
15513 buf[len - 1]--;
15514 rest += ten_k;
15515 }
15516}
15517
15522inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
15523 diyfp M_minus, diyfp w, diyfp M_plus)
15524{
15525 static_assert(kAlpha >= -60, "internal error");
15526 static_assert(kGamma <= -32, "internal error");
15527
15528 // Generates the digits (and the exponent) of a decimal floating-point
15529 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15530 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15531 //
15532 // <--------------------------- delta ---->
15533 // <---- dist --------->
15534 // --------------[------------------+-------------------]--------------
15535 // M- w M+
15536 //
15537 // Grisu2 generates the digits of M+ from left to right and stops as soon as
15538 // V is in [M-,M+].
15539
15540 JSON_ASSERT(M_plus.e >= kAlpha);
15541 JSON_ASSERT(M_plus.e <= kGamma);
15542
15543 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15544 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
15545
15546 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15547 //
15548 // M+ = f * 2^e
15549 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15550 // = ((p1 ) * 2^-e + (p2 )) * 2^e
15551 // = p1 + p2 * 2^e
15552
15553 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15554
15555 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.)
15556 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
15557
15558 // 1)
15559 //
15560 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15561
15562 JSON_ASSERT(p1 > 0);
15563
15564 std::uint32_t pow10{};
15565 const int k = find_largest_pow10(p1, pow10);
15566
15567 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15568 //
15569 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15570 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
15571 //
15572 // M+ = p1 + p2 * 2^e
15573 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
15574 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15575 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
15576 //
15577 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15578 //
15579 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15580 //
15581 // but stop as soon as
15582 //
15583 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15584
15585 int n = k;
15586 while (n > 0)
15587 {
15588 // Invariants:
15589 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
15590 // pow10 = 10^(n-1) <= p1 < 10^n
15591 //
15592 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
15593 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
15594 //
15595 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15596 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15597 //
15598 JSON_ASSERT(d <= 9);
15599 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15600 //
15601 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15602 //
15603 p1 = r;
15604 n--;
15605 //
15606 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
15607 // pow10 = 10^n
15608 //
15609
15610 // Now check if enough digits have been generated.
15611 // Compute
15612 //
15613 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15614 //
15615 // Note:
15616 // Since rest and delta share the same exponent e, it suffices to
15617 // compare the significands.
15618 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15619 if (rest <= delta)
15620 {
15621 // V = buffer * 10^n, with M- <= V <= M+.
15622
15623 decimal_exponent += n;
15624
15625 // We may now just stop. But instead look if the buffer could be
15626 // decremented to bring V closer to w.
15627 //
15628 // pow10 = 10^n is now 1 ulp in the decimal representation V.
15629 // The rounding procedure works with diyfp's with an implicit
15630 // exponent of e.
15631 //
15632 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15633 //
15634 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
15635 grisu2_round(buffer, length, dist, delta, rest, ten_n);
15636
15637 return;
15638 }
15639
15640 pow10 /= 10;
15641 //
15642 // pow10 = 10^(n-1) <= p1 < 10^n
15643 // Invariants restored.
15644 }
15645
15646 // 2)
15647 //
15648 // The digits of the integral part have been generated:
15649 //
15650 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15651 // = buffer + p2 * 2^e
15652 //
15653 // Now generate the digits of the fractional part p2 * 2^e.
15654 //
15655 // Note:
15656 // No decimal point is generated: the exponent is adjusted instead.
15657 //
15658 // p2 actually represents the fraction
15659 //
15660 // p2 * 2^e
15661 // = p2 / 2^-e
15662 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
15663 //
15664 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15665 //
15666 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15667 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15668 //
15669 // using
15670 //
15671 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15672 // = ( d) * 2^-e + ( r)
15673 //
15674 // or
15675 // 10^m * p2 * 2^e = d + r * 2^e
15676 //
15677 // i.e.
15678 //
15679 // M+ = buffer + p2 * 2^e
15680 // = buffer + 10^-m * (d + r * 2^e)
15681 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15682 //
15683 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15684
15685 JSON_ASSERT(p2 > delta);
15686
15687 int m = 0;
15688 for (;;)
15689 {
15690 // Invariant:
15691 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15692 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
15693 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
15694 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15695 //
15696 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
15697 p2 *= 10;
15698 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
15699 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15700 //
15701 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15702 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15703 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15704 //
15705 JSON_ASSERT(d <= 9);
15706 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15707 //
15708 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15709 //
15710 p2 = r;
15711 m++;
15712 //
15713 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15714 // Invariant restored.
15715
15716 // Check if enough digits have been generated.
15717 //
15718 // 10^-m * p2 * 2^e <= delta * 2^e
15719 // p2 * 2^e <= 10^m * delta * 2^e
15720 // p2 <= 10^m * delta
15721 delta *= 10;
15722 dist *= 10;
15723 if (p2 <= delta)
15724 {
15725 break;
15726 }
15727 }
15728
15729 // V = buffer * 10^-m, with M- <= V <= M+.
15730
15731 decimal_exponent -= m;
15732
15733 // 1 ulp in the decimal representation is now 10^-m.
15734 // Since delta and dist are now scaled by 10^m, we need to do the
15735 // same with ulp in order to keep the units in sync.
15736 //
15737 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
15738 //
15739 const std::uint64_t ten_m = one.f;
15740 grisu2_round(buffer, length, dist, delta, p2, ten_m);
15741
15742 // By construction this algorithm generates the shortest possible decimal
15743 // number (Loitsch, Theorem 6.2) which rounds back to w.
15744 // For an input number of precision p, at least
15745 //
15746 // N = 1 + ceil(p * log_10(2))
15747 //
15748 // decimal digits are sufficient to identify all binary floating-point
15749 // numbers (Matula, "In-and-Out conversions").
15750 // This implies that the algorithm does not produce more than N decimal
15751 // digits.
15752 //
15753 // N = 17 for p = 53 (IEEE double precision)
15754 // N = 9 for p = 24 (IEEE single precision)
15755}
15756
15763inline void grisu2(char* buf, int& len, int& decimal_exponent,
15764 diyfp m_minus, diyfp v, diyfp m_plus)
15765{
15766 JSON_ASSERT(m_plus.e == m_minus.e);
15767 JSON_ASSERT(m_plus.e == v.e);
15768
15769 // --------(-----------------------+-----------------------)-------- (A)
15770 // m- v m+
15771 //
15772 // --------------------(-----------+-----------------------)-------- (B)
15773 // m- v m+
15774 //
15775 // First scale v (and m- and m+) such that the exponent is in the range
15776 // [alpha, gamma].
15777
15778 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
15779
15780 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
15781
15782 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
15783 const diyfp w = diyfp::mul(v, c_minus_k);
15784 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
15785 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
15786
15787 // ----(---+---)---------------(---+---)---------------(---+---)----
15788 // w- w w+
15789 // = c*m- = c*v = c*m+
15790 //
15791 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
15792 // w+ are now off by a small amount.
15793 // In fact:
15794 //
15795 // w - v * 10^k < 1 ulp
15796 //
15797 // To account for this inaccuracy, add resp. subtract 1 ulp.
15798 //
15799 // --------+---[---------------(---+---)---------------]---+--------
15800 // w- M- w M+ w+
15801 //
15802 // Now any number in [M-, M+] (bounds included) will round to w when input,
15803 // regardless of how the input rounding algorithm breaks ties.
15804 //
15805 // And digit_gen generates the shortest possible such number in [M-, M+].
15806 // Note that this does not mean that Grisu2 always generates the shortest
15807 // possible number in the interval (m-, m+).
15808 const diyfp M_minus(w_minus.f + 1, w_minus.e);
15809 const diyfp M_plus (w_plus.f - 1, w_plus.e );
15810
15811 decimal_exponent = -cached.k; // = -(-k) = k
15812
15813 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
15814}
15815
15821template<typename FloatType>
15823void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
15824{
15825 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
15826 "internal error: not enough precision");
15827
15828 JSON_ASSERT(std::isfinite(value));
15829 JSON_ASSERT(value > 0);
15830
15831 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
15832 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
15833 // decimal representations are not exactly "short".
15834 //
15835 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
15836 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
15837 // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
15838 // does.
15839 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
15840 // representation using the corresponding std::from_chars function recovers value exactly". That
15841 // indicates that single precision floating-point numbers should be recovered using
15842 // 'std::strtof'.
15843 //
15844 // NB: If the neighbors are computed for single-precision numbers, there is a single float
15845 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
15846 // value is off by 1 ulp.
15847#if 0
15848 const boundaries w = compute_boundaries(static_cast<double>(value));
15849#else
15851#endif
15852
15853 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
15854}
15855
15863inline char* append_exponent(char* buf, int e)
15864{
15865 JSON_ASSERT(e > -1000);
15866 JSON_ASSERT(e < 1000);
15867
15868 if (e < 0)
15869 {
15870 e = -e;
15871 *buf++ = '-';
15872 }
15873 else
15874 {
15875 *buf++ = '+';
15876 }
15877
15878 auto k = static_cast<std::uint32_t>(e);
15879 if (k < 10)
15880 {
15881 // Always print at least two digits in the exponent.
15882 // This is for compatibility with printf("%g").
15883 *buf++ = '0';
15884 *buf++ = static_cast<char>('0' + k);
15885 }
15886 else if (k < 100)
15887 {
15888 *buf++ = static_cast<char>('0' + k / 10);
15889 k %= 10;
15890 *buf++ = static_cast<char>('0' + k);
15891 }
15892 else
15893 {
15894 *buf++ = static_cast<char>('0' + k / 100);
15895 k %= 100;
15896 *buf++ = static_cast<char>('0' + k / 10);
15897 k %= 10;
15898 *buf++ = static_cast<char>('0' + k);
15899 }
15900
15901 return buf;
15902}
15903
15915inline char* format_buffer(char* buf, int len, int decimal_exponent,
15916 int min_exp, int max_exp)
15917{
15918 JSON_ASSERT(min_exp < 0);
15919 JSON_ASSERT(max_exp > 0);
15920
15921 const int k = len;
15922 const int n = len + decimal_exponent;
15923
15924 // v = buf * 10^(n-k)
15925 // k is the length of the buffer (number of decimal digits)
15926 // n is the position of the decimal point relative to the start of the buffer.
15927
15928 if (k <= n && n <= max_exp)
15929 {
15930 // digits[000]
15931 // len <= max_exp + 2
15932
15933 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
15934 // Make it look like a floating-point number (#362, #378)
15935 buf[n + 0] = '.';
15936 buf[n + 1] = '0';
15937 return buf + (static_cast<size_t>(n) + 2);
15938 }
15939
15940 if (0 < n && n <= max_exp)
15941 {
15942 // dig.its
15943 // len <= max_digits10 + 1
15944
15945 JSON_ASSERT(k > n);
15946
15947 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
15948 buf[n] = '.';
15949 return buf + (static_cast<size_t>(k) + 1U);
15950 }
15951
15952 if (min_exp < n && n <= 0)
15953 {
15954 // 0.[000]digits
15955 // len <= 2 + (-min_exp - 1) + max_digits10
15956
15957 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
15958 buf[0] = '0';
15959 buf[1] = '.';
15960 std::memset(buf + 2, '0', static_cast<size_t>(-n));
15961 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
15962 }
15963
15964 if (k == 1)
15965 {
15966 // dE+123
15967 // len <= 1 + 5
15968
15969 buf += 1;
15970 }
15971 else
15972 {
15973 // d.igitsE+123
15974 // len <= max_digits10 + 1 + 5
15975
15976 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
15977 buf[1] = '.';
15978 buf += 1 + static_cast<size_t>(k);
15979 }
15980
15981 *buf++ = 'e';
15982 return append_exponent(buf, n - 1);
15983}
15984
15985} // namespace dtoa_impl
15986
15997template<typename FloatType>
16000char* to_chars(char* first, const char* last, FloatType value)
16001{
16002 static_cast<void>(last); // maybe unused - fix warning
16003 JSON_ASSERT(std::isfinite(value));
16004
16005 // Use signbit(value) instead of (value < 0) since signbit works for -0.
16006 if (std::signbit(value))
16007 {
16008 value = -value;
16009 *first++ = '-';
16010 }
16011
16012#ifdef __GNUC__
16013#pragma GCC diagnostic push
16014#pragma GCC diagnostic ignored "-Wfloat-equal"
16015#endif
16016 if (value == 0) // +-0
16017 {
16018 *first++ = '0';
16019 // Make it look like a floating-point number (#362, #378)
16020 *first++ = '.';
16021 *first++ = '0';
16022 return first;
16023 }
16024#ifdef __GNUC__
16025#pragma GCC diagnostic pop
16026#endif
16027
16028 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
16029
16030 // Compute v = buffer * 10^decimal_exponent.
16031 // The decimal digits are stored in the buffer, which needs to be interpreted
16032 // as an unsigned decimal integer.
16033 // len is the length of the buffer, i.e. the number of decimal digits.
16034 int len = 0;
16035 int decimal_exponent = 0;
16036 dtoa_impl::grisu2(first, len, decimal_exponent, value);
16037
16038 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
16039
16040 // Format the buffer like printf("%.*g", prec, value)
16041 constexpr int kMinExp = -4;
16042 // Use digits10 here to increase compatibility with version 2.
16043 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
16044
16045 JSON_ASSERT(last - first >= kMaxExp + 2);
16046 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
16047 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
16048
16049 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
16050}
16051
16052} // namespace detail
16053} // namespace nlohmann
16054
16055// #include <nlohmann/detail/exceptions.hpp>
16056
16057// #include <nlohmann/detail/macro_scope.hpp>
16058
16059// #include <nlohmann/detail/meta/cpp_future.hpp>
16060
16061// #include <nlohmann/detail/output/binary_writer.hpp>
16062
16063// #include <nlohmann/detail/output/output_adapters.hpp>
16064
16065// #include <nlohmann/detail/value_t.hpp>
16066
16067
16068namespace nlohmann
16069{
16070namespace detail
16071{
16073// serialization //
16075
16078{
16079 strict,
16080 replace,
16081 ignore
16082};
16083
16084template<typename BasicJsonType>
16086{
16087 using string_t = typename BasicJsonType::string_t;
16088 using number_float_t = typename BasicJsonType::number_float_t;
16089 using number_integer_t = typename BasicJsonType::number_integer_t;
16090 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
16091 using binary_char_t = typename BasicJsonType::binary_t::value_type;
16092 static constexpr std::uint8_t UTF8_ACCEPT = 0;
16093 static constexpr std::uint8_t UTF8_REJECT = 1;
16094
16095 public:
16103 : o(std::move(s))
16104 , loc(std::localeconv())
16105 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
16106 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
16107 , indent_char(ichar)
16109 , error_handler(error_handler_)
16110 {}
16111
16112 // delete because of pointer members
16113 serializer(const serializer&) = delete;
16117 ~serializer() = default;
16118
16141 void dump(const BasicJsonType& val,
16142 const bool pretty_print,
16143 const bool ensure_ascii,
16144 const unsigned int indent_step,
16145 const unsigned int current_indent = 0)
16146 {
16147 switch (val.m_type)
16148 {
16149 case value_t::object:
16150 {
16151 if (val.m_value.object->empty())
16152 {
16153 o->write_characters("{}", 2);
16154 return;
16155 }
16156
16157 if (pretty_print)
16158 {
16159 o->write_characters("{\n", 2);
16160
16161 // variable to hold indentation for recursive calls
16162 const auto new_indent = current_indent + indent_step;
16163 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16164 {
16165 indent_string.resize(indent_string.size() * 2, ' ');
16166 }
16167
16168 // first n-1 elements
16169 auto i = val.m_value.object->cbegin();
16170 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16171 {
16172 o->write_characters(indent_string.c_str(), new_indent);
16173 o->write_character('\"');
16174 dump_escaped(i->first, ensure_ascii);
16175 o->write_characters("\": ", 3);
16176 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16177 o->write_characters(",\n", 2);
16178 }
16179
16180 // last element
16181 JSON_ASSERT(i != val.m_value.object->cend());
16182 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16183 o->write_characters(indent_string.c_str(), new_indent);
16184 o->write_character('\"');
16185 dump_escaped(i->first, ensure_ascii);
16186 o->write_characters("\": ", 3);
16187 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16188
16189 o->write_character('\n');
16190 o->write_characters(indent_string.c_str(), current_indent);
16191 o->write_character('}');
16192 }
16193 else
16194 {
16195 o->write_character('{');
16196
16197 // first n-1 elements
16198 auto i = val.m_value.object->cbegin();
16199 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16200 {
16201 o->write_character('\"');
16202 dump_escaped(i->first, ensure_ascii);
16203 o->write_characters("\":", 2);
16204 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16205 o->write_character(',');
16206 }
16207
16208 // last element
16209 JSON_ASSERT(i != val.m_value.object->cend());
16210 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16211 o->write_character('\"');
16212 dump_escaped(i->first, ensure_ascii);
16213 o->write_characters("\":", 2);
16214 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16215
16216 o->write_character('}');
16217 }
16218
16219 return;
16220 }
16221
16222 case value_t::array:
16223 {
16224 if (val.m_value.array->empty())
16225 {
16226 o->write_characters("[]", 2);
16227 return;
16228 }
16229
16230 if (pretty_print)
16231 {
16232 o->write_characters("[\n", 2);
16233
16234 // variable to hold indentation for recursive calls
16235 const auto new_indent = current_indent + indent_step;
16236 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16237 {
16238 indent_string.resize(indent_string.size() * 2, ' ');
16239 }
16240
16241 // first n-1 elements
16242 for (auto i = val.m_value.array->cbegin();
16243 i != val.m_value.array->cend() - 1; ++i)
16244 {
16245 o->write_characters(indent_string.c_str(), new_indent);
16246 dump(*i, true, ensure_ascii, indent_step, new_indent);
16247 o->write_characters(",\n", 2);
16248 }
16249
16250 // last element
16251 JSON_ASSERT(!val.m_value.array->empty());
16252 o->write_characters(indent_string.c_str(), new_indent);
16253 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
16254
16255 o->write_character('\n');
16256 o->write_characters(indent_string.c_str(), current_indent);
16257 o->write_character(']');
16258 }
16259 else
16260 {
16261 o->write_character('[');
16262
16263 // first n-1 elements
16264 for (auto i = val.m_value.array->cbegin();
16265 i != val.m_value.array->cend() - 1; ++i)
16266 {
16267 dump(*i, false, ensure_ascii, indent_step, current_indent);
16268 o->write_character(',');
16269 }
16270
16271 // last element
16272 JSON_ASSERT(!val.m_value.array->empty());
16273 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
16274
16275 o->write_character(']');
16276 }
16277
16278 return;
16279 }
16280
16281 case value_t::string:
16282 {
16283 o->write_character('\"');
16284 dump_escaped(*val.m_value.string, ensure_ascii);
16285 o->write_character('\"');
16286 return;
16287 }
16288
16289 case value_t::binary:
16290 {
16291 if (pretty_print)
16292 {
16293 o->write_characters("{\n", 2);
16294
16295 // variable to hold indentation for recursive calls
16296 const auto new_indent = current_indent + indent_step;
16297 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16298 {
16299 indent_string.resize(indent_string.size() * 2, ' ');
16300 }
16301
16302 o->write_characters(indent_string.c_str(), new_indent);
16303
16304 o->write_characters("\"bytes\": [", 10);
16305
16306 if (!val.m_value.binary->empty())
16307 {
16308 for (auto i = val.m_value.binary->cbegin();
16309 i != val.m_value.binary->cend() - 1; ++i)
16310 {
16311 dump_integer(*i);
16312 o->write_characters(", ", 2);
16313 }
16314 dump_integer(val.m_value.binary->back());
16315 }
16316
16317 o->write_characters("],\n", 3);
16318 o->write_characters(indent_string.c_str(), new_indent);
16319
16320 o->write_characters("\"subtype\": ", 11);
16321 if (val.m_value.binary->has_subtype())
16322 {
16323 dump_integer(val.m_value.binary->subtype());
16324 }
16325 else
16326 {
16327 o->write_characters("null", 4);
16328 }
16329 o->write_character('\n');
16330 o->write_characters(indent_string.c_str(), current_indent);
16331 o->write_character('}');
16332 }
16333 else
16334 {
16335 o->write_characters("{\"bytes\":[", 10);
16336
16337 if (!val.m_value.binary->empty())
16338 {
16339 for (auto i = val.m_value.binary->cbegin();
16340 i != val.m_value.binary->cend() - 1; ++i)
16341 {
16342 dump_integer(*i);
16343 o->write_character(',');
16344 }
16345 dump_integer(val.m_value.binary->back());
16346 }
16347
16348 o->write_characters("],\"subtype\":", 12);
16349 if (val.m_value.binary->has_subtype())
16350 {
16351 dump_integer(val.m_value.binary->subtype());
16352 o->write_character('}');
16353 }
16354 else
16355 {
16356 o->write_characters("null}", 5);
16357 }
16358 }
16359 return;
16360 }
16361
16362 case value_t::boolean:
16363 {
16364 if (val.m_value.boolean)
16365 {
16366 o->write_characters("true", 4);
16367 }
16368 else
16369 {
16370 o->write_characters("false", 5);
16371 }
16372 return;
16373 }
16374
16376 {
16377 dump_integer(val.m_value.number_integer);
16378 return;
16379 }
16380
16382 {
16383 dump_integer(val.m_value.number_unsigned);
16384 return;
16385 }
16386
16388 {
16389 dump_float(val.m_value.number_float);
16390 return;
16391 }
16392
16393 case value_t::discarded:
16394 {
16395 o->write_characters("<discarded>", 11);
16396 return;
16397 }
16398
16399 case value_t::null:
16400 {
16401 o->write_characters("null", 4);
16402 return;
16403 }
16404
16405 default: // LCOV_EXCL_LINE
16406 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16407 }
16408 }
16409
16425 void dump_escaped(const string_t& s, const bool ensure_ascii)
16426 {
16427 std::uint32_t codepoint{};
16428 std::uint8_t state = UTF8_ACCEPT;
16429 std::size_t bytes = 0; // number of bytes written to string_buffer
16430
16431 // number of bytes written at the point of the last valid byte
16433 std::size_t undumped_chars = 0;
16434
16435 for (std::size_t i = 0; i < s.size(); ++i)
16436 {
16437 const auto byte = static_cast<std::uint8_t>(s[i]);
16438
16439 switch (decode(state, codepoint, byte))
16440 {
16441 case UTF8_ACCEPT: // decode found a new code point
16442 {
16443 switch (codepoint)
16444 {
16445 case 0x08: // backspace
16446 {
16447 string_buffer[bytes++] = '\\';
16448 string_buffer[bytes++] = 'b';
16449 break;
16450 }
16451
16452 case 0x09: // horizontal tab
16453 {
16454 string_buffer[bytes++] = '\\';
16455 string_buffer[bytes++] = 't';
16456 break;
16457 }
16458
16459 case 0x0A: // newline
16460 {
16461 string_buffer[bytes++] = '\\';
16462 string_buffer[bytes++] = 'n';
16463 break;
16464 }
16465
16466 case 0x0C: // formfeed
16467 {
16468 string_buffer[bytes++] = '\\';
16469 string_buffer[bytes++] = 'f';
16470 break;
16471 }
16472
16473 case 0x0D: // carriage return
16474 {
16475 string_buffer[bytes++] = '\\';
16476 string_buffer[bytes++] = 'r';
16477 break;
16478 }
16479
16480 case 0x22: // quotation mark
16481 {
16482 string_buffer[bytes++] = '\\';
16483 string_buffer[bytes++] = '\"';
16484 break;
16485 }
16486
16487 case 0x5C: // reverse solidus
16488 {
16489 string_buffer[bytes++] = '\\';
16490 string_buffer[bytes++] = '\\';
16491 break;
16492 }
16493
16494 default:
16495 {
16496 // escape control characters (0x00..0x1F) or, if
16497 // ensure_ascii parameter is used, non-ASCII characters
16498 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
16499 {
16500 if (codepoint <= 0xFFFF)
16501 {
16502 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16503 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
16504 static_cast<std::uint16_t>(codepoint)));
16505 bytes += 6;
16506 }
16507 else
16508 {
16509 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16510 static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
16511 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
16512 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
16513 bytes += 12;
16514 }
16515 }
16516 else
16517 {
16518 // copy byte to buffer (all previous bytes
16519 // been copied have in default case above)
16520 string_buffer[bytes++] = s[i];
16521 }
16522 break;
16523 }
16524 }
16525
16526 // write buffer and reset index; there must be 13 bytes
16527 // left, as this is the maximal number of bytes to be
16528 // written ("\uxxxx\uxxxx\0") for one code point
16529 if (string_buffer.size() - bytes < 13)
16530 {
16531 o->write_characters(string_buffer.data(), bytes);
16532 bytes = 0;
16533 }
16534
16535 // remember the byte position of this accept
16537 undumped_chars = 0;
16538 break;
16539 }
16540
16541 case UTF8_REJECT: // decode found invalid UTF-8 byte
16542 {
16543 switch (error_handler)
16544 {
16546 {
16547 std::stringstream ss;
16548 ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (byte | 0);
16549 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + ss.str(), BasicJsonType()));
16550 }
16551
16554 {
16555 // in case we saw this character the first time, we
16556 // would like to read it again, because the byte
16557 // may be OK for itself, but just not OK for the
16558 // previous sequence
16559 if (undumped_chars > 0)
16560 {
16561 --i;
16562 }
16563
16564 // reset length buffer to the last accepted index;
16565 // thus removing/ignoring the invalid characters
16567
16569 {
16570 // add a replacement character
16571 if (ensure_ascii)
16572 {
16573 string_buffer[bytes++] = '\\';
16574 string_buffer[bytes++] = 'u';
16575 string_buffer[bytes++] = 'f';
16576 string_buffer[bytes++] = 'f';
16577 string_buffer[bytes++] = 'f';
16578 string_buffer[bytes++] = 'd';
16579 }
16580 else
16581 {
16585 }
16586
16587 // write buffer and reset index; there must be 13 bytes
16588 // left, as this is the maximal number of bytes to be
16589 // written ("\uxxxx\uxxxx\0") for one code point
16590 if (string_buffer.size() - bytes < 13)
16591 {
16592 o->write_characters(string_buffer.data(), bytes);
16593 bytes = 0;
16594 }
16595
16597 }
16598
16599 undumped_chars = 0;
16600
16601 // continue processing the string
16603 break;
16604 }
16605
16606 default: // LCOV_EXCL_LINE
16607 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16608 }
16609 break;
16610 }
16611
16612 default: // decode found yet incomplete multi-byte code point
16613 {
16614 if (!ensure_ascii)
16615 {
16616 // code point will not be escaped - copy byte to buffer
16617 string_buffer[bytes++] = s[i];
16618 }
16620 break;
16621 }
16622 }
16623 }
16624
16625 // we finished processing the string
16627 {
16628 // write buffer
16629 if (bytes > 0)
16630 {
16631 o->write_characters(string_buffer.data(), bytes);
16632 }
16633 }
16634 else
16635 {
16636 // we finish reading, but do not accept: string was incomplete
16637 switch (error_handler)
16638 {
16640 {
16641 std::stringstream ss;
16642 ss << std::uppercase << std::setfill('0') << std::setw(2) << std::hex << (static_cast<std::uint8_t>(s.back()) | 0);
16643 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + ss.str(), BasicJsonType()));
16644 }
16645
16647 {
16648 // write all accepted bytes
16649 o->write_characters(string_buffer.data(), bytes_after_last_accept);
16650 break;
16651 }
16652
16654 {
16655 // write all accepted bytes
16656 o->write_characters(string_buffer.data(), bytes_after_last_accept);
16657 // add a replacement character
16658 if (ensure_ascii)
16659 {
16660 o->write_characters("\\ufffd", 6);
16661 }
16662 else
16663 {
16664 o->write_characters("\xEF\xBF\xBD", 3);
16665 }
16666 break;
16667 }
16668
16669 default: // LCOV_EXCL_LINE
16670 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16671 }
16672 }
16673 }
16674
16675 private:
16684 inline unsigned int count_digits(number_unsigned_t x) noexcept
16685 {
16686 unsigned int n_digits = 1;
16687 for (;;)
16688 {
16689 if (x < 10)
16690 {
16691 return n_digits;
16692 }
16693 if (x < 100)
16694 {
16695 return n_digits + 1;
16696 }
16697 if (x < 1000)
16698 {
16699 return n_digits + 2;
16700 }
16701 if (x < 10000)
16702 {
16703 return n_digits + 3;
16704 }
16705 x = x / 10000u;
16706 n_digits += 4;
16707 }
16708 }
16709
16710 // templates to avoid warnings about useless casts
16711 template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
16712 bool is_negative_number(NumberType x)
16713 {
16714 return x < 0;
16715 }
16716
16717 template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
16718 bool is_negative_number(NumberType /*unused*/)
16719 {
16720 return false;
16721 }
16722
16732 template < typename NumberType, detail::enable_if_t <
16733 std::is_integral<NumberType>::value ||
16734 std::is_same<NumberType, number_unsigned_t>::value ||
16735 std::is_same<NumberType, number_integer_t>::value ||
16736 std::is_same<NumberType, binary_char_t>::value,
16737 int > = 0 >
16738 void dump_integer(NumberType x)
16739 {
16740 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
16741 {
16742 {
16743 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
16744 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
16745 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
16746 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
16747 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
16748 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
16749 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
16750 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
16751 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
16752 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
16753 }
16754 };
16755
16756 // special case for "0"
16757 if (x == 0)
16758 {
16759 o->write_character('0');
16760 return;
16761 }
16762
16763 // use a pointer to fill the buffer
16764 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16765
16766 number_unsigned_t abs_value;
16767
16768 unsigned int n_chars{};
16769
16770 if (is_negative_number(x))
16771 {
16772 *buffer_ptr = '-';
16773 abs_value = remove_sign(static_cast<number_integer_t>(x));
16774
16775 // account one more byte for the minus sign
16776 n_chars = 1 + count_digits(abs_value);
16777 }
16778 else
16779 {
16780 abs_value = static_cast<number_unsigned_t>(x);
16781 n_chars = count_digits(abs_value);
16782 }
16783
16784 // spare 1 byte for '\0'
16785 JSON_ASSERT(n_chars < number_buffer.size() - 1);
16786
16787 // jump to the end to generate the string from backward,
16788 // so we later avoid reversing the result
16789 buffer_ptr += n_chars;
16790
16791 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
16792 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
16793 while (abs_value >= 100)
16794 {
16795 const auto digits_index = static_cast<unsigned>((abs_value % 100));
16796 abs_value /= 100;
16797 *(--buffer_ptr) = digits_to_99[digits_index][1];
16798 *(--buffer_ptr) = digits_to_99[digits_index][0];
16799 }
16800
16801 if (abs_value >= 10)
16802 {
16803 const auto digits_index = static_cast<unsigned>(abs_value);
16804 *(--buffer_ptr) = digits_to_99[digits_index][1];
16805 *(--buffer_ptr) = digits_to_99[digits_index][0];
16806 }
16807 else
16808 {
16809 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
16810 }
16811
16812 o->write_characters(number_buffer.data(), n_chars);
16813 }
16814
16823 void dump_float(number_float_t x)
16824 {
16825 // NaN / inf
16826 if (!std::isfinite(x))
16827 {
16828 o->write_characters("null", 4);
16829 return;
16830 }
16831
16832 // If number_float_t is an IEEE-754 single or double precision number,
16833 // use the Grisu2 algorithm to produce short numbers which are
16834 // guaranteed to round-trip, using strtof and strtod, resp.
16835 //
16836 // NB: The test below works if <long double> == <double>.
16837 static constexpr bool is_ieee_single_or_double
16838 = (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) ||
16839 (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);
16840
16841 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
16842 }
16843
16844 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
16845 {
16846 auto* begin = number_buffer.data();
16847 auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
16848
16849 o->write_characters(begin, static_cast<size_t>(end - begin));
16850 }
16851
16852 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
16853 {
16854 // get number of digits for a float -> text -> float round-trip
16855 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
16856
16857 // the actual conversion
16858 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16859 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
16860
16861 // negative value indicates an error
16862 JSON_ASSERT(len > 0);
16863 // check if buffer was large enough
16864 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
16865
16866 // erase thousands separator
16867 if (thousands_sep != '\0')
16868 {
16869 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
16870 const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
16871 std::fill(end, number_buffer.end(), '\0');
16872 JSON_ASSERT((end - number_buffer.begin()) <= len);
16873 len = (end - number_buffer.begin());
16874 }
16875
16876 // convert decimal point to '.'
16877 if (decimal_point != '\0' && decimal_point != '.')
16878 {
16879 // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
16880 const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
16881 if (dec_pos != number_buffer.end())
16882 {
16883 *dec_pos = '.';
16884 }
16885 }
16886
16887 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
16888
16889 // determine if we need to append ".0"
16890 const bool value_is_int_like =
16891 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
16892 [](char c)
16893 {
16894 return c == '.' || c == 'e';
16895 });
16896
16897 if (value_is_int_like)
16898 {
16899 o->write_characters(".0", 2);
16900 }
16901 }
16902
16924 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
16925 {
16926 static const std::array<std::uint8_t, 400> utf8d =
16927 {
16928 {
16929 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
16930 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
16931 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
16932 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
16933 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
16934 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
16935 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
16936 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
16937 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
16938 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
16939 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
16940 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
16941 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
16942 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
16943 }
16944 };
16945
16946 JSON_ASSERT(byte < utf8d.size());
16947 const std::uint8_t type = utf8d[byte];
16948
16949 codep = (state != UTF8_ACCEPT)
16950 ? (byte & 0x3fu) | (codep << 6u)
16951 : (0xFFu >> type) & (byte);
16952
16953 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
16954 JSON_ASSERT(index < 400);
16955 state = utf8d[index];
16956 return state;
16957 }
16958
16959 /*
16960 * Overload to make the compiler happy while it is instantiating
16961 * dump_integer for number_unsigned_t.
16962 * Must never be called.
16963 */
16965 {
16966 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16967 return x; // LCOV_EXCL_LINE
16968 }
16969
16970 /*
16971 * Helper function for dump_integer
16972 *
16973 * This function takes a negative signed integer and returns its absolute
16974 * value as unsigned integer. The plus/minus shuffling is necessary as we can
16975 * not directly remove the sign of an arbitrary signed integer as the
16976 * absolute values of INT_MIN and INT_MAX are usually not the same. See
16977 * #1708 for details.
16978 */
16979 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
16980 {
16981 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
16982 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
16983 }
16984
16985 private:
16987 output_adapter_t<char> o = nullptr;
16988
16990 std::array<char, 64> number_buffer{{}};
16991
16993 const std::lconv* loc = nullptr;
16995 const char thousands_sep = '\0';
16997 const char decimal_point = '\0';
16998
17000 std::array<char, 512> string_buffer{{}};
17001
17003 const char indent_char;
17006
17009};
17010} // namespace detail
17011} // namespace nlohmann
17012
17013// #include <nlohmann/detail/value_t.hpp>
17014
17015// #include <nlohmann/json_fwd.hpp>
17016
17017// #include <nlohmann/ordered_map.hpp>
17018
17019
17020#include <functional> // less
17021#include <initializer_list> // initializer_list
17022#include <iterator> // input_iterator_tag, iterator_traits
17023#include <memory> // allocator
17024#include <stdexcept> // for out_of_range
17025#include <type_traits> // enable_if, is_convertible
17026#include <utility> // pair
17027#include <vector> // vector
17028
17029// #include <nlohmann/detail/macro_scope.hpp>
17030
17031
17032namespace nlohmann
17033{
17034
17037template <class Key, class T, class IgnoredLess = std::less<Key>,
17038 class Allocator = std::allocator<std::pair<const Key, T>>>
17039 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
17040{
17041 using key_type = Key;
17042 using mapped_type = T;
17043 using Container = std::vector<std::pair<const Key, T>, Allocator>;
17044 using iterator = typename Container::iterator;
17045 using const_iterator = typename Container::const_iterator;
17046 using size_type = typename Container::size_type;
17047 using value_type = typename Container::value_type;
17048
17049 // Explicit constructors instead of `using Container::Container`
17050 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
17051 ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
17052 template <class It>
17053 ordered_map(It first, It last, const Allocator& alloc = Allocator())
17054 : Container{first, last, alloc} {}
17055 ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
17056 : Container{init, alloc} {}
17057
17058 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
17059 {
17060 for (auto it = this->begin(); it != this->end(); ++it)
17061 {
17062 if (it->first == key)
17063 {
17064 return {it, false};
17065 }
17066 }
17067 Container::emplace_back(key, t);
17068 return {--this->end(), true};
17069 }
17070
17071 T& operator[](const Key& key)
17072 {
17073 return emplace(key, T{}).first->second;
17074 }
17075
17076 const T& operator[](const Key& key) const
17077 {
17078 return at(key);
17079 }
17080
17081 T& at(const Key& key)
17082 {
17083 for (auto it = this->begin(); it != this->end(); ++it)
17084 {
17085 if (it->first == key)
17086 {
17087 return it->second;
17088 }
17089 }
17090
17091 JSON_THROW(std::out_of_range("key not found"));
17092 }
17093
17094 const T& at(const Key& key) const
17095 {
17096 for (auto it = this->begin(); it != this->end(); ++it)
17097 {
17098 if (it->first == key)
17099 {
17100 return it->second;
17101 }
17102 }
17103
17104 JSON_THROW(std::out_of_range("key not found"));
17105 }
17106
17107 size_type erase(const Key& key)
17108 {
17109 for (auto it = this->begin(); it != this->end(); ++it)
17110 {
17111 if (it->first == key)
17112 {
17113 // Since we cannot move const Keys, re-construct them in place
17114 for (auto next = it; ++next != this->end(); ++it)
17115 {
17116 it->~value_type(); // Destroy but keep allocation
17117 new (&*it) value_type{std::move(*next)};
17118 }
17119 Container::pop_back();
17120 return 1;
17121 }
17122 }
17123 return 0;
17124 }
17125
17127 {
17128 return erase(pos, std::next(pos));
17129 }
17130
17132 {
17133 const auto elements_affected = std::distance(first, last);
17134 const auto offset = std::distance(Container::begin(), first);
17135
17136 // This is the start situation. We need to delete elements_affected
17137 // elements (3 in this example: e, f, g), and need to return an
17138 // iterator past the last deleted element (h in this example).
17139 // Note that offset is the distance from the start of the vector
17140 // to first. We will need this later.
17141
17142 // [ a, b, c, d, e, f, g, h, i, j ]
17143 // ^ ^
17144 // first last
17145
17146 // Since we cannot move const Keys, we re-construct them in place.
17147 // We start at first and re-construct (viz. copy) the elements from
17148 // the back of the vector. Example for first iteration:
17149
17150 // ,--------.
17151 // v | destroy e and re-construct with h
17152 // [ a, b, c, d, e, f, g, h, i, j ]
17153 // ^ ^
17154 // it it + elements_affected
17155
17156 for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
17157 {
17158 it->~value_type(); // destroy but keep allocation
17159 new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
17160 }
17161
17162 // [ a, b, c, d, h, i, j, h, i, j ]
17163 // ^ ^
17164 // first last
17165
17166 // remove the unneeded elements at the end of the vector
17167 Container::resize(this->size() - static_cast<size_type>(elements_affected));
17168
17169 // [ a, b, c, d, h, i, j ]
17170 // ^ ^
17171 // first last
17172
17173 // first is now pointing past the last deleted element, but we cannot
17174 // use this iterator, because it may have been invalidated by the
17175 // resize call. Instead, we can return begin() + offset.
17176 return Container::begin() + offset;
17177 }
17178
17179 size_type count(const Key& key) const
17180 {
17181 for (auto it = this->begin(); it != this->end(); ++it)
17182 {
17183 if (it->first == key)
17184 {
17185 return 1;
17186 }
17187 }
17188 return 0;
17189 }
17190
17191 iterator find(const Key& key)
17192 {
17193 for (auto it = this->begin(); it != this->end(); ++it)
17194 {
17195 if (it->first == key)
17196 {
17197 return it;
17198 }
17199 }
17200 return Container::end();
17201 }
17202
17203 const_iterator find(const Key& key) const
17204 {
17205 for (auto it = this->begin(); it != this->end(); ++it)
17206 {
17207 if (it->first == key)
17208 {
17209 return it;
17210 }
17211 }
17212 return Container::end();
17213 }
17214
17215 std::pair<iterator, bool> insert( value_type&& value )
17216 {
17217 return emplace(value.first, std::move(value.second));
17218 }
17219
17220 std::pair<iterator, bool> insert( const value_type& value )
17221 {
17222 for (auto it = this->begin(); it != this->end(); ++it)
17223 {
17224 if (it->first == value.first)
17225 {
17226 return {it, false};
17227 }
17228 }
17229 Container::push_back(value);
17230 return {--this->end(), true};
17231 }
17232
17233 template<typename InputIt>
17234 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
17235 std::input_iterator_tag>::value>::type;
17236
17237 template<typename InputIt, typename = require_input_iter<InputIt>>
17238 void insert(InputIt first, InputIt last)
17239 {
17240 for (auto it = first; it != last; ++it)
17241 {
17242 insert(*it);
17243 }
17244 }
17245};
17246
17247} // namespace nlohmann
17248
17249
17250#if defined(JSON_HAS_CPP_17)
17251 #include <string_view>
17252#endif
17253
17259namespace nlohmann
17260{
17261
17281class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
17282{
17283 private:
17284 template<detail::value_t> friend struct detail::external_constructor;
17285 friend ::nlohmann::json_pointer<basic_json>;
17286
17287 template<typename BasicJsonType, typename InputType>
17288 friend class ::nlohmann::detail::parser;
17289 friend ::nlohmann::detail::serializer<basic_json>;
17290 template<typename BasicJsonType>
17291 friend class ::nlohmann::detail::iter_impl;
17292 template<typename BasicJsonType, typename CharType>
17293 friend class ::nlohmann::detail::binary_writer;
17294 template<typename BasicJsonType, typename InputType, typename SAX>
17295 friend class ::nlohmann::detail::binary_reader;
17296 template<typename BasicJsonType>
17297 friend class ::nlohmann::detail::json_sax_dom_parser;
17298 template<typename BasicJsonType>
17299 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
17300 friend class ::nlohmann::detail::exception;
17301
17304
17306 // convenience aliases for types residing in namespace detail;
17308
17309 template<typename InputAdapterType>
17310 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
17311 InputAdapterType adapter,
17313 const bool allow_exceptions = true,
17314 const bool ignore_comments = false
17315 )
17316 {
17317 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
17318 std::move(cb), allow_exceptions, ignore_comments);
17319 }
17320
17321 private:
17323 template<typename BasicJsonType>
17325 template<typename BasicJsonType>
17327 template<typename Iterator>
17330
17331 template<typename CharType>
17333
17334 template<typename InputType>
17337
17340
17341 public:
17345 template<typename T, typename SFINAE>
17346 using json_serializer = JSONSerializer<T, SFINAE>;
17352 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
17353
17357
17359 // exceptions //
17361
17365
17372
17374
17375
17377 // container types //
17379
17384
17387
17392
17394 using difference_type = std::ptrdiff_t;
17396 using size_type = std::size_t;
17397
17399 using allocator_type = AllocatorType<basic_json>;
17400
17402 using pointer = typename std::allocator_traits<allocator_type>::pointer;
17404 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
17405
17414
17416
17417
17421 {
17422 return allocator_type();
17423 }
17424
17429 {
17430 basic_json result;
17431
17432 result["copyright"] = "(C) 2013-2022 Niels Lohmann";
17433 result["name"] = "JSON for Modern C++";
17434 result["url"] = "https://github.com/nlohmann/json";
17435 result["version"]["string"] =
17436 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
17437 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
17438 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
17439 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
17440 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
17441 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
17442
17443#ifdef _WIN32
17444 result["platform"] = "win32";
17445#elif defined __linux__
17446 result["platform"] = "linux";
17447#elif defined __APPLE__
17448 result["platform"] = "apple";
17449#elif defined __unix__
17450 result["platform"] = "unix";
17451#else
17452 result["platform"] = "unknown";
17453#endif
17454
17455#if defined(__ICC) || defined(__INTEL_COMPILER)
17456 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
17457#elif defined(__clang__)
17458 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
17459#elif defined(__GNUC__) || defined(__GNUG__)
17460 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
17461#elif defined(__HP_cc) || defined(__HP_aCC)
17462 result["compiler"] = "hp"
17463#elif defined(__IBMCPP__)
17464 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
17465#elif defined(_MSC_VER)
17466 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
17467#elif defined(__PGI)
17468 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
17469#elif defined(__SUNPRO_CC)
17470 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
17471#else
17472 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
17473#endif
17474
17475#ifdef __cplusplus
17476 result["compiler"]["c++"] = std::to_string(__cplusplus);
17477#else
17478 result["compiler"]["c++"] = "unknown";
17479#endif
17480 return result;
17481 }
17482
17483
17485 // JSON value data types //
17487
17492
17495#if defined(JSON_HAS_CPP_14)
17496 // Use transparent comparator if possible, combined with perfect forwarding
17497 // on find() and count() calls prevents unnecessary string construction.
17498 using object_comparator_t = std::less<>;
17499#else
17500 using object_comparator_t = std::less<StringType>;
17501#endif
17502
17505 using object_t = ObjectType<StringType,
17506 basic_json,
17508 AllocatorType<std::pair<const StringType,
17509 basic_json>>>;
17510
17513 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17514
17517 using string_t = StringType;
17518
17521 using boolean_t = BooleanType;
17522
17525 using number_integer_t = NumberIntegerType;
17526
17529 using number_unsigned_t = NumberUnsignedType;
17530
17533 using number_float_t = NumberFloatType;
17534
17538
17540
17541 private:
17542
17544 template<typename T, typename... Args>
17546 static T* create(Args&& ... args)
17547 {
17548 AllocatorType<T> alloc;
17549 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
17550
17551 auto deleter = [&](T * obj)
17552 {
17553 AllocatorTraits::deallocate(alloc, obj, 1);
17554 };
17555 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
17556 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
17557 JSON_ASSERT(obj != nullptr);
17558 return obj.release();
17559 }
17560
17562 // JSON value storage //
17564
17591 union json_value
17592 {
17609
17611 json_value() = default;
17613 json_value(boolean_t v) noexcept : boolean(v) {}
17622 {
17623 switch (t)
17624 {
17625 case value_t::object:
17626 {
17627 object = create<object_t>();
17628 break;
17629 }
17630
17631 case value_t::array:
17632 {
17633 array = create<array_t>();
17634 break;
17635 }
17636
17637 case value_t::string:
17638 {
17639 string = create<string_t>("");
17640 break;
17641 }
17642
17643 case value_t::binary:
17644 {
17645 binary = create<binary_t>();
17646 break;
17647 }
17648
17649 case value_t::boolean:
17650 {
17651 boolean = static_cast<boolean_t>(false);
17652 break;
17653 }
17654
17655 case value_t::number_integer:
17656 {
17657 number_integer = static_cast<number_integer_t>(0);
17658 break;
17659 }
17660
17661 case value_t::number_unsigned:
17662 {
17663 number_unsigned = static_cast<number_unsigned_t>(0);
17664 break;
17665 }
17666
17667 case value_t::number_float:
17668 {
17669 number_float = static_cast<number_float_t>(0.0);
17670 break;
17671 }
17672
17673 case value_t::null:
17674 {
17675 object = nullptr; // silence warning, see #821
17676 break;
17677 }
17678
17679 case value_t::discarded:
17680 default:
17681 {
17682 object = nullptr; // silence warning, see #821
17683 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
17684 {
17685 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.5", basic_json())); // LCOV_EXCL_LINE
17686 }
17687 break;
17688 }
17689 }
17690 }
17691
17694
17697
17700
17703
17706
17709
17712
17715
17718
17721
17723 {
17724 if (t == value_t::array || t == value_t::object)
17725 {
17726 // flatten the current json_value to a heap-allocated stack
17727 std::vector<basic_json> stack;
17728
17729 // move the top-level items to stack
17730 if (t == value_t::array)
17731 {
17732 stack.reserve(array->size());
17733 std::move(array->begin(), array->end(), std::back_inserter(stack));
17734 }
17735 else
17736 {
17737 stack.reserve(object->size());
17738 for (auto&& it : *object)
17739 {
17740 stack.push_back(std::move(it.second));
17741 }
17742 }
17743
17744 while (!stack.empty())
17745 {
17746 // move the last item to local variable to be processed
17747 basic_json current_item(std::move(stack.back()));
17748 stack.pop_back();
17749
17750 // if current_item is array/object, move
17751 // its children to the stack to be processed later
17752 if (current_item.is_array())
17753 {
17754 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
17755
17756 current_item.m_value.array->clear();
17757 }
17758 else if (current_item.is_object())
17759 {
17760 for (auto&& it : *current_item.m_value.object)
17761 {
17762 stack.push_back(std::move(it.second));
17763 }
17764
17765 current_item.m_value.object->clear();
17766 }
17767
17768 // it's now safe that current_item get destructed
17769 // since it doesn't have any children
17770 }
17771 }
17772
17773 switch (t)
17774 {
17775 case value_t::object:
17776 {
17777 AllocatorType<object_t> alloc;
17778 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
17779 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
17780 break;
17781 }
17782
17783 case value_t::array:
17784 {
17785 AllocatorType<array_t> alloc;
17786 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
17787 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
17788 break;
17789 }
17790
17791 case value_t::string:
17792 {
17793 AllocatorType<string_t> alloc;
17794 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
17795 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
17796 break;
17797 }
17798
17799 case value_t::binary:
17800 {
17801 AllocatorType<binary_t> alloc;
17802 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
17803 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
17804 break;
17805 }
17806
17807 case value_t::null:
17808 case value_t::boolean:
17809 case value_t::number_integer:
17810 case value_t::number_unsigned:
17811 case value_t::number_float:
17812 case value_t::discarded:
17813 default:
17814 {
17815 break;
17816 }
17817 }
17818 }
17819 };
17820
17821 private:
17840 void assert_invariant(bool check_parents = true) const noexcept
17841 {
17842 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
17843 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
17844 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
17845 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
17846
17847#if JSON_DIAGNOSTICS
17848 JSON_TRY
17849 {
17850 // cppcheck-suppress assertWithSideEffect
17851 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
17852 {
17853 return j.m_parent == this;
17854 }));
17855 }
17856 JSON_CATCH(...) {} // LCOV_EXCL_LINE
17857#endif
17858 static_cast<void>(check_parents);
17859 }
17860
17862 {
17863#if JSON_DIAGNOSTICS
17864 switch (m_type)
17865 {
17866 case value_t::array:
17867 {
17868 for (auto& element : *m_value.array)
17869 {
17870 element.m_parent = this;
17871 }
17872 break;
17873 }
17874
17875 case value_t::object:
17876 {
17877 for (auto& element : *m_value.object)
17878 {
17879 element.second.m_parent = this;
17880 }
17881 break;
17882 }
17883
17884 case value_t::null:
17885 case value_t::string:
17886 case value_t::boolean:
17887 case value_t::number_integer:
17888 case value_t::number_unsigned:
17889 case value_t::number_float:
17890 case value_t::binary:
17891 case value_t::discarded:
17892 default:
17893 break;
17894 }
17895#endif
17896 }
17897
17899 {
17900#if JSON_DIAGNOSTICS
17901 for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
17902 {
17903 (it + i)->m_parent = this;
17904 }
17905#else
17906 static_cast<void>(count_set_parents);
17907#endif
17908 return it;
17909 }
17910
17911 reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
17912 {
17913#if JSON_DIAGNOSTICS
17914 if (old_capacity != static_cast<std::size_t>(-1))
17915 {
17916 // see https://github.com/nlohmann/json/issues/2838
17917 JSON_ASSERT(type() == value_t::array);
17918 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
17919 {
17920 // capacity has changed: update all parents
17921 set_parents();
17922 return j;
17923 }
17924 }
17925
17926 // ordered_json uses a vector internally, so pointers could have
17927 // been invalidated; see https://github.com/nlohmann/json/issues/2962
17928#ifdef JSON_HEDLEY_MSVC_VERSION
17929#pragma warning(push )
17930#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
17931#endif
17933 {
17934 set_parents();
17935 return j;
17936 }
17937#ifdef JSON_HEDLEY_MSVC_VERSION
17938#pragma warning( pop )
17939#endif
17940
17941 j.m_parent = this;
17942#else
17943 static_cast<void>(j);
17944 static_cast<void>(old_capacity);
17945#endif
17946 return j;
17947 }
17948
17949 public:
17951 // JSON parser callback //
17953
17957
17961
17963 // constructors //
17965
17970
17974 : m_type(v), m_value(v)
17975 {
17977 }
17978
17981 basic_json(std::nullptr_t = nullptr) noexcept
17982 : basic_json(value_t::null)
17983 {
17985 }
17986
17989 template < typename CompatibleType,
17993 basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
17994 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
17995 std::forward<CompatibleType>(val))))
17996 {
17997 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
17998 set_parents();
18000 }
18001
18004 template < typename BasicJsonType,
18006 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
18007 basic_json(const BasicJsonType& val)
18008 {
18009 using other_boolean_t = typename BasicJsonType::boolean_t;
18010 using other_number_float_t = typename BasicJsonType::number_float_t;
18011 using other_number_integer_t = typename BasicJsonType::number_integer_t;
18012 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
18013 using other_string_t = typename BasicJsonType::string_t;
18014 using other_object_t = typename BasicJsonType::object_t;
18015 using other_array_t = typename BasicJsonType::array_t;
18016 using other_binary_t = typename BasicJsonType::binary_t;
18017
18018 switch (val.type())
18019 {
18020 case value_t::boolean:
18021 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
18022 break;
18023 case value_t::number_float:
18024 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
18025 break;
18026 case value_t::number_integer:
18027 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
18028 break;
18029 case value_t::number_unsigned:
18030 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
18031 break;
18032 case value_t::string:
18033 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
18034 break;
18035 case value_t::object:
18036 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
18037 break;
18038 case value_t::array:
18039 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
18040 break;
18041 case value_t::binary:
18042 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
18043 break;
18044 case value_t::null:
18045 *this = nullptr;
18046 break;
18047 case value_t::discarded:
18048 m_type = value_t::discarded;
18049 break;
18050 default: // LCOV_EXCL_LINE
18051 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18052 }
18053 set_parents();
18055 }
18056
18060 bool type_deduction = true,
18061 value_t manual_type = value_t::array)
18062 {
18063 // check if each element is an array with two elements whose first
18064 // element is a string
18065 bool is_an_object = std::all_of(init.begin(), init.end(),
18066 [](const detail::json_ref<basic_json>& element_ref)
18067 {
18068 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
18069 });
18070
18071 // adjust type if type deduction is not wanted
18072 if (!type_deduction)
18073 {
18074 // if array is wanted, do not create an object though possible
18075 if (manual_type == value_t::array)
18076 {
18077 is_an_object = false;
18078 }
18079
18080 // if object is wanted but impossible, throw an exception
18081 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
18082 {
18083 JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
18084 }
18085 }
18086
18087 if (is_an_object)
18088 {
18089 // the initializer list is a list of pairs -> create object
18090 m_type = value_t::object;
18091 m_value = value_t::object;
18092
18093 for (auto& element_ref : init)
18094 {
18095 auto element = element_ref.moved_or_copied();
18097 std::move(*((*element.m_value.array)[0].m_value.string)),
18098 std::move((*element.m_value.array)[1]));
18099 }
18100 }
18101 else
18102 {
18103 // the initializer list describes an array -> create array
18104 m_type = value_t::array;
18105 m_value.array = create<array_t>(init.begin(), init.end());
18106 }
18107
18108 set_parents();
18110 }
18111
18115 static basic_json binary(const typename binary_t::container_type& init)
18116 {
18117 auto res = basic_json();
18118 res.m_type = value_t::binary;
18119 res.m_value = init;
18120 return res;
18121 }
18122
18126 static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
18127 {
18128 auto res = basic_json();
18129 res.m_type = value_t::binary;
18130 res.m_value = binary_t(init, subtype);
18131 return res;
18132 }
18133
18138 {
18139 auto res = basic_json();
18140 res.m_type = value_t::binary;
18141 res.m_value = std::move(init);
18142 return res;
18143 }
18144
18148 static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
18149 {
18150 auto res = basic_json();
18151 res.m_type = value_t::binary;
18152 res.m_value = binary_t(std::move(init), subtype);
18153 return res;
18154 }
18155
18160 {
18161 return basic_json(init, false, value_t::array);
18162 }
18163
18168 {
18169 return basic_json(init, false, value_t::object);
18170 }
18171
18175 : m_type(value_t::array)
18176 {
18177 m_value.array = create<array_t>(cnt, val);
18178 set_parents();
18180 }
18181
18184 template < class InputIT, typename std::enable_if <
18185 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
18186 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
18187 basic_json(InputIT first, InputIT last)
18188 {
18189 JSON_ASSERT(first.m_object != nullptr);
18190 JSON_ASSERT(last.m_object != nullptr);
18191
18192 // make sure iterator fits the current value
18193 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
18194 {
18195 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
18196 }
18197
18198 // copy type from first iterator
18199 m_type = first.m_object->m_type;
18200
18201 // check if iterator range is complete for primitive values
18202 switch (m_type)
18203 {
18204 case value_t::boolean:
18205 case value_t::number_float:
18206 case value_t::number_integer:
18207 case value_t::number_unsigned:
18208 case value_t::string:
18209 {
18210 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
18211 || !last.m_it.primitive_iterator.is_end()))
18212 {
18213 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
18214 }
18215 break;
18216 }
18217
18218 case value_t::null:
18219 case value_t::object:
18220 case value_t::array:
18221 case value_t::binary:
18222 case value_t::discarded:
18223 default:
18224 break;
18225 }
18226
18227 switch (m_type)
18228 {
18229 case value_t::number_integer:
18230 {
18231 m_value.number_integer = first.m_object->m_value.number_integer;
18232 break;
18233 }
18234
18235 case value_t::number_unsigned:
18236 {
18237 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
18238 break;
18239 }
18240
18241 case value_t::number_float:
18242 {
18243 m_value.number_float = first.m_object->m_value.number_float;
18244 break;
18245 }
18246
18247 case value_t::boolean:
18248 {
18249 m_value.boolean = first.m_object->m_value.boolean;
18250 break;
18251 }
18252
18253 case value_t::string:
18254 {
18255 m_value = *first.m_object->m_value.string;
18256 break;
18257 }
18258
18259 case value_t::object:
18260 {
18261 m_value.object = create<object_t>(first.m_it.object_iterator,
18262 last.m_it.object_iterator);
18263 break;
18264 }
18265
18266 case value_t::array:
18267 {
18268 m_value.array = create<array_t>(first.m_it.array_iterator,
18269 last.m_it.array_iterator);
18270 break;
18271 }
18272
18273 case value_t::binary:
18274 {
18275 m_value = *first.m_object->m_value.binary;
18276 break;
18277 }
18278
18279 case value_t::null:
18280 case value_t::discarded:
18281 default:
18282 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
18283 }
18284
18285 set_parents();
18287 }
18288
18289
18291 // other constructors and destructor //
18293
18294 template<typename JsonRef,
18296 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
18297 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
18298
18302 : m_type(other.m_type)
18303 {
18304 // check of passed value is valid
18305 other.assert_invariant();
18306
18307 switch (m_type)
18308 {
18309 case value_t::object:
18310 {
18311 m_value = *other.m_value.object;
18312 break;
18313 }
18314
18315 case value_t::array:
18316 {
18317 m_value = *other.m_value.array;
18318 break;
18319 }
18320
18321 case value_t::string:
18322 {
18323 m_value = *other.m_value.string;
18324 break;
18325 }
18326
18327 case value_t::boolean:
18328 {
18329 m_value = other.m_value.boolean;
18330 break;
18331 }
18332
18333 case value_t::number_integer:
18334 {
18335 m_value = other.m_value.number_integer;
18336 break;
18337 }
18338
18339 case value_t::number_unsigned:
18340 {
18341 m_value = other.m_value.number_unsigned;
18342 break;
18343 }
18344
18345 case value_t::number_float:
18346 {
18347 m_value = other.m_value.number_float;
18348 break;
18349 }
18350
18351 case value_t::binary:
18352 {
18353 m_value = *other.m_value.binary;
18354 break;
18355 }
18356
18357 case value_t::null:
18358 case value_t::discarded:
18359 default:
18360 break;
18361 }
18362
18363 set_parents();
18365 }
18366
18369 basic_json(basic_json&& other) noexcept
18370 : m_type(std::move(other.m_type)),
18371 m_value(std::move(other.m_value))
18372 {
18373 // check that passed value is valid
18374 other.assert_invariant(false);
18375
18376 // invalidate payload
18377 other.m_type = value_t::null;
18378 other.m_value = {};
18379
18380 set_parents();
18382 }
18383
18387 std::is_nothrow_move_constructible<value_t>::value&&
18388 std::is_nothrow_move_assignable<value_t>::value&&
18389 std::is_nothrow_move_constructible<json_value>::value&&
18390 std::is_nothrow_move_assignable<json_value>::value
18391 )
18392 {
18393 // check that passed value is valid
18394 other.assert_invariant();
18395
18396 using std::swap;
18397 swap(m_type, other.m_type);
18398 swap(m_value, other.m_value);
18399
18400 set_parents();
18402 return *this;
18403 }
18404
18407 ~basic_json() noexcept
18408 {
18409 assert_invariant(false);
18410 m_value.destroy(m_type);
18411 }
18412
18414
18415 public:
18417 // object inspection //
18419
18423
18426 string_t dump(const int indent = -1,
18427 const char indent_char = ' ',
18428 const bool ensure_ascii = false,
18429 const error_handler_t error_handler = error_handler_t::strict) const
18430 {
18431 string_t result;
18432 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
18433
18434 if (indent >= 0)
18435 {
18436 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
18437 }
18438 else
18439 {
18440 s.dump(*this, false, ensure_ascii, 0);
18441 }
18442
18443 return result;
18444 }
18445
18448 constexpr value_t type() const noexcept
18449 {
18450 return m_type;
18451 }
18452
18455 constexpr bool is_primitive() const noexcept
18456 {
18457 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
18458 }
18459
18462 constexpr bool is_structured() const noexcept
18463 {
18464 return is_array() || is_object();
18465 }
18466
18469 constexpr bool is_null() const noexcept
18470 {
18471 return m_type == value_t::null;
18472 }
18473
18476 constexpr bool is_boolean() const noexcept
18477 {
18478 return m_type == value_t::boolean;
18479 }
18480
18483 constexpr bool is_number() const noexcept
18484 {
18485 return is_number_integer() || is_number_float();
18486 }
18487
18490 constexpr bool is_number_integer() const noexcept
18491 {
18492 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
18493 }
18494
18497 constexpr bool is_number_unsigned() const noexcept
18498 {
18499 return m_type == value_t::number_unsigned;
18500 }
18501
18504 constexpr bool is_number_float() const noexcept
18505 {
18506 return m_type == value_t::number_float;
18507 }
18508
18511 constexpr bool is_object() const noexcept
18512 {
18513 return m_type == value_t::object;
18514 }
18515
18518 constexpr bool is_array() const noexcept
18519 {
18520 return m_type == value_t::array;
18521 }
18522
18525 constexpr bool is_string() const noexcept
18526 {
18527 return m_type == value_t::string;
18528 }
18529
18532 constexpr bool is_binary() const noexcept
18533 {
18534 return m_type == value_t::binary;
18535 }
18536
18539 constexpr bool is_discarded() const noexcept
18540 {
18541 return m_type == value_t::discarded;
18542 }
18543
18546 constexpr operator value_t() const noexcept
18547 {
18548 return m_type;
18549 }
18550
18552
18553 private:
18555 // value access //
18557
18559 boolean_t get_impl(boolean_t* /*unused*/) const
18560 {
18562 {
18563 return m_value.boolean;
18564 }
18565
18566 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
18567 }
18568
18570 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
18571 {
18572 return is_object() ? m_value.object : nullptr;
18573 }
18574
18576 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
18577 {
18578 return is_object() ? m_value.object : nullptr;
18579 }
18580
18582 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
18583 {
18584 return is_array() ? m_value.array : nullptr;
18585 }
18586
18588 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
18589 {
18590 return is_array() ? m_value.array : nullptr;
18591 }
18592
18594 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
18595 {
18596 return is_string() ? m_value.string : nullptr;
18597 }
18598
18600 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
18601 {
18602 return is_string() ? m_value.string : nullptr;
18603 }
18604
18606 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
18607 {
18608 return is_boolean() ? &m_value.boolean : nullptr;
18609 }
18610
18612 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
18613 {
18614 return is_boolean() ? &m_value.boolean : nullptr;
18615 }
18616
18619 {
18620 return is_number_integer() ? &m_value.number_integer : nullptr;
18621 }
18622
18624 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
18625 {
18626 return is_number_integer() ? &m_value.number_integer : nullptr;
18627 }
18628
18631 {
18632 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
18633 }
18634
18636 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
18637 {
18638 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
18639 }
18640
18643 {
18644 return is_number_float() ? &m_value.number_float : nullptr;
18645 }
18646
18648 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
18649 {
18650 return is_number_float() ? &m_value.number_float : nullptr;
18651 }
18652
18654 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
18655 {
18656 return is_binary() ? m_value.binary : nullptr;
18657 }
18658
18660 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
18661 {
18662 return is_binary() ? m_value.binary : nullptr;
18663 }
18664
18676 template<typename ReferenceType, typename ThisType>
18677 static ReferenceType get_ref_impl(ThisType& obj)
18678 {
18679 // delegate the call to get_ptr<>()
18680 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
18681
18682 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
18683 {
18684 return *ptr;
18685 }
18686
18687 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
18688 }
18689
18690 public:
18694
18697 template<typename PointerType, typename std::enable_if<
18698 std::is_pointer<PointerType>::value, int>::type = 0>
18699 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
18700 {
18701 // delegate the call to get_impl_ptr<>()
18702 return get_impl_ptr(static_cast<PointerType>(nullptr));
18703 }
18704
18707 template < typename PointerType, typename std::enable_if <
18708 std::is_pointer<PointerType>::value&&
18709 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
18710 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
18711 {
18712 // delegate the call to get_impl_ptr<>() const
18713 return get_impl_ptr(static_cast<PointerType>(nullptr));
18714 }
18715
18716 private:
18755 template < typename ValueType,
18759 int > = 0 >
18760 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
18761 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
18762 {
18763 auto ret = ValueType();
18764 JSONSerializer<ValueType>::from_json(*this, ret);
18765 return ret;
18766 }
18767
18798 template < typename ValueType,
18801 int > = 0 >
18802 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
18803 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
18804 {
18805 return JSONSerializer<ValueType>::from_json(*this);
18806 }
18807
18823 template < typename BasicJsonType,
18826 int > = 0 >
18827 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
18828 {
18829 return *this;
18830 }
18831
18846 template<typename BasicJsonType,
18848 std::is_same<BasicJsonType, basic_json_t>::value,
18849 int> = 0>
18851 {
18852 return *this;
18853 }
18854
18859 template<typename PointerType,
18861 std::is_pointer<PointerType>::value,
18862 int> = 0>
18863 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
18864 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
18865 {
18866 // delegate the call to get_ptr
18867 return get_ptr<PointerType>();
18868 }
18869
18870 public:
18894 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
18895#if defined(JSON_HAS_CPP_14)
18896 constexpr
18897#endif
18898 auto get() const noexcept(
18899 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
18900 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
18901 {
18902 // we cannot static_assert on ValueTypeCV being non-const, because
18903 // there is support for get<const basic_json_t>(), which is why we
18904 // still need the uncvref
18905 static_assert(!std::is_reference<ValueTypeCV>::value,
18906 "get() cannot be used with reference types, you might want to use get_ref()");
18907 return get_impl<ValueType>(detail::priority_tag<4> {});
18908 }
18909
18937 template<typename PointerType, typename std::enable_if<
18938 std::is_pointer<PointerType>::value, int>::type = 0>
18939 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
18940 {
18941 // delegate the call to get_ptr
18942 return get_ptr<PointerType>();
18943 }
18944
18947 template < typename ValueType,
18951 int > = 0 >
18952 ValueType & get_to(ValueType& v) const noexcept(noexcept(
18953 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
18954 {
18955 JSONSerializer<ValueType>::from_json(*this, v);
18956 return v;
18957 }
18958
18959 // specialization to allow calling get_to with a basic_json value
18960 // see https://github.com/nlohmann/json/issues/2175
18961 template<typename ValueType,
18964 int> = 0>
18965 ValueType & get_to(ValueType& v) const
18966 {
18967 v = *this;
18968 return v;
18969 }
18970
18971 template <
18972 typename T, std::size_t N,
18973 typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
18976 Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
18977 noexcept(noexcept(JSONSerializer<Array>::from_json(
18978 std::declval<const basic_json_t&>(), v)))
18979 {
18980 JSONSerializer<Array>::from_json(*this, v);
18981 return v;
18982 }
18983
18986 template<typename ReferenceType, typename std::enable_if<
18987 std::is_reference<ReferenceType>::value, int>::type = 0>
18988 ReferenceType get_ref()
18989 {
18990 // delegate call to get_ref_impl
18991 return get_ref_impl<ReferenceType>(*this);
18992 }
18993
18996 template < typename ReferenceType, typename std::enable_if <
18997 std::is_reference<ReferenceType>::value&&
18998 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
18999 ReferenceType get_ref() const
19000 {
19001 // delegate call to get_ref_impl
19002 return get_ref_impl<ReferenceType>(*this);
19003 }
19004
19034 template < typename ValueType, typename std::enable_if <
19041
19042#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
19044#endif
19046 >::value, int >::type = 0 >
19047 JSON_EXPLICIT operator ValueType() const
19048 {
19049 // delegate the call to get<>() const
19050 return get<ValueType>();
19051 }
19052
19056 {
19057 if (!is_binary())
19058 {
19059 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
19060 }
19061
19062 return *get_ptr<binary_t*>();
19063 }
19064
19067 const binary_t& get_binary() const
19068 {
19069 if (!is_binary())
19070 {
19071 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
19072 }
19073
19074 return *get_ptr<const binary_t*>();
19075 }
19076
19078
19079
19081 // element access //
19083
19087
19091 {
19092 // at only works for arrays
19094 {
19095 JSON_TRY
19096 {
19097 return set_parent(m_value.array->at(idx));
19098 }
19099 JSON_CATCH (std::out_of_range&)
19100 {
19101 // create better exception explanation
19102 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
19103 }
19104 }
19105 else
19106 {
19107 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
19108 }
19109 }
19110
19114 {
19115 // at only works for arrays
19117 {
19118 JSON_TRY
19119 {
19120 return m_value.array->at(idx);
19121 }
19122 JSON_CATCH (std::out_of_range&)
19123 {
19124 // create better exception explanation
19125 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
19126 }
19127 }
19128 else
19129 {
19130 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
19131 }
19132 }
19133
19136 reference at(const typename object_t::key_type& key)
19137 {
19138 // at only works for objects
19140 {
19141 JSON_TRY
19142 {
19143 return set_parent(m_value.object->at(key));
19144 }
19145 JSON_CATCH (std::out_of_range&)
19146 {
19147 // create better exception explanation
19148 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
19149 }
19150 }
19151 else
19152 {
19153 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
19154 }
19155 }
19156
19159 const_reference at(const typename object_t::key_type& key) const
19160 {
19161 // at only works for objects
19163 {
19164 JSON_TRY
19165 {
19166 return m_value.object->at(key);
19167 }
19168 JSON_CATCH (std::out_of_range&)
19169 {
19170 // create better exception explanation
19171 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
19172 }
19173 }
19174 else
19175 {
19176 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
19177 }
19178 }
19179
19183 {
19184 // implicitly convert null value to an empty array
19185 if (is_null())
19186 {
19187 m_type = value_t::array;
19188 m_value.array = create<array_t>();
19190 }
19191
19192 // operator[] only works for arrays
19194 {
19195 // fill up array with null values if given idx is outside range
19196 if (idx >= m_value.array->size())
19197 {
19198#if JSON_DIAGNOSTICS
19199 // remember array size & capacity before resizing
19200 const auto old_size = m_value.array->size();
19201 const auto old_capacity = m_value.array->capacity();
19202#endif
19203 m_value.array->resize(idx + 1);
19204
19205#if JSON_DIAGNOSTICS
19206 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
19207 {
19208 // capacity has changed: update all parents
19209 set_parents();
19210 }
19211 else
19212 {
19213 // set parent for values added above
19214 set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
19215 }
19216#endif
19218 }
19219
19220 return m_value.array->operator[](idx);
19221 }
19222
19223 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
19224 }
19225
19229 {
19230 // const operator[] only works for arrays
19232 {
19233 return m_value.array->operator[](idx);
19234 }
19235
19236 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
19237 }
19238
19241 reference operator[](const typename object_t::key_type& key)
19242 {
19243 // implicitly convert null value to an empty object
19244 if (is_null())
19245 {
19246 m_type = value_t::object;
19247 m_value.object = create<object_t>();
19249 }
19250
19251 // operator[] only works for objects
19253 {
19254 return set_parent(m_value.object->operator[](key));
19255 }
19256
19257 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
19258 }
19259
19262 const_reference operator[](const typename object_t::key_type& key) const
19263 {
19264 // const operator[] only works for objects
19266 {
19267 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
19268 return m_value.object->find(key)->second;
19269 }
19270
19271 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
19272 }
19273
19276 template<typename T>
19278 reference operator[](T* key)
19279 {
19280 // implicitly convert null to object
19281 if (is_null())
19282 {
19283 m_type = value_t::object;
19284 m_value = value_t::object;
19286 }
19287
19288 // at only works for objects
19290 {
19291 return set_parent(m_value.object->operator[](key));
19292 }
19293
19294 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
19295 }
19296
19299 template<typename T>
19301 const_reference operator[](T* key) const
19302 {
19303 // at only works for objects
19305 {
19306 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
19307 return m_value.object->find(key)->second;
19308 }
19309
19310 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
19311 }
19312
19316 template < class ValueType, typename std::enable_if <
19318 && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
19319 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
19320 {
19321 // at only works for objects
19323 {
19324 // if key is found, return value and given default value otherwise
19325 const auto it = find(key);
19326 if (it != end())
19327 {
19328 return it->template get<ValueType>();
19329 }
19330
19331 return default_value;
19332 }
19333
19334 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
19335 }
19336
19340 string_t value(const typename object_t::key_type& key, const char* default_value) const
19341 {
19342 return value(key, string_t(default_value));
19343 }
19344
19347 template<class ValueType, typename std::enable_if<
19349 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
19350 {
19351 // at only works for objects
19353 {
19354 // if pointer resolves a value, return it or use default value
19355 JSON_TRY
19356 {
19357 return ptr.get_checked(this).template get<ValueType>();
19358 }
19360 {
19361 return default_value;
19362 }
19363 }
19364
19365 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
19366 }
19367
19372 string_t value(const json_pointer& ptr, const char* default_value) const
19373 {
19374 return value(ptr, string_t(default_value));
19375 }
19376
19380 {
19381 return *begin();
19382 }
19383
19387 {
19388 return *cbegin();
19389 }
19390
19394 {
19395 auto tmp = end();
19396 --tmp;
19397 return *tmp;
19398 }
19399
19403 {
19404 auto tmp = cend();
19405 --tmp;
19406 return *tmp;
19407 }
19408
19411 template < class IteratorType, typename std::enable_if <
19412 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
19413 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
19414 = 0 >
19415 IteratorType erase(IteratorType pos)
19416 {
19417 // make sure iterator fits the current value
19418 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
19419 {
19420 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
19421 }
19422
19423 IteratorType result = end();
19424
19425 switch (m_type)
19426 {
19427 case value_t::boolean:
19428 case value_t::number_float:
19429 case value_t::number_integer:
19430 case value_t::number_unsigned:
19431 case value_t::string:
19432 case value_t::binary:
19433 {
19434 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
19435 {
19436 JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
19437 }
19438
19439 if (is_string())
19440 {
19441 AllocatorType<string_t> alloc;
19442 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
19443 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
19444 m_value.string = nullptr;
19445 }
19446 else if (is_binary())
19447 {
19448 AllocatorType<binary_t> alloc;
19449 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
19450 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
19451 m_value.binary = nullptr;
19452 }
19453
19454 m_type = value_t::null;
19456 break;
19457 }
19458
19459 case value_t::object:
19460 {
19461 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
19462 break;
19463 }
19464
19465 case value_t::array:
19466 {
19467 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
19468 break;
19469 }
19470
19471 case value_t::null:
19472 case value_t::discarded:
19473 default:
19474 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
19475 }
19476
19477 return result;
19478 }
19479
19482 template < class IteratorType, typename std::enable_if <
19483 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
19484 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
19485 = 0 >
19486 IteratorType erase(IteratorType first, IteratorType last)
19487 {
19488 // make sure iterator fits the current value
19489 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
19490 {
19491 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
19492 }
19493
19494 IteratorType result = end();
19495
19496 switch (m_type)
19497 {
19498 case value_t::boolean:
19499 case value_t::number_float:
19500 case value_t::number_integer:
19501 case value_t::number_unsigned:
19502 case value_t::string:
19503 case value_t::binary:
19504 {
19505 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
19506 || !last.m_it.primitive_iterator.is_end()))
19507 {
19508 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
19509 }
19510
19511 if (is_string())
19512 {
19513 AllocatorType<string_t> alloc;
19514 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
19515 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
19516 m_value.string = nullptr;
19517 }
19518 else if (is_binary())
19519 {
19520 AllocatorType<binary_t> alloc;
19521 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
19522 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
19523 m_value.binary = nullptr;
19524 }
19525
19526 m_type = value_t::null;
19528 break;
19529 }
19530
19531 case value_t::object:
19532 {
19533 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
19534 last.m_it.object_iterator);
19535 break;
19536 }
19537
19538 case value_t::array:
19539 {
19540 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
19541 last.m_it.array_iterator);
19542 break;
19543 }
19544
19545 case value_t::null:
19546 case value_t::discarded:
19547 default:
19548 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
19549 }
19550
19551 return result;
19552 }
19553
19556 size_type erase(const typename object_t::key_type& key)
19557 {
19558 // this erase only works for objects
19560 {
19561 return m_value.object->erase(key);
19562 }
19563
19564 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
19565 }
19566
19569 void erase(const size_type idx)
19570 {
19571 // this erase only works for arrays
19573 {
19574 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
19575 {
19576 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
19577 }
19578
19579 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
19580 }
19581 else
19582 {
19583 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
19584 }
19585 }
19586
19588
19589
19591 // lookup //
19593
19596
19599 template<typename KeyT>
19600 iterator find(KeyT&& key)
19601 {
19602 auto result = end();
19603
19604 if (is_object())
19605 {
19606 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
19607 }
19608
19609 return result;
19610 }
19611
19614 template<typename KeyT>
19615 const_iterator find(KeyT&& key) const
19616 {
19617 auto result = cend();
19618
19619 if (is_object())
19620 {
19621 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
19622 }
19623
19624 return result;
19625 }
19626
19629 template<typename KeyT>
19630 size_type count(KeyT&& key) const
19631 {
19632 // return 0 for all nonobject types
19633 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
19634 }
19635
19638 template < typename KeyT, typename std::enable_if <
19639 !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
19640 bool contains(KeyT && key) const
19641 {
19642 return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
19643 }
19644
19647 bool contains(const json_pointer& ptr) const
19648 {
19649 return ptr.contains(this);
19650 }
19651
19653
19654
19656 // iterators //
19658
19661
19664 iterator begin() noexcept
19665 {
19666 iterator result(this);
19667 result.set_begin();
19668 return result;
19669 }
19670
19673 const_iterator begin() const noexcept
19674 {
19675 return cbegin();
19676 }
19677
19680 const_iterator cbegin() const noexcept
19681 {
19682 const_iterator result(this);
19683 result.set_begin();
19684 return result;
19685 }
19686
19689 iterator end() noexcept
19690 {
19691 iterator result(this);
19692 result.set_end();
19693 return result;
19694 }
19695
19698 const_iterator end() const noexcept
19699 {
19700 return cend();
19701 }
19702
19705 const_iterator cend() const noexcept
19706 {
19707 const_iterator result(this);
19708 result.set_end();
19709 return result;
19710 }
19711
19715 {
19716 return reverse_iterator(end());
19717 }
19718
19722 {
19723 return crbegin();
19724 }
19725
19729 {
19730 return reverse_iterator(begin());
19731 }
19732
19736 {
19737 return crend();
19738 }
19739
19743 {
19744 return const_reverse_iterator(cend());
19745 }
19746
19750 {
19752 }
19753
19754 public:
19762 {
19763 return ref.items();
19764 }
19765
19773 {
19774 return ref.items();
19775 }
19776
19780 {
19781 return iteration_proxy<iterator>(*this);
19782 }
19783
19787 {
19788 return iteration_proxy<const_iterator>(*this);
19789 }
19790
19792
19793
19795 // capacity //
19797
19800
19803 bool empty() const noexcept
19804 {
19805 switch (m_type)
19806 {
19807 case value_t::null:
19808 {
19809 // null values are empty
19810 return true;
19811 }
19812
19813 case value_t::array:
19814 {
19815 // delegate call to array_t::empty()
19816 return m_value.array->empty();
19817 }
19818
19819 case value_t::object:
19820 {
19821 // delegate call to object_t::empty()
19822 return m_value.object->empty();
19823 }
19824
19825 case value_t::string:
19826 case value_t::boolean:
19827 case value_t::number_integer:
19828 case value_t::number_unsigned:
19829 case value_t::number_float:
19830 case value_t::binary:
19831 case value_t::discarded:
19832 default:
19833 {
19834 // all other types are nonempty
19835 return false;
19836 }
19837 }
19838 }
19839
19842 size_type size() const noexcept
19843 {
19844 switch (m_type)
19845 {
19846 case value_t::null:
19847 {
19848 // null values are empty
19849 return 0;
19850 }
19851
19852 case value_t::array:
19853 {
19854 // delegate call to array_t::size()
19855 return m_value.array->size();
19856 }
19857
19858 case value_t::object:
19859 {
19860 // delegate call to object_t::size()
19861 return m_value.object->size();
19862 }
19863
19864 case value_t::string:
19865 case value_t::boolean:
19866 case value_t::number_integer:
19867 case value_t::number_unsigned:
19868 case value_t::number_float:
19869 case value_t::binary:
19870 case value_t::discarded:
19871 default:
19872 {
19873 // all other types have size 1
19874 return 1;
19875 }
19876 }
19877 }
19878
19881 size_type max_size() const noexcept
19882 {
19883 switch (m_type)
19884 {
19885 case value_t::array:
19886 {
19887 // delegate call to array_t::max_size()
19888 return m_value.array->max_size();
19889 }
19890
19891 case value_t::object:
19892 {
19893 // delegate call to object_t::max_size()
19894 return m_value.object->max_size();
19895 }
19896
19897 case value_t::null:
19898 case value_t::string:
19899 case value_t::boolean:
19900 case value_t::number_integer:
19901 case value_t::number_unsigned:
19902 case value_t::number_float:
19903 case value_t::binary:
19904 case value_t::discarded:
19905 default:
19906 {
19907 // all other types have max_size() == size()
19908 return size();
19909 }
19910 }
19911 }
19912
19914
19915
19917 // modifiers //
19919
19922
19925 void clear() noexcept
19926 {
19927 switch (m_type)
19928 {
19929 case value_t::number_integer:
19930 {
19931 m_value.number_integer = 0;
19932 break;
19933 }
19934
19935 case value_t::number_unsigned:
19936 {
19937 m_value.number_unsigned = 0;
19938 break;
19939 }
19940
19941 case value_t::number_float:
19942 {
19943 m_value.number_float = 0.0;
19944 break;
19945 }
19946
19947 case value_t::boolean:
19948 {
19949 m_value.boolean = false;
19950 break;
19951 }
19952
19953 case value_t::string:
19954 {
19955 m_value.string->clear();
19956 break;
19957 }
19958
19959 case value_t::binary:
19960 {
19961 m_value.binary->clear();
19962 break;
19963 }
19964
19965 case value_t::array:
19966 {
19967 m_value.array->clear();
19968 break;
19969 }
19970
19971 case value_t::object:
19972 {
19973 m_value.object->clear();
19974 break;
19975 }
19976
19977 case value_t::null:
19978 case value_t::discarded:
19979 default:
19980 break;
19981 }
19982 }
19983
19987 {
19988 // push_back only works for null objects or arrays
19989 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
19990 {
19991 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
19992 }
19993
19994 // transform null object into an array
19995 if (is_null())
19996 {
19997 m_type = value_t::array;
19998 m_value = value_t::array;
20000 }
20001
20002 // add element to array (move semantics)
20003 const auto old_capacity = m_value.array->capacity();
20004 m_value.array->push_back(std::move(val));
20005 set_parent(m_value.array->back(), old_capacity);
20006 // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
20007 }
20008
20012 {
20013 push_back(std::move(val));
20014 return *this;
20015 }
20016
20019 void push_back(const basic_json& val)
20020 {
20021 // push_back only works for null objects or arrays
20022 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
20023 {
20024 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
20025 }
20026
20027 // transform null object into an array
20028 if (is_null())
20029 {
20030 m_type = value_t::array;
20031 m_value = value_t::array;
20033 }
20034
20035 // add element to array
20036 const auto old_capacity = m_value.array->capacity();
20037 m_value.array->push_back(val);
20038 set_parent(m_value.array->back(), old_capacity);
20039 }
20040
20044 {
20045 push_back(val);
20046 return *this;
20047 }
20048
20051 void push_back(const typename object_t::value_type& val)
20052 {
20053 // push_back only works for null objects or objects
20054 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
20055 {
20056 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
20057 }
20058
20059 // transform null object into an object
20060 if (is_null())
20061 {
20062 m_type = value_t::object;
20063 m_value = value_t::object;
20065 }
20066
20067 // add element to object
20068 auto res = m_value.object->insert(val);
20069 set_parent(res.first->second);
20070 }
20071
20074 reference operator+=(const typename object_t::value_type& val)
20075 {
20076 push_back(val);
20077 return *this;
20078 }
20079
20083 {
20084 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
20085 {
20086 basic_json&& key = init.begin()->moved_or_copied();
20087 push_back(typename object_t::value_type(
20088 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
20089 }
20090 else
20091 {
20092 push_back(basic_json(init));
20093 }
20094 }
20095
20099 {
20100 push_back(init);
20101 return *this;
20102 }
20103
20106 template<class... Args>
20107 reference emplace_back(Args&& ... args)
20108 {
20109 // emplace_back only works for null objects or arrays
20110 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
20111 {
20112 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
20113 }
20114
20115 // transform null object into an array
20116 if (is_null())
20117 {
20118 m_type = value_t::array;
20119 m_value = value_t::array;
20121 }
20122
20123 // add element to array (perfect forwarding)
20124 const auto old_capacity = m_value.array->capacity();
20125 m_value.array->emplace_back(std::forward<Args>(args)...);
20126 return set_parent(m_value.array->back(), old_capacity);
20127 }
20128
20131 template<class... Args>
20132 std::pair<iterator, bool> emplace(Args&& ... args)
20133 {
20134 // emplace only works for null objects or arrays
20135 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
20136 {
20137 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
20138 }
20139
20140 // transform null object into an object
20141 if (is_null())
20142 {
20143 m_type = value_t::object;
20144 m_value = value_t::object;
20146 }
20147
20148 // add element to array (perfect forwarding)
20149 auto res = m_value.object->emplace(std::forward<Args>(args)...);
20150 set_parent(res.first->second);
20151
20152 // create result iterator and set iterator to the result of emplace
20153 auto it = begin();
20154 it.m_it.object_iterator = res.first;
20155
20156 // return pair of iterator and boolean
20157 return {it, res.second};
20158 }
20159
20163 template<typename... Args>
20165 {
20166 iterator result(this);
20167 JSON_ASSERT(m_value.array != nullptr);
20168
20169 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
20170 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
20171 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
20172
20173 // This could have been written as:
20174 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
20175 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
20176
20177 set_parents();
20178 return result;
20179 }
20180
20184 {
20185 // insert only works for arrays
20187 {
20188 // check if iterator pos fits to this JSON value
20189 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
20190 {
20191 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
20192 }
20193
20194 // insert to array and return iterator
20195 return insert_iterator(pos, val);
20196 }
20197
20198 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
20199 }
20200
20204 {
20205 return insert(pos, val);
20206 }
20207
20211 {
20212 // insert only works for arrays
20214 {
20215 // check if iterator pos fits to this JSON value
20216 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
20217 {
20218 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
20219 }
20220
20221 // insert to array and return iterator
20222 return insert_iterator(pos, cnt, val);
20223 }
20224
20225 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
20226 }
20227
20231 {
20232 // insert only works for arrays
20234 {
20235 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
20236 }
20237
20238 // check if iterator pos fits to this JSON value
20239 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
20240 {
20241 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
20242 }
20243
20244 // check if range iterators belong to the same JSON object
20245 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
20246 {
20247 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
20248 }
20249
20250 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
20251 {
20252 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
20253 }
20254
20255 // insert to array and return iterator
20256 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
20257 }
20258
20262 {
20263 // insert only works for arrays
20265 {
20266 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
20267 }
20268
20269 // check if iterator pos fits to this JSON value
20270 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
20271 {
20272 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
20273 }
20274
20275 // insert to array and return iterator
20276 return insert_iterator(pos, ilist.begin(), ilist.end());
20277 }
20278
20282 {
20283 // insert only works for objects
20285 {
20286 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
20287 }
20288
20289 // check if range iterators belong to the same JSON object
20290 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
20291 {
20292 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
20293 }
20294
20295 // passed iterators must belong to objects
20296 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
20297 {
20298 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
20299 }
20300
20301 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
20302 }
20303
20306 void update(const_reference j, bool merge_objects = false)
20307 {
20308 update(j.begin(), j.end(), merge_objects);
20309 }
20310
20313 void update(const_iterator first, const_iterator last, bool merge_objects = false)
20314 {
20315 // implicitly convert null value to an empty object
20316 if (is_null())
20317 {
20318 m_type = value_t::object;
20319 m_value.object = create<object_t>();
20321 }
20322
20324 {
20325 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
20326 }
20327
20328 // check if range iterators belong to the same JSON object
20329 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
20330 {
20331 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
20332 }
20333
20334 // passed iterators must belong to objects
20335 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
20336 {
20337 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(first.m_object->type_name()), *first.m_object));
20338 }
20339
20340 for (auto it = first; it != last; ++it)
20341 {
20342 if (merge_objects && it.value().is_object())
20343 {
20344 auto it2 = m_value.object->find(it.key());
20345 if (it2 != m_value.object->end())
20346 {
20347 it2->second.update(it.value(), true);
20348 continue;
20349 }
20350 }
20351 m_value.object->operator[](it.key()) = it.value();
20352#if JSON_DIAGNOSTICS
20353 m_value.object->operator[](it.key()).m_parent = this;
20354#endif
20355 }
20356 }
20357
20360 void swap(reference other) noexcept (
20361 std::is_nothrow_move_constructible<value_t>::value&&
20362 std::is_nothrow_move_assignable<value_t>::value&&
20363 std::is_nothrow_move_constructible<json_value>::value&&
20364 std::is_nothrow_move_assignable<json_value>::value
20365 )
20366 {
20367 std::swap(m_type, other.m_type);
20368 std::swap(m_value, other.m_value);
20369
20370 set_parents();
20371 other.set_parents();
20373 }
20374
20377 friend void swap(reference left, reference right) noexcept (
20378 std::is_nothrow_move_constructible<value_t>::value&&
20379 std::is_nothrow_move_assignable<value_t>::value&&
20380 std::is_nothrow_move_constructible<json_value>::value&&
20381 std::is_nothrow_move_assignable<json_value>::value
20382 )
20383 {
20384 left.swap(right);
20385 }
20386
20389 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
20390 {
20391 // swap only works for arrays
20393 {
20394 std::swap(*(m_value.array), other);
20395 }
20396 else
20397 {
20398 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
20399 }
20400 }
20401
20404 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
20405 {
20406 // swap only works for objects
20408 {
20409 std::swap(*(m_value.object), other);
20410 }
20411 else
20412 {
20413 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
20414 }
20415 }
20416
20419 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
20420 {
20421 // swap only works for strings
20423 {
20424 std::swap(*(m_value.string), other);
20425 }
20426 else
20427 {
20428 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
20429 }
20430 }
20431
20434 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
20435 {
20436 // swap only works for strings
20438 {
20439 std::swap(*(m_value.binary), other);
20440 }
20441 else
20442 {
20443 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
20444 }
20445 }
20446
20449 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
20450 {
20451 // swap only works for strings
20453 {
20454 std::swap(*(m_value.binary), other);
20455 }
20456 else
20457 {
20458 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
20459 }
20460 }
20461
20463
20464 public:
20466 // lexicographical comparison operators //
20468
20471
20474 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
20475 {
20476#ifdef __GNUC__
20477#pragma GCC diagnostic push
20478#pragma GCC diagnostic ignored "-Wfloat-equal"
20479#endif
20480 const auto lhs_type = lhs.type();
20481 const auto rhs_type = rhs.type();
20482
20483 if (lhs_type == rhs_type)
20484 {
20485 switch (lhs_type)
20486 {
20487 case value_t::array:
20488 return *lhs.m_value.array == *rhs.m_value.array;
20489
20490 case value_t::object:
20491 return *lhs.m_value.object == *rhs.m_value.object;
20492
20493 case value_t::null:
20494 return true;
20495
20496 case value_t::string:
20497 return *lhs.m_value.string == *rhs.m_value.string;
20498
20499 case value_t::boolean:
20500 return lhs.m_value.boolean == rhs.m_value.boolean;
20501
20502 case value_t::number_integer:
20503 return lhs.m_value.number_integer == rhs.m_value.number_integer;
20504
20505 case value_t::number_unsigned:
20506 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
20507
20508 case value_t::number_float:
20509 return lhs.m_value.number_float == rhs.m_value.number_float;
20510
20511 case value_t::binary:
20512 return *lhs.m_value.binary == *rhs.m_value.binary;
20513
20514 case value_t::discarded:
20515 default:
20516 return false;
20517 }
20518 }
20519 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
20520 {
20521 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
20522 }
20523 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
20524 {
20525 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
20526 }
20527 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
20528 {
20529 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
20530 }
20531 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
20532 {
20533 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
20534 }
20535 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
20536 {
20537 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
20538 }
20539 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
20540 {
20541 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
20542 }
20543
20544 return false;
20545#ifdef __GNUC__
20546#pragma GCC diagnostic pop
20547#endif
20548 }
20549
20552 template<typename ScalarType, typename std::enable_if<
20553 std::is_scalar<ScalarType>::value, int>::type = 0>
20554 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
20555 {
20556 return lhs == basic_json(rhs);
20557 }
20558
20561 template<typename ScalarType, typename std::enable_if<
20562 std::is_scalar<ScalarType>::value, int>::type = 0>
20563 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
20564 {
20565 return basic_json(lhs) == rhs;
20566 }
20567
20570 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
20571 {
20572 return !(lhs == rhs);
20573 }
20574
20577 template<typename ScalarType, typename std::enable_if<
20578 std::is_scalar<ScalarType>::value, int>::type = 0>
20579 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
20580 {
20581 return lhs != basic_json(rhs);
20582 }
20583
20586 template<typename ScalarType, typename std::enable_if<
20587 std::is_scalar<ScalarType>::value, int>::type = 0>
20588 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
20589 {
20590 return basic_json(lhs) != rhs;
20591 }
20592
20595 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
20596 {
20597 const auto lhs_type = lhs.type();
20598 const auto rhs_type = rhs.type();
20599
20600 if (lhs_type == rhs_type)
20601 {
20602 switch (lhs_type)
20603 {
20604 case value_t::array:
20605 // note parentheses are necessary, see
20606 // https://github.com/nlohmann/json/issues/1530
20607 return (*lhs.m_value.array) < (*rhs.m_value.array);
20608
20609 case value_t::object:
20610 return (*lhs.m_value.object) < (*rhs.m_value.object);
20611
20612 case value_t::null:
20613 return false;
20614
20615 case value_t::string:
20616 return (*lhs.m_value.string) < (*rhs.m_value.string);
20617
20618 case value_t::boolean:
20619 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
20620
20621 case value_t::number_integer:
20622 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
20623
20624 case value_t::number_unsigned:
20625 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
20626
20627 case value_t::number_float:
20628 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
20629
20630 case value_t::binary:
20631 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
20632
20633 case value_t::discarded:
20634 default:
20635 return false;
20636 }
20637 }
20638 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
20639 {
20640 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
20641 }
20642 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
20643 {
20644 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
20645 }
20646 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
20647 {
20648 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
20649 }
20650 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
20651 {
20652 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
20653 }
20654 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
20655 {
20656 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
20657 }
20658 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
20659 {
20660 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
20661 }
20662
20663 // We only reach this line if we cannot compare values. In that case,
20664 // we compare types. Note we have to call the operator explicitly,
20665 // because MSVC has problems otherwise.
20666 return operator<(lhs_type, rhs_type);
20667 }
20668
20671 template<typename ScalarType, typename std::enable_if<
20672 std::is_scalar<ScalarType>::value, int>::type = 0>
20673 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
20674 {
20675 return lhs < basic_json(rhs);
20676 }
20677
20680 template<typename ScalarType, typename std::enable_if<
20681 std::is_scalar<ScalarType>::value, int>::type = 0>
20682 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
20683 {
20684 return basic_json(lhs) < rhs;
20685 }
20686
20689 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
20690 {
20691 return !(rhs < lhs);
20692 }
20693
20696 template<typename ScalarType, typename std::enable_if<
20697 std::is_scalar<ScalarType>::value, int>::type = 0>
20698 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
20699 {
20700 return lhs <= basic_json(rhs);
20701 }
20702
20705 template<typename ScalarType, typename std::enable_if<
20706 std::is_scalar<ScalarType>::value, int>::type = 0>
20707 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
20708 {
20709 return basic_json(lhs) <= rhs;
20710 }
20711
20714 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
20715 {
20716 return !(lhs <= rhs);
20717 }
20718
20721 template<typename ScalarType, typename std::enable_if<
20722 std::is_scalar<ScalarType>::value, int>::type = 0>
20723 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
20724 {
20725 return lhs > basic_json(rhs);
20726 }
20727
20730 template<typename ScalarType, typename std::enable_if<
20731 std::is_scalar<ScalarType>::value, int>::type = 0>
20732 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
20733 {
20734 return basic_json(lhs) > rhs;
20735 }
20736
20739 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
20740 {
20741 return !(lhs < rhs);
20742 }
20743
20746 template<typename ScalarType, typename std::enable_if<
20747 std::is_scalar<ScalarType>::value, int>::type = 0>
20748 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
20749 {
20750 return lhs >= basic_json(rhs);
20751 }
20752
20755 template<typename ScalarType, typename std::enable_if<
20756 std::is_scalar<ScalarType>::value, int>::type = 0>
20757 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
20758 {
20759 return basic_json(lhs) >= rhs;
20760 }
20761
20763
20765 // serialization //
20767
20770#ifndef JSON_NO_IO
20773 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
20774 {
20775 // read width member and use it as indentation parameter if nonzero
20776 const bool pretty_print = o.width() > 0;
20777 const auto indentation = pretty_print ? o.width() : 0;
20778
20779 // reset width to 0 for subsequent calls to this stream
20780 o.width(0);
20781
20782 // do the actual serialization
20783 serializer s(detail::output_adapter<char>(o), o.fill());
20784 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
20785 return o;
20786 }
20787
20794 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
20795 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
20796 {
20797 return o << j;
20798 }
20799#endif // JSON_NO_IO
20801
20802
20804 // deserialization //
20806
20809
20812 template<typename InputType>
20814 static basic_json parse(InputType&& i,
20815 const parser_callback_t cb = nullptr,
20816 const bool allow_exceptions = true,
20817 const bool ignore_comments = false)
20818 {
20819 basic_json result;
20820 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
20821 return result;
20822 }
20823
20826 template<typename IteratorType>
20828 static basic_json parse(IteratorType first,
20829 IteratorType last,
20830 const parser_callback_t cb = nullptr,
20831 const bool allow_exceptions = true,
20832 const bool ignore_comments = false)
20833 {
20834 basic_json result;
20835 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
20836 return result;
20837 }
20838
20840 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
20841 static basic_json parse(detail::span_input_adapter&& i,
20842 const parser_callback_t cb = nullptr,
20843 const bool allow_exceptions = true,
20844 const bool ignore_comments = false)
20845 {
20846 basic_json result;
20847 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
20848 return result;
20849 }
20850
20853 template<typename InputType>
20854 static bool accept(InputType&& i,
20855 const bool ignore_comments = false)
20856 {
20857 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
20858 }
20859
20862 template<typename IteratorType>
20863 static bool accept(IteratorType first, IteratorType last,
20864 const bool ignore_comments = false)
20865 {
20866 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
20867 }
20868
20870 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
20871 static bool accept(detail::span_input_adapter&& i,
20872 const bool ignore_comments = false)
20873 {
20874 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
20875 }
20876
20879 template <typename InputType, typename SAX>
20881 static bool sax_parse(InputType&& i, SAX* sax,
20883 const bool strict = true,
20884 const bool ignore_comments = false)
20885 {
20886 auto ia = detail::input_adapter(std::forward<InputType>(i));
20887 return format == input_format_t::json
20888 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
20889 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
20890 }
20891
20894 template<class IteratorType, class SAX>
20896 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
20898 const bool strict = true,
20899 const bool ignore_comments = false)
20900 {
20901 auto ia = detail::input_adapter(std::move(first), std::move(last));
20902 return format == input_format_t::json
20903 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
20904 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
20905 }
20906
20912 template <typename SAX>
20913 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
20915 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
20917 const bool strict = true,
20918 const bool ignore_comments = false)
20919 {
20920 auto ia = i.get();
20921 return format == input_format_t::json
20922 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
20923 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
20924 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
20925 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
20926 }
20927#ifndef JSON_NO_IO
20934 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
20935 friend std::istream& operator<<(basic_json& j, std::istream& i)
20936 {
20937 return operator>>(i, j);
20938 }
20939
20942 friend std::istream& operator>>(std::istream& i, basic_json& j)
20943 {
20944 parser(detail::input_adapter(i)).parse(false, j);
20945 return i;
20946 }
20947#endif // JSON_NO_IO
20949
20951 // convenience functions //
20953
20957 const char* type_name() const noexcept
20958 {
20959 switch (m_type)
20960 {
20961 case value_t::null:
20962 return "null";
20963 case value_t::object:
20964 return "object";
20965 case value_t::array:
20966 return "array";
20967 case value_t::string:
20968 return "string";
20969 case value_t::boolean:
20970 return "boolean";
20971 case value_t::binary:
20972 return "binary";
20973 case value_t::discarded:
20974 return "discarded";
20975 case value_t::number_integer:
20976 case value_t::number_unsigned:
20977 case value_t::number_float:
20978 default:
20979 return "number";
20980 }
20981 }
20982
20983
20986 // member variables //
20988
20990 value_t m_type = value_t::null;
20991
20994
20995#if JSON_DIAGNOSTICS
20997 basic_json* m_parent = nullptr;
20998#endif
20999
21001 // binary serialization/deserialization //
21003
21006
21007 public:
21010 static std::vector<std::uint8_t> to_cbor(const basic_json& j)
21011 {
21012 std::vector<std::uint8_t> result;
21013 to_cbor(j, result);
21014 return result;
21015 }
21016
21023
21027 {
21029 }
21030
21033 static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
21034 {
21035 std::vector<std::uint8_t> result;
21036 to_msgpack(j, result);
21037 return result;
21038 }
21039
21046
21050 {
21052 }
21053
21056 static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
21057 const bool use_size = false,
21058 const bool use_type = false)
21059 {
21060 std::vector<std::uint8_t> result;
21061 to_ubjson(j, result, use_size, use_type);
21062 return result;
21063 }
21064
21068 const bool use_size = false, const bool use_type = false)
21069 {
21070 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
21071 }
21072
21076 const bool use_size = false, const bool use_type = false)
21077 {
21078 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
21079 }
21080
21083 static std::vector<std::uint8_t> to_bson(const basic_json& j)
21084 {
21085 std::vector<std::uint8_t> result;
21086 to_bson(j, result);
21087 return result;
21088 }
21089
21096
21100 {
21102 }
21103
21106 template<typename InputType>
21108 static basic_json from_cbor(InputType&& i,
21109 const bool strict = true,
21110 const bool allow_exceptions = true,
21111 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
21112 {
21113 basic_json result;
21114 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21115 auto ia = detail::input_adapter(std::forward<InputType>(i));
21116 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
21117 return res ? result : basic_json(value_t::discarded);
21118 }
21119
21122 template<typename IteratorType>
21124 static basic_json from_cbor(IteratorType first, IteratorType last,
21125 const bool strict = true,
21126 const bool allow_exceptions = true,
21127 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
21128 {
21129 basic_json result;
21130 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21131 auto ia = detail::input_adapter(std::move(first), std::move(last));
21132 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
21133 return res ? result : basic_json(value_t::discarded);
21134 }
21135
21136 template<typename T>
21138 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
21139 static basic_json from_cbor(const T* ptr, std::size_t len,
21140 const bool strict = true,
21141 const bool allow_exceptions = true,
21142 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
21143 {
21144 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
21145 }
21146
21147
21149 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
21150 static basic_json from_cbor(detail::span_input_adapter&& i,
21151 const bool strict = true,
21152 const bool allow_exceptions = true,
21153 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
21154 {
21155 basic_json result;
21156 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21157 auto ia = i.get();
21158 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
21159 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
21160 return res ? result : basic_json(value_t::discarded);
21161 }
21162
21165 template<typename InputType>
21167 static basic_json from_msgpack(InputType&& i,
21168 const bool strict = true,
21169 const bool allow_exceptions = true)
21170 {
21171 basic_json result;
21172 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21173 auto ia = detail::input_adapter(std::forward<InputType>(i));
21174 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
21175 return res ? result : basic_json(value_t::discarded);
21176 }
21177
21180 template<typename IteratorType>
21182 static basic_json from_msgpack(IteratorType first, IteratorType last,
21183 const bool strict = true,
21184 const bool allow_exceptions = true)
21185 {
21186 basic_json result;
21187 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21188 auto ia = detail::input_adapter(std::move(first), std::move(last));
21189 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
21190 return res ? result : basic_json(value_t::discarded);
21191 }
21192
21193 template<typename T>
21195 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
21196 static basic_json from_msgpack(const T* ptr, std::size_t len,
21197 const bool strict = true,
21198 const bool allow_exceptions = true)
21199 {
21200 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
21201 }
21202
21204 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
21205 static basic_json from_msgpack(detail::span_input_adapter&& i,
21206 const bool strict = true,
21207 const bool allow_exceptions = true)
21208 {
21209 basic_json result;
21210 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21211 auto ia = i.get();
21212 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
21213 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
21214 return res ? result : basic_json(value_t::discarded);
21215 }
21216
21219 template<typename InputType>
21221 static basic_json from_ubjson(InputType&& i,
21222 const bool strict = true,
21223 const bool allow_exceptions = true)
21224 {
21225 basic_json result;
21226 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21227 auto ia = detail::input_adapter(std::forward<InputType>(i));
21228 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
21229 return res ? result : basic_json(value_t::discarded);
21230 }
21231
21234 template<typename IteratorType>
21236 static basic_json from_ubjson(IteratorType first, IteratorType last,
21237 const bool strict = true,
21238 const bool allow_exceptions = true)
21239 {
21240 basic_json result;
21241 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21242 auto ia = detail::input_adapter(std::move(first), std::move(last));
21243 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
21244 return res ? result : basic_json(value_t::discarded);
21245 }
21246
21247 template<typename T>
21249 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
21250 static basic_json from_ubjson(const T* ptr, std::size_t len,
21251 const bool strict = true,
21252 const bool allow_exceptions = true)
21253 {
21254 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
21255 }
21256
21258 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
21259 static basic_json from_ubjson(detail::span_input_adapter&& i,
21260 const bool strict = true,
21261 const bool allow_exceptions = true)
21262 {
21263 basic_json result;
21264 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21265 auto ia = i.get();
21266 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
21267 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
21268 return res ? result : basic_json(value_t::discarded);
21269 }
21270
21273 template<typename InputType>
21275 static basic_json from_bson(InputType&& i,
21276 const bool strict = true,
21277 const bool allow_exceptions = true)
21278 {
21279 basic_json result;
21280 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21281 auto ia = detail::input_adapter(std::forward<InputType>(i));
21282 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
21283 return res ? result : basic_json(value_t::discarded);
21284 }
21285
21288 template<typename IteratorType>
21290 static basic_json from_bson(IteratorType first, IteratorType last,
21291 const bool strict = true,
21292 const bool allow_exceptions = true)
21293 {
21294 basic_json result;
21295 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21296 auto ia = detail::input_adapter(std::move(first), std::move(last));
21297 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
21298 return res ? result : basic_json(value_t::discarded);
21299 }
21300
21301 template<typename T>
21303 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
21304 static basic_json from_bson(const T* ptr, std::size_t len,
21305 const bool strict = true,
21306 const bool allow_exceptions = true)
21307 {
21308 return from_bson(ptr, ptr + len, strict, allow_exceptions);
21309 }
21310
21312 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
21313 static basic_json from_bson(detail::span_input_adapter&& i,
21314 const bool strict = true,
21315 const bool allow_exceptions = true)
21316 {
21317 basic_json result;
21318 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
21319 auto ia = i.get();
21320 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
21321 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
21322 return res ? result : basic_json(value_t::discarded);
21323 }
21325
21327 // JSON Pointer support //
21329
21332
21336 {
21337 return ptr.get_unchecked(this);
21338 }
21339
21343 {
21344 return ptr.get_unchecked(this);
21345 }
21346
21350 {
21351 return ptr.get_checked(this);
21352 }
21353
21357 {
21358 return ptr.get_checked(this);
21359 }
21360
21364 {
21365 basic_json result(value_t::object);
21366 json_pointer::flatten("", *this, result);
21367 return result;
21368 }
21369
21373 {
21374 return json_pointer::unflatten(*this);
21375 }
21376
21378
21380 // JSON Patch functions //
21382
21385
21388 basic_json patch(const basic_json& json_patch) const
21389 {
21390 // make a working copy to apply the patch to
21391 basic_json result = *this;
21392
21393 // the valid JSON Patch operations
21394 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
21395
21396 const auto get_op = [](const std::string & op)
21397 {
21398 if (op == "add")
21399 {
21400 return patch_operations::add;
21401 }
21402 if (op == "remove")
21403 {
21404 return patch_operations::remove;
21405 }
21406 if (op == "replace")
21407 {
21408 return patch_operations::replace;
21409 }
21410 if (op == "move")
21411 {
21412 return patch_operations::move;
21413 }
21414 if (op == "copy")
21415 {
21416 return patch_operations::copy;
21417 }
21418 if (op == "test")
21419 {
21420 return patch_operations::test;
21421 }
21422
21423 return patch_operations::invalid;
21424 };
21425
21426 // wrapper for "add" operation; add value at ptr
21427 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
21428 {
21429 // adding to the root of the target document means replacing it
21430 if (ptr.empty())
21431 {
21432 result = val;
21433 return;
21434 }
21435
21436 // make sure the top element of the pointer exists
21437 json_pointer top_pointer = ptr.top();
21438 if (top_pointer != ptr)
21439 {
21440 result.at(top_pointer);
21441 }
21442
21443 // get reference to parent of JSON pointer ptr
21444 const auto last_path = ptr.back();
21445 ptr.pop_back();
21446 basic_json& parent = result[ptr];
21447
21448 switch (parent.m_type)
21449 {
21450 case value_t::null:
21451 case value_t::object:
21452 {
21453 // use operator[] to add value
21454 parent[last_path] = val;
21455 break;
21456 }
21457
21458 case value_t::array:
21459 {
21460 if (last_path == "-")
21461 {
21462 // special case: append to back
21463 parent.push_back(val);
21464 }
21465 else
21466 {
21467 const auto idx = json_pointer::array_index(last_path);
21468 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
21469 {
21470 // avoid undefined behavior
21471 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
21472 }
21473
21474 // default case: insert add offset
21475 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
21476 }
21477 break;
21478 }
21479
21480 // if there exists a parent it cannot be primitive
21481 case value_t::string: // LCOV_EXCL_LINE
21482 case value_t::boolean: // LCOV_EXCL_LINE
21483 case value_t::number_integer: // LCOV_EXCL_LINE
21484 case value_t::number_unsigned: // LCOV_EXCL_LINE
21485 case value_t::number_float: // LCOV_EXCL_LINE
21486 case value_t::binary: // LCOV_EXCL_LINE
21487 case value_t::discarded: // LCOV_EXCL_LINE
21488 default: // LCOV_EXCL_LINE
21489 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
21490 }
21491 };
21492
21493 // wrapper for "remove" operation; remove value at ptr
21494 const auto operation_remove = [this, &result](json_pointer & ptr)
21495 {
21496 // get reference to parent of JSON pointer ptr
21497 const auto last_path = ptr.back();
21498 ptr.pop_back();
21499 basic_json& parent = result.at(ptr);
21500
21501 // remove child
21502 if (parent.is_object())
21503 {
21504 // perform range check
21505 auto it = parent.find(last_path);
21506 if (JSON_HEDLEY_LIKELY(it != parent.end()))
21507 {
21508 parent.erase(it);
21509 }
21510 else
21511 {
21512 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
21513 }
21514 }
21515 else if (parent.is_array())
21516 {
21517 // note erase performs range check
21518 parent.erase(json_pointer::array_index(last_path));
21519 }
21520 };
21521
21522 // type check: top level value must be an array
21523 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
21524 {
21525 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
21526 }
21527
21528 // iterate and apply the operations
21529 for (const auto& val : json_patch)
21530 {
21531 // wrapper to get a value for an operation
21532 const auto get_value = [&val](const std::string & op,
21533 const std::string & member,
21534 bool string_type) -> basic_json &
21535 {
21536 // find value
21537 auto it = val.m_value.object->find(member);
21538
21539 // context-sensitive error message
21540 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
21541
21542 // check if desired value is present
21543 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
21544 {
21545 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
21546 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
21547 }
21548
21549 // check if result is of type string
21550 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
21551 {
21552 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
21553 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
21554 }
21555
21556 // no error: return value
21557 return it->second;
21558 };
21559
21560 // type check: every element of the array must be an object
21561 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
21562 {
21563 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
21564 }
21565
21566 // collect mandatory members
21567 const auto op = get_value("op", "op", true).template get<std::string>();
21568 const auto path = get_value(op, "path", true).template get<std::string>();
21569 json_pointer ptr(path);
21570
21571 switch (get_op(op))
21572 {
21573 case patch_operations::add:
21574 {
21575 operation_add(ptr, get_value("add", "value", false));
21576 break;
21577 }
21578
21579 case patch_operations::remove:
21580 {
21581 operation_remove(ptr);
21582 break;
21583 }
21584
21585 case patch_operations::replace:
21586 {
21587 // the "path" location must exist - use at()
21588 result.at(ptr) = get_value("replace", "value", false);
21589 break;
21590 }
21591
21592 case patch_operations::move:
21593 {
21594 const auto from_path = get_value("move", "from", true).template get<std::string>();
21595 json_pointer from_ptr(from_path);
21596
21597 // the "from" location must exist - use at()
21598 basic_json v = result.at(from_ptr);
21599
21600 // The move operation is functionally identical to a
21601 // "remove" operation on the "from" location, followed
21602 // immediately by an "add" operation at the target
21603 // location with the value that was just removed.
21604 operation_remove(from_ptr);
21605 operation_add(ptr, v);
21606 break;
21607 }
21608
21609 case patch_operations::copy:
21610 {
21611 const auto from_path = get_value("copy", "from", true).template get<std::string>();
21612 const json_pointer from_ptr(from_path);
21613
21614 // the "from" location must exist - use at()
21615 basic_json v = result.at(from_ptr);
21616
21617 // The copy is functionally identical to an "add"
21618 // operation at the target location using the value
21619 // specified in the "from" member.
21620 operation_add(ptr, v);
21621 break;
21622 }
21623
21624 case patch_operations::test:
21625 {
21626 bool success = false;
21627 JSON_TRY
21628 {
21629 // check if "value" matches the one at "path"
21630 // the "path" location must exist - use at()
21631 success = (result.at(ptr) == get_value("test", "value", false));
21632 }
21634 {
21635 // ignore out of range errors: success remains false
21636 }
21637
21638 // throw an exception if test fails
21639 if (JSON_HEDLEY_UNLIKELY(!success))
21640 {
21641 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
21642 }
21643
21644 break;
21645 }
21646
21647 case patch_operations::invalid:
21648 default:
21649 {
21650 // op must be "add", "remove", "replace", "move", "copy", or
21651 // "test"
21652 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
21653 }
21654 }
21655 }
21656
21657 return result;
21658 }
21659
21663 static basic_json diff(const basic_json& source, const basic_json& target,
21664 const std::string& path = "")
21665 {
21666 // the patch
21667 basic_json result(value_t::array);
21668
21669 // if the values are the same, return empty patch
21670 if (source == target)
21671 {
21672 return result;
21673 }
21674
21675 if (source.type() != target.type())
21676 {
21677 // different types: replace value
21678 result.push_back(
21679 {
21680 {"op", "replace"}, {"path", path}, {"value", target}
21681 });
21682 return result;
21683 }
21684
21685 switch (source.type())
21686 {
21687 case value_t::array:
21688 {
21689 // first pass: traverse common elements
21690 std::size_t i = 0;
21691 while (i < source.size() && i < target.size())
21692 {
21693 // recursive call to compare array values at index i
21694 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
21695 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
21696 ++i;
21697 }
21698
21699 // We now reached the end of at least one array
21700 // in a second pass, traverse the remaining elements
21701
21702 // remove my remaining elements
21703 const auto end_index = static_cast<difference_type>(result.size());
21704 while (i < source.size())
21705 {
21706 // add operations in reverse order to avoid invalid
21707 // indices
21708 result.insert(result.begin() + end_index, object(
21709 {
21710 {"op", "remove"},
21711 {"path", path + "/" + std::to_string(i)}
21712 }));
21713 ++i;
21714 }
21715
21716 // add other remaining elements
21717 while (i < target.size())
21718 {
21719 result.push_back(
21720 {
21721 {"op", "add"},
21722 {"path", path + "/-"},
21723 {"value", target[i]}
21724 });
21725 ++i;
21726 }
21727
21728 break;
21729 }
21730
21731 case value_t::object:
21732 {
21733 // first pass: traverse this object's elements
21734 for (auto it = source.cbegin(); it != source.cend(); ++it)
21735 {
21736 // escape the key name to be used in a JSON patch
21737 const auto path_key = path + "/" + detail::escape(it.key());
21738
21739 if (target.find(it.key()) != target.end())
21740 {
21741 // recursive call to compare object values at key it
21742 auto temp_diff = diff(it.value(), target[it.key()], path_key);
21743 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
21744 }
21745 else
21746 {
21747 // found a key that is not in o -> remove it
21748 result.push_back(object(
21749 {
21750 {"op", "remove"}, {"path", path_key}
21751 }));
21752 }
21753 }
21754
21755 // second pass: traverse other object's elements
21756 for (auto it = target.cbegin(); it != target.cend(); ++it)
21757 {
21758 if (source.find(it.key()) == source.end())
21759 {
21760 // found a key that is not in this -> add it
21761 const auto path_key = path + "/" + detail::escape(it.key());
21762 result.push_back(
21763 {
21764 {"op", "add"}, {"path", path_key},
21765 {"value", it.value()}
21766 });
21767 }
21768 }
21769
21770 break;
21771 }
21772
21773 case value_t::null:
21774 case value_t::string:
21775 case value_t::boolean:
21776 case value_t::number_integer:
21777 case value_t::number_unsigned:
21778 case value_t::number_float:
21779 case value_t::binary:
21780 case value_t::discarded:
21781 default:
21782 {
21783 // both primitive type: replace value
21784 result.push_back(
21785 {
21786 {"op", "replace"}, {"path", path}, {"value", target}
21787 });
21788 break;
21789 }
21790 }
21791
21792 return result;
21793 }
21794
21796
21798 // JSON Merge Patch functions //
21800
21803
21806 void merge_patch(const basic_json& apply_patch)
21807 {
21808 if (apply_patch.is_object())
21809 {
21810 if (!is_object())
21811 {
21812 *this = object();
21813 }
21814 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
21815 {
21816 if (it.value().is_null())
21817 {
21818 erase(it.key());
21819 }
21820 else
21821 {
21822 operator[](it.key()).merge_patch(it.value());
21823 }
21824 }
21825 }
21826 else
21827 {
21828 *this = apply_patch;
21829 }
21830 }
21831
21833};
21834
21839{
21840 return j.dump();
21841}
21842
21843} // namespace nlohmann
21844
21846// nonmember support //
21848
21849namespace std // NOLINT(cert-dcl58-cpp)
21850{
21851
21856{
21857 std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
21858 {
21859 return nlohmann::detail::hash(j);
21860 }
21861};
21862
21863// specialization for std::less<value_t>
21864template<>
21865struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
21866{
21872 nlohmann::detail::value_t rhs) const noexcept
21873 {
21874 return nlohmann::detail::operator<(lhs, rhs);
21875 }
21876};
21877
21878// C++20 prohibit function specialization in the std namespace.
21879#ifndef JSON_HAS_CPP_20
21880
21884inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
21885 is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
21886 is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
21887{
21888 j1.swap(j2);
21889}
21890
21891#endif
21892
21893} // namespace std
21894
21898inline nlohmann::json operator "" _json(const char* s, std::size_t n)
21899{
21900 return nlohmann::json::parse(s, s + n);
21901}
21902
21906inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
21907{
21908 return nlohmann::json::json_pointer(std::string(s, n));
21909}
21910
21911// #include <nlohmann/detail/macro_unscope.hpp>
21912
21913
21914// restore clang diagnostic settings
21915#if defined(__clang__)
21916 #pragma clang diagnostic pop
21917#endif
21918
21919// clean up
21920#undef JSON_ASSERT
21921#undef JSON_INTERNAL_CATCH
21922#undef JSON_CATCH
21923#undef JSON_THROW
21924#undef JSON_TRY
21925#undef JSON_PRIVATE_UNLESS_TESTED
21926#undef JSON_HAS_CPP_11
21927#undef JSON_HAS_CPP_14
21928#undef JSON_HAS_CPP_17
21929#undef JSON_HAS_CPP_20
21930#undef JSON_HAS_FILESYSTEM
21931#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
21932#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
21933#undef NLOHMANN_BASIC_JSON_TPL
21934#undef JSON_EXPLICIT
21935#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
21936
21937// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
21938
21939
21940#undef JSON_HEDLEY_ALWAYS_INLINE
21941#undef JSON_HEDLEY_ARM_VERSION
21942#undef JSON_HEDLEY_ARM_VERSION_CHECK
21943#undef JSON_HEDLEY_ARRAY_PARAM
21944#undef JSON_HEDLEY_ASSUME
21945#undef JSON_HEDLEY_BEGIN_C_DECLS
21946#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
21947#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
21948#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
21949#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
21950#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
21951#undef JSON_HEDLEY_CLANG_HAS_FEATURE
21952#undef JSON_HEDLEY_CLANG_HAS_WARNING
21953#undef JSON_HEDLEY_COMPCERT_VERSION
21954#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
21955#undef JSON_HEDLEY_CONCAT
21956#undef JSON_HEDLEY_CONCAT3
21957#undef JSON_HEDLEY_CONCAT3_EX
21958#undef JSON_HEDLEY_CONCAT_EX
21959#undef JSON_HEDLEY_CONST
21960#undef JSON_HEDLEY_CONSTEXPR
21961#undef JSON_HEDLEY_CONST_CAST
21962#undef JSON_HEDLEY_CPP_CAST
21963#undef JSON_HEDLEY_CRAY_VERSION
21964#undef JSON_HEDLEY_CRAY_VERSION_CHECK
21965#undef JSON_HEDLEY_C_DECL
21966#undef JSON_HEDLEY_DEPRECATED
21967#undef JSON_HEDLEY_DEPRECATED_FOR
21968#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
21969#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
21970#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
21971#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
21972#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
21973#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
21974#undef JSON_HEDLEY_DIAGNOSTIC_POP
21975#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
21976#undef JSON_HEDLEY_DMC_VERSION
21977#undef JSON_HEDLEY_DMC_VERSION_CHECK
21978#undef JSON_HEDLEY_EMPTY_BASES
21979#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
21980#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
21981#undef JSON_HEDLEY_END_C_DECLS
21982#undef JSON_HEDLEY_FLAGS
21983#undef JSON_HEDLEY_FLAGS_CAST
21984#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
21985#undef JSON_HEDLEY_GCC_HAS_BUILTIN
21986#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
21987#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
21988#undef JSON_HEDLEY_GCC_HAS_EXTENSION
21989#undef JSON_HEDLEY_GCC_HAS_FEATURE
21990#undef JSON_HEDLEY_GCC_HAS_WARNING
21991#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
21992#undef JSON_HEDLEY_GCC_VERSION
21993#undef JSON_HEDLEY_GCC_VERSION_CHECK
21994#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
21995#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
21996#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
21997#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
21998#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
21999#undef JSON_HEDLEY_GNUC_HAS_FEATURE
22000#undef JSON_HEDLEY_GNUC_HAS_WARNING
22001#undef JSON_HEDLEY_GNUC_VERSION
22002#undef JSON_HEDLEY_GNUC_VERSION_CHECK
22003#undef JSON_HEDLEY_HAS_ATTRIBUTE
22004#undef JSON_HEDLEY_HAS_BUILTIN
22005#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
22006#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
22007#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
22008#undef JSON_HEDLEY_HAS_EXTENSION
22009#undef JSON_HEDLEY_HAS_FEATURE
22010#undef JSON_HEDLEY_HAS_WARNING
22011#undef JSON_HEDLEY_IAR_VERSION
22012#undef JSON_HEDLEY_IAR_VERSION_CHECK
22013#undef JSON_HEDLEY_IBM_VERSION
22014#undef JSON_HEDLEY_IBM_VERSION_CHECK
22015#undef JSON_HEDLEY_IMPORT
22016#undef JSON_HEDLEY_INLINE
22017#undef JSON_HEDLEY_INTEL_CL_VERSION
22018#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
22019#undef JSON_HEDLEY_INTEL_VERSION
22020#undef JSON_HEDLEY_INTEL_VERSION_CHECK
22021#undef JSON_HEDLEY_IS_CONSTANT
22022#undef JSON_HEDLEY_IS_CONSTEXPR_
22023#undef JSON_HEDLEY_LIKELY
22024#undef JSON_HEDLEY_MALLOC
22025#undef JSON_HEDLEY_MCST_LCC_VERSION
22026#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
22027#undef JSON_HEDLEY_MESSAGE
22028#undef JSON_HEDLEY_MSVC_VERSION
22029#undef JSON_HEDLEY_MSVC_VERSION_CHECK
22030#undef JSON_HEDLEY_NEVER_INLINE
22031#undef JSON_HEDLEY_NON_NULL
22032#undef JSON_HEDLEY_NO_ESCAPE
22033#undef JSON_HEDLEY_NO_RETURN
22034#undef JSON_HEDLEY_NO_THROW
22035#undef JSON_HEDLEY_NULL
22036#undef JSON_HEDLEY_PELLES_VERSION
22037#undef JSON_HEDLEY_PELLES_VERSION_CHECK
22038#undef JSON_HEDLEY_PGI_VERSION
22039#undef JSON_HEDLEY_PGI_VERSION_CHECK
22040#undef JSON_HEDLEY_PREDICT
22041#undef JSON_HEDLEY_PRINTF_FORMAT
22042#undef JSON_HEDLEY_PRIVATE
22043#undef JSON_HEDLEY_PUBLIC
22044#undef JSON_HEDLEY_PURE
22045#undef JSON_HEDLEY_REINTERPRET_CAST
22046#undef JSON_HEDLEY_REQUIRE
22047#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
22048#undef JSON_HEDLEY_REQUIRE_MSG
22049#undef JSON_HEDLEY_RESTRICT
22050#undef JSON_HEDLEY_RETURNS_NON_NULL
22051#undef JSON_HEDLEY_SENTINEL
22052#undef JSON_HEDLEY_STATIC_ASSERT
22053#undef JSON_HEDLEY_STATIC_CAST
22054#undef JSON_HEDLEY_STRINGIFY
22055#undef JSON_HEDLEY_STRINGIFY_EX
22056#undef JSON_HEDLEY_SUNPRO_VERSION
22057#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
22058#undef JSON_HEDLEY_TINYC_VERSION
22059#undef JSON_HEDLEY_TINYC_VERSION_CHECK
22060#undef JSON_HEDLEY_TI_ARMCL_VERSION
22061#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
22062#undef JSON_HEDLEY_TI_CL2000_VERSION
22063#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
22064#undef JSON_HEDLEY_TI_CL430_VERSION
22065#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
22066#undef JSON_HEDLEY_TI_CL6X_VERSION
22067#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
22068#undef JSON_HEDLEY_TI_CL7X_VERSION
22069#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
22070#undef JSON_HEDLEY_TI_CLPRU_VERSION
22071#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
22072#undef JSON_HEDLEY_TI_VERSION
22073#undef JSON_HEDLEY_TI_VERSION_CHECK
22074#undef JSON_HEDLEY_UNAVAILABLE
22075#undef JSON_HEDLEY_UNLIKELY
22076#undef JSON_HEDLEY_UNPREDICTABLE
22077#undef JSON_HEDLEY_UNREACHABLE
22078#undef JSON_HEDLEY_UNREACHABLE_RETURN
22079#undef JSON_HEDLEY_VERSION
22080#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
22081#undef JSON_HEDLEY_VERSION_DECODE_MINOR
22082#undef JSON_HEDLEY_VERSION_DECODE_REVISION
22083#undef JSON_HEDLEY_VERSION_ENCODE
22084#undef JSON_HEDLEY_WARNING
22085#undef JSON_HEDLEY_WARN_UNUSED_RESULT
22086#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
22087#undef JSON_HEDLEY_FALL_THROUGH
22088
22089
22090
22091#endif // INCLUDE_NLOHMANN_JSON_HPP_
a class to store JSON values
Definition json.hpp:17282
ValueType & get_to(ValueType &v) const
Definition json.hpp:18965
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition json.hpp:20281
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition json.hpp:18582
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition json.hpp:17960
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition json.hpp:19640
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition json.hpp:19779
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition json.hpp:19742
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
Definition json.hpp:18636
number_unsigned_t number_unsigned
number (unsigned integer)
Definition json.hpp:17606
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition json.hpp:21342
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition json.hpp:21335
friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
comparison: equal
Definition json.hpp:20554
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition json.hpp:19319
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition json.hpp:18504
NumberIntegerType number_integer_t
a type for a number (integer)
Definition json.hpp:17525
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition json.hpp:20474
NLOHMANN_BASIC_JSON_TPL basic_json_t
workaround type for MSVC
Definition json.hpp:17303
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition json.hpp:20306
static bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
generate SAX events
Definition json.hpp:20881
ReferenceType get_ref()
get a reference value (implicit)
Definition json.hpp:18988
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition json.hpp:20814
reference emplace_back(Args &&... args)
add an object to an array
Definition json.hpp:20107
const_iterator find(KeyT &&key) const
find an element in a JSON object
Definition json.hpp:19615
basic_json(const value_t v)
create an empty value with a given type
Definition json.hpp:17973
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition json.hpp:18570
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition json.hpp:19881
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition json.hpp:21663
static std::vector< std::uint8_t > to_bson(const basic_json &j)
create a BSON serialization of a given JSON value
Definition json.hpp:21083
void erase(const size_type idx)
remove element from a JSON array given an index
Definition json.hpp:19569
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition json.hpp:19749
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition json.hpp:19159
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition json.hpp:19136
iterator begin() noexcept
returns an iterator to the first element
Definition json.hpp:19664
binary_t & get_binary()
get a binary value
Definition json.hpp:19055
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition json.hpp:18187
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition json.hpp:21033
friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition json.hpp:20563
json_value(object_t &&value)
constructor for rvalue objects
Definition json.hpp:17702
basic_json(const JsonRef &ref)
Definition json.hpp:18297
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition json.hpp:21010
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition json.hpp:18386
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition json.hpp:18159
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition json.hpp:17619
const_reverse_iterator rend() const noexcept
returns an iterator to the reverse-end
Definition json.hpp:19735
void assert_invariant(bool check_parents=true) const noexcept
checks the class invariants
Definition json.hpp:17840
json_value(string_t &&value)
constructor for rvalue strings
Definition json.hpp:17696
const_iterator cend() const noexcept
returns an iterator to one past the last element
Definition json.hpp:19705
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition json.hpp:17615
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition json.hpp:18630
reference back()
access the last element
Definition json.hpp:19393
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition json.hpp:18606
const binary_t & get_binary() const
get a binary value
Definition json.hpp:19067
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition json.hpp:18612
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition json.hpp:20854
StringType string_t
a type for a string
Definition json.hpp:17517
size_type size() const noexcept
returns the number of elements
Definition json.hpp:19842
void push_back(const basic_json &val)
add an object to an array
Definition json.hpp:20019
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition json.hpp:17428
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition json.hpp:19349
std::size_t size_type
a type to represent container sizes
Definition json.hpp:17396
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition json.hpp:18952
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition json.hpp:17394
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition json.hpp:18115
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition json.hpp:19241
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition json.hpp:17617
reference operator+=(basic_json &&val)
add an object to an array
Definition json.hpp:20011
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition json.hpp:18007
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition json.hpp:17404
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition json.hpp:21290
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition json.hpp:17402
constexpr const binary_t * get_impl_ptr(const binary_t *) const noexcept
get a pointer to the value (binary)
Definition json.hpp:18660
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition json.hpp:21108
BooleanType boolean_t
a type for a boolean
Definition json.hpp:17521
iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
Definition json.hpp:17898
void push_back(initializer_list_t init)
add an object to an object
Definition json.hpp:20082
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition json.hpp:18559
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition json.hpp:18426
static bool accept(IteratorType first, IteratorType last, const bool ignore_comments=false)
check if the input is valid JSON
Definition json.hpp:20863
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition json.hpp:19415
static void to_bson(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a BSON serialization of a given JSON value
Definition json.hpp:21092
friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
comparison: not equal
Definition json.hpp:20579
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BSON format
Definition json.hpp:21275
constexpr bool is_structured() const noexcept
return whether type is structured
Definition json.hpp:18462
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition json.hpp:20707
const_iterator begin() const noexcept
returns an iterator to the first element
Definition json.hpp:19673
void update(const_iterator first, const_iterator last, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition json.hpp:20313
friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
comparison: less than
Definition json.hpp:20673
reference at(size_type idx)
access specified array element with bounds checking
Definition json.hpp:19090
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition json.hpp:18148
reference front()
access the first element
Definition json.hpp:19379
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition json.hpp:18455
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition json.hpp:18497
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
create a CBOR serialization of a given JSON value
Definition json.hpp:21026
void swap(object_t &other)
exchanges the values
Definition json.hpp:20404
constexpr bool is_object() const noexcept
return whether value is an object
Definition json.hpp:18511
const_reference front() const
access the first element
Definition json.hpp:19386
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition json.hpp:18448
NumberFloatType number_float_t
a type for a number (floating-point)
Definition json.hpp:17533
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition json.hpp:17411
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition json.hpp:20773
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition json.hpp:20689
bool empty() const noexcept
checks whether the container is empty.
Definition json.hpp:19803
json_value(value_t t)
constructor for empty values of a given type
Definition json.hpp:17621
basic_json(const basic_json &other)
copy constructor
Definition json.hpp:18301
~basic_json() noexcept
destructor
Definition json.hpp:18407
static std::vector< std::uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition json.hpp:21056
basic_json(basic_json &&other) noexcept
move constructor
Definition json.hpp:18369
friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition json.hpp:20732
reference set_parent(reference j, std::size_t old_capacity=static_cast< std::size_t >(-1))
Definition json.hpp:17911
BasicJsonType get_impl(detail::priority_tag< 2 >) const
get special-case overload
Definition json.hpp:18827
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition json.hpp:21075
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition json.hpp:20570
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition json.hpp:20210
friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition json.hpp:20682
json_value m_value
the value of the current element
Definition json.hpp:20993
boolean_t boolean
boolean
Definition json.hpp:17602
void swap(typename binary_t::container_type &other)
exchanges the values
Definition json.hpp:20449
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition json.hpp:20739
void swap(array_t &other)
exchanges the values
Definition json.hpp:20389
ValueType get_impl(detail::priority_tag< 0 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
Definition json.hpp:18760
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition json.hpp:19728
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition json.hpp:18126
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition json.hpp:19761
json_value(const string_t &value)
constructor for strings
Definition json.hpp:17693
json_value(const binary_t &value)
constructor for binary arrays (internal type)
Definition json.hpp:17717
ReferenceType get_ref() const
get a reference value (implicit)
Definition json.hpp:18999
json_value(const array_t &value)
constructor for arrays
Definition json.hpp:17705
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition json.hpp:20230
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition json.hpp:18939
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition json.hpp:21356
const_iterator end() const noexcept
returns an iterator to one past the last element
Definition json.hpp:19698
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition json.hpp:21806
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition json.hpp:18699
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition json.hpp:19786
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition json.hpp:20261
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition json.hpp:17513
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition json.hpp:18976
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition json.hpp:20714
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
Definition json.hpp:18624
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition json.hpp:18600
void destroy(value_t t)
Definition json.hpp:17722
json_value(const object_t &value)
constructor for objects
Definition json.hpp:17699
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition json.hpp:19486
json_value(typename binary_t::container_type &&value)
constructor for rvalue binary arrays
Definition json.hpp:17714
json_value(boolean_t v) noexcept
constructor for booleans
Definition json.hpp:17613
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition json.hpp:18476
iterator end() noexcept
returns an iterator to one past the last element
Definition json.hpp:19689
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition json.hpp:20360
void clear() noexcept
clears the contents
Definition json.hpp:19925
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition json.hpp:20757
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition json.hpp:21182
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition json.hpp:18532
static JSON_HEDLEY_RETURNS_NON_NULL T * create(Args &&... args)
helper for exception-safe object creation
Definition json.hpp:17546
binary_t * binary
binary (stored with pointer to save storage)
Definition json.hpp:17600
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition json.hpp:18167
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition json.hpp:20203
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition json.hpp:21236
reference operator[](size_type idx)
access specified array element
Definition json.hpp:19182
friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than
Definition json.hpp:20723
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
create a BSON serialization of a given JSON value
Definition json.hpp:21099
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition json.hpp:21349
void swap(binary_t &other)
exchanges the values
Definition json.hpp:20434
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition json.hpp:17413
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition json.hpp:21221
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition json.hpp:17344
friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition json.hpp:20588
static void to_ubjson(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition json.hpp:21067
const_reverse_iterator rbegin() const noexcept
returns an iterator to the reverse-beginning
Definition json.hpp:19721
void swap(string_t &other)
exchanges the values
Definition json.hpp:20419
const_reference back() const
access the last element
Definition json.hpp:19402
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition json.hpp:20595
ValueType get_impl(detail::priority_tag< 1 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >())))
get a value (explicit); special case
Definition json.hpp:18802
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array
Definition json.hpp:18137
constexpr bool is_string() const noexcept
return whether value is a string
Definition json.hpp:18525
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition json.hpp:18618
constexpr bool is_array() const noexcept
return whether value is an array
Definition json.hpp:18518
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition json.hpp:20164
basic_json flatten() const
return flattened JSON value
Definition json.hpp:21363
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
Definition json.hpp:18648
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition json.hpp:18588
friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than or equal
Definition json.hpp:20748
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition json.hpp:20957
void push_back(basic_json &&val)
add an object to an array
Definition json.hpp:19986
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition json.hpp:21124
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition json.hpp:19630
json_value(const typename binary_t::container_type &value)
constructor for binary arrays
Definition json.hpp:17711
json_value()=default
default constructor (for null values)
constexpr bool is_number() const noexcept
return whether value is a number
Definition json.hpp:18483
number_float_t number_float
number (floating-point)
Definition json.hpp:17608
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition json.hpp:18594
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition json.hpp:20795
std::less< StringType > object_comparator_t
object key comparator type
Definition json.hpp:17500
string_t * string
string (stored with pointer to save storage)
Definition json.hpp:17598
reference operator+=(initializer_list_t init)
add an object to an object
Definition json.hpp:20098
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
Definition json.hpp:17332
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition json.hpp:18490
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition json.hpp:17352
static void to_cbor(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a CBOR serialization of a given JSON value
Definition json.hpp:21019
detail::value_t value_t
Definition json.hpp:17342
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition json.hpp:18642
json_value(binary_t &&value)
constructor for rvalue binary arrays (internal type)
Definition json.hpp:17720
friend class ::nlohmann::detail::parser
Definition json.hpp:17288
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
create a MessagePack serialization of a given JSON value
Definition json.hpp:21049
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition json.hpp:19262
iterator find(KeyT &&key)
find an element in a JSON object
Definition json.hpp:19600
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition json.hpp:17981
const_reference operator[](size_type idx) const
access specified array element
Definition json.hpp:19228
array_t * array
array (stored with pointer to save storage)
Definition json.hpp:17596
AllocatorType< basic_json > allocator_type
the allocator type
Definition json.hpp:17399
basic_json get_impl(detail::priority_tag< 3 >) const
get special-case overload
Definition json.hpp:18850
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition json.hpp:17537
JSONSerializer< T, SFINAE > json_serializer
Definition json.hpp:17346
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition json.hpp:20051
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a pair of character iterators
Definition json.hpp:20828
number_integer_t number_integer
number (integer)
Definition json.hpp:17604
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition json.hpp:19647
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition json.hpp:21167
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition json.hpp:21388
string_t value(const typename object_t::key_type &key, const char *default_value) const
access specified object element with default value
Definition json.hpp:19340
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value from compatible types
Definition json.hpp:17993
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition json.hpp:21372
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition json.hpp:17529
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition json.hpp:20074
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition json.hpp:19680
friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
comparison: less than or equal
Definition json.hpp:20698
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition json.hpp:20942
static ::nlohmann::detail::parser< basic_json, InputAdapterType > parser(InputAdapterType adapter, detail::parser_callback_t< basic_json >cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
Definition json.hpp:17310
json_value(array_t &&value)
constructor for rvalue arrays
Definition json.hpp:17708
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition json.hpp:18059
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition json.hpp:19113
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition json.hpp:20183
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition json.hpp:18539
constexpr auto get_impl(detail::priority_tag< 4 >) const noexcept -> decltype(std::declval< const basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition json.hpp:18863
constexpr bool is_null() const noexcept
return whether value is null
Definition json.hpp:18469
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition json.hpp:20377
binary_t * get_impl_ptr(binary_t *) noexcept
get a pointer to the value (binary)
Definition json.hpp:18654
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > > > object_t
a type for an object
Definition json.hpp:17509
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
Definition json.hpp:18898
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition json.hpp:20132
static void to_msgpack(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a MessagePack serialization of a given JSON value
Definition json.hpp:21042
reference operator+=(const basic_json &val)
add an object to an array
Definition json.hpp:20043
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition json.hpp:19556
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition json.hpp:18677
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition json.hpp:18174
static allocator_type get_allocator()
returns the allocator associated with the container
Definition json.hpp:17420
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition json.hpp:18576
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition json.hpp:18710
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition json.hpp:19714
an internal type for a backed binary type
Definition json.hpp:4973
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition json.hpp:4994
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition json.hpp:4984
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition json.hpp:4989
bool operator!=(const byte_container_with_subtype &rhs) const
Definition json.hpp:5013
void clear_subtype() noexcept
clears the binary subtype
Definition json.hpp:5042
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition json.hpp:4979
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition json.hpp:5001
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition json.hpp:5035
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition json.hpp:5020
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition json.hpp:5028
bool operator==(const byte_container_with_subtype &rhs) const
Definition json.hpp:5007
deserialization of CBOR, MessagePack, and UBJSON values
Definition json.hpp:8230
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:8232
bool get_msgpack_array(const std::size_t len)
Definition json.hpp:9921
binary_reader & operator=(const binary_reader &)=delete
bool get_bson_string(const NumberType len, string_t &result)
Parses a zero-terminated string of length len from the BSON input.
Definition json.hpp:8384
bool parse_bson_element_internal(const char_int_type element_type, const std::size_t element_type_parse_position)
Read a BSON document element of the given element_type.
Definition json.hpp:8431
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
Definition json.hpp:8547
char_int_type get_ignore_noop()
Definition json.hpp:10494
binary_reader(InputAdapterType &&adapter) noexcept
create a binary reader
Definition json.hpp:8246
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:8231
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
Definition json.hpp:8354
bool get_cbor_array(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition json.hpp:9254
bool get_msgpack_binary(binary_t &result)
reads a MessagePack byte array
Definition json.hpp:9810
bool get_cbor_object(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition json.hpp:9292
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
Definition json.hpp:9999
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
Definition json.hpp:8509
bool parse_cbor_internal(const bool get_char, const cbor_tag_handler_t tag_handler)
Definition json.hpp:8577
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
Definition json.hpp:10562
bool get_cbor_string(string_t &result)
reads a CBOR string
Definition json.hpp:9065
InputAdapterType ia
input adapter
Definition json.hpp:10679
bool get_binary(const input_format_t format, const NumberType len, binary_t &result)
create a byte array by reading bytes from the input
Definition json.hpp:10595
bool parse_ubjson_internal(const bool get_char=true)
Definition json.hpp:9980
bool unexpect_eof(const input_format_t format, const char *context) const
Definition json.hpp:10619
binary_reader & operator=(binary_reader &&)=default
bool get_ubjson_size_type(std::pair< std::size_t, char_int_type > &result)
determine the type and size for a container
Definition json.hpp:10130
std::string get_token_string() const
Definition json.hpp:10632
bool get_ubjson_value(const char_int_type prefix)
Definition json.hpp:10171
typename BasicJsonType::string_t string_t
Definition json.hpp:8234
bool get_msgpack_object(const std::size_t len)
Definition json.hpp:9943
bool get_bson_binary(const NumberType len, binary_t &result)
Parses a byte array input of length len from the BSON input.
Definition json.hpp:8405
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
Definition json.hpp:10645
std::size_t chars_read
the number of characters read
Definition json.hpp:10685
typename std::char_traits< char_type >::int_type char_int_type
Definition json.hpp:8238
binary_reader(const binary_reader &)=delete
char_int_type current
the current character
Definition json.hpp:10682
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition json.hpp:8267
json_sax_t * sax
the SAX parser
Definition json.hpp:10691
bool get_ubjson_size_value(std::size_t &result)
Definition json.hpp:10053
typename InputAdapterType::char_type char_type
Definition json.hpp:8237
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
Definition json.hpp:8329
bool get_number(const input_format_t format, NumberType &result)
Definition json.hpp:10519
bool get_cbor_binary(binary_t &result)
reads a CBOR byte array
Definition json.hpp:9160
binary_reader(binary_reader &&)=default
typename BasicJsonType::binary_t binary_t
Definition json.hpp:8235
char_int_type get()
get next character from the input
Definition json.hpp:10485
const bool is_little_endian
whether we can assume little endianness
Definition json.hpp:10688
bool get_msgpack_string(string_t &result)
reads a MessagePack string
Definition json.hpp:9728
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:8233
serialization to CBOR and MessagePack values
Definition json.hpp:13315
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
Definition json.hpp:14391
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix)
Definition json.hpp:14582
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition json.hpp:14013
static std::size_t calc_bson_entry_header_size(const string_t &name, const BasicJsonType &j)
Definition json.hpp:14221
static constexpr CharType get_ubjson_float_prefix(double)
Definition json.hpp:14808
void write_bson_entry_header(const string_t &name, const std::uint8_t element_type)
Writes the given element_type and name to the output adapter.
Definition json.hpp:14236
static std::size_t calc_bson_element_size(const string_t &name, const BasicJsonType &j)
Calculates the size necessary to serialize the JSON value j with its name.
Definition json.hpp:14425
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
Definition json.hpp:14258
void write_bson_object(const typename BasicJsonType::object_t &value)
Definition json.hpp:14535
typename BasicJsonType::string_t string_t
Definition json.hpp:13316
static constexpr CharType get_cbor_float_prefix(float)
Definition json.hpp:14551
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition json.hpp:14908
typename BasicJsonType::binary_t binary_t
Definition json.hpp:13317
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition json.hpp:13326
static constexpr CharType get_msgpack_float_prefix(double)
Definition json.hpp:14570
CharType ubjson_prefix(const BasicJsonType &j) const noexcept
determine the type prefix of container values
Definition json.hpp:14722
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
Definition json.hpp:14308
static CharType to_char_type(std::uint8_t x) noexcept
Definition json.hpp:14886
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
Definition json.hpp:14276
void write_bson_object_entry(const string_t &name, const typename BasicJsonType::object_t &value)
Writes a BSON element with key name and object value.
Definition json.hpp:14358
static constexpr CharType get_ubjson_float_prefix(float)
Definition json.hpp:14803
void write_number(const NumberType n)
Definition json.hpp:14829
void write_bson_element(const string_t &name, const BasicJsonType &j)
Serializes the JSON value j to BSON and associates it with the key name.
Definition json.hpp:14473
void write_bson_binary(const string_t &name, const binary_t &value)
Writes a BSON element with key name and binary value value.
Definition json.hpp:14410
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
Definition json.hpp:14290
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t &value)
Definition json.hpp:14383
void write_bson(const BasicJsonType &j)
Definition json.hpp:13335
void write_cbor(const BasicJsonType &j)
Definition json.hpp:13364
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
Definition json.hpp:14326
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition json.hpp:14879
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:13318
void write_bson_unsigned(const string_t &name, const BasicJsonType &j)
Writes a BSON element with key name and unsigned value.
Definition json.hpp:14336
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
Calculates the size of the BSON serialization of the given JSON-object j.
Definition json.hpp:14520
static constexpr CharType get_msgpack_float_prefix(float)
Definition json.hpp:14565
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
Definition json.hpp:14248
void write_msgpack(const BasicJsonType &j)
Definition json.hpp:13688
void write_compact_float(const number_float_t n, detail::input_format_t format)
Definition json.hpp:14845
static std::size_t calc_bson_string_size(const string_t &value)
Definition json.hpp:14268
static std::size_t calc_bson_integer_size(const std::int64_t value)
Definition json.hpp:14298
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
Definition json.hpp:14368
static constexpr CharType get_cbor_float_prefix(double)
Definition json.hpp:14556
general exception of the basic_json class
Definition json.hpp:2809
const int id
the id of the exception
Definition json.hpp:2818
static std::string diagnostics(const BasicJsonType &leaf_element)
Definition json.hpp:2830
static std::string name(const std::string &ename, int id_)
Definition json.hpp:2824
std::runtime_error m
an exception object as storage for error messages
Definition json.hpp:2895
const char * what() const noexcept override
returns the explanatory string
Definition json.hpp:2812
std::FILE * m_file
the file pointer to read from
Definition json.hpp:5268
file_input_adapter(const file_input_adapter &)=delete
file_input_adapter(file_input_adapter &&) noexcept=default
std::char_traits< char >::int_type get_character() noexcept
Definition json.hpp:5261
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition json.hpp:5305
input_stream_adapter & operator=(input_stream_adapter &)=delete
input_stream_adapter(const input_stream_adapter &)=delete
std::istream * is
the associated input stream
Definition json.hpp:5328
input_stream_adapter & operator=(input_stream_adapter &&)=delete
std::char_traits< char >::int_type get_character()
Definition json.hpp:5315
exception indicating errors with iterators
Definition json.hpp:2954
static invalid_iterator create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition json.hpp:2957
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition json.hpp:11407
bool operator<(const iter_impl &other) const
comparison: smaller
Definition json.hpp:11870
iter_impl operator-(difference_type i) const
subtract from iterator
Definition json.hpp:12000
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition json.hpp:11861
iter_impl const operator--(int)
post-decrement (it–)
Definition json.hpp:11773
void set_end() noexcept
set the iterator past the last value
Definition json.hpp:11597
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition json.hpp:11434
iter_impl & operator--()
pre-decrement (–it)
Definition json.hpp:11784
difference_type operator-(const iter_impl &other) const
return difference
Definition json.hpp:12011
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition json.hpp:11516
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition json.hpp:11443
reference operator*() const
return a reference to the value pointed to by the iterator
Definition json.hpp:11636
iter_impl(iter_impl &&) noexcept=default
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition json.hpp:11923
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition json.hpp:11438
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition json.hpp:11541
pointer operator->() const
dereference the iterator
Definition json.hpp:11680
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition json.hpp:11506
iter_impl const operator++(int)
post-increment (it++)
Definition json.hpp:11722
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition json.hpp:11531
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition json.hpp:12103
iter_impl operator+(difference_type i) const
add to iterator
Definition json.hpp:11978
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition json.hpp:11989
const object_t::key_type & key() const
return the key of an object iterator
Definition json.hpp:12078
bool operator==(const IterImpl &other) const
comparison: equal
Definition json.hpp:11825
bool operator>(const iter_impl &other) const
comparison: greater than
Definition json.hpp:11914
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition json.hpp:11432
reference value() const
return the value of an iterator
Definition json.hpp:12094
typename BasicJsonType::object_t object_t
Definition json.hpp:11416
friend other_iter_impl
allow basic_json to access private members
Definition json.hpp:11411
iter_impl & operator++()
pre-increment (++it)
Definition json.hpp:11733
reference operator[](difference_type n) const
access to successor
Definition json.hpp:12040
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition json.hpp:11905
std::bidirectional_iterator_tag iterator_category
Definition json.hpp:11429
iter_impl & operator+=(difference_type i)
add to iterator
Definition json.hpp:11932
typename BasicJsonType::array_t array_t
Definition json.hpp:11417
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition json.hpp:11969
IteratorType anchor
the iterator
Definition json.hpp:4338
std::input_iterator_tag iterator_category
Definition json.hpp:4333
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition json.hpp:4334
const string_type empty_str
an empty string (to return a reference for primitive values)
Definition json.hpp:4346
iteration_proxy_value(IteratorType it) noexcept
Definition json.hpp:4349
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition json.hpp:4375
std::size_t array_index_last
last stringified array index
Definition json.hpp:4342
string_type array_index_str
a string representation of the array index
Definition json.hpp:4344
IteratorType::reference value() const
return value of the iterator
Definition json.hpp:4417
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition json.hpp:4360
std::size_t array_index
an index for arrays (used to create key names)
Definition json.hpp:4340
iteration_proxy_value & operator*()
dereference operator (needed for range-based for)
Definition json.hpp:4354
const string_type & key() const
return key of the iterator
Definition json.hpp:4381
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition json.hpp:4369
proxy class for the items() function
Definition json.hpp:4425
iteration_proxy_value< IteratorType > begin() noexcept
return iterator begin (needed for range-based for)
Definition json.hpp:4436
iteration_proxy_value< IteratorType > end() noexcept
return iterator end (needed for range-based for)
Definition json.hpp:4442
IteratorType::reference container
the container to iterate
Definition json.hpp:4428
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition json.hpp:4432
typename std::iterator_traits< IteratorType >::value_type char_type
Definition json.hpp:5339
iterator_input_adapter(IteratorType first, IteratorType last)
Definition json.hpp:5341
std::char_traits< char_type >::int_type get_character()
Definition json.hpp:5345
value_type const * value_ref
Definition json.hpp:13131
json_ref(json_ref &&) noexcept=default
value_type const & operator*() const
Definition json.hpp:13119
BasicJsonType value_type
Definition json.hpp:13082
json_ref(Args &&... args)
Definition json.hpp:13099
json_ref(const value_type &value)
Definition json.hpp:13088
value_type const * operator->() const
Definition json.hpp:13124
json_ref(std::initializer_list< json_ref > init)
Definition json.hpp:13092
json_ref(value_type &&value)
Definition json.hpp:13084
value_type moved_or_copied() const
Definition json.hpp:13110
a template for a reverse iterator class
Definition json.hpp:12145
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition json.hpp:12154
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition json.hpp:12173
typename Base::reference reference
the reference type for the pointed-to element
Definition json.hpp:12151
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition json.hpp:12197
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition json.hpp:12185
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition json.hpp:12149
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition json.hpp:12158
reference operator[](difference_type n) const
access to successor
Definition json.hpp:12209
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition json.hpp:12203
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition json.hpp:12191
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition json.hpp:12161
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition json.hpp:12215
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition json.hpp:12179
reference value() const
return the value of an iterator
Definition json.hpp:12222
json_reverse_iterator & operator++()
pre-increment (++it)
Definition json.hpp:12167
bool start_object(std::size_t=static_cast< std::size_t >(-1))
Definition json.hpp:6373
typename BasicJsonType::string_t string_t
Definition json.hpp:6335
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:6332
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:6334
typename BasicJsonType::binary_t binary_t
Definition json.hpp:6336
bool start_array(std::size_t=static_cast< std::size_t >(-1))
Definition json.hpp:6388
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition json.hpp:6398
bool number_integer(number_integer_t)
Definition json.hpp:6348
bool number_unsigned(number_unsigned_t)
Definition json.hpp:6353
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:6333
bool number_float(number_float_t, const string_t &)
Definition json.hpp:6358
typename BasicJsonType::string_t string_t
Definition json.hpp:6028
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:6026
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:6025
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
Definition json.hpp:6245
typename BasicJsonType::parser_callback_t parser_callback_t
Definition json.hpp:6030
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition json.hpp:6029
bool number_integer(number_integer_t val)
Definition json.hpp:6060
BasicJsonType & root
the parsed JSON value
Definition json.hpp:6309
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:6027
typename BasicJsonType::parse_event_t parse_event_t
Definition json.hpp:6031
bool number_unsigned(number_unsigned_t val)
Definition json.hpp:6066
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
bool number_float(number_float_t val, const string_t &)
Definition json.hpp:6072
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition json.hpp:6211
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition json.hpp:6033
SAX implementation to create a JSON value from SAX events.
Definition json.hpp:5849
bool start_array(std::size_t len)
Definition json.hpp:5941
json_sax_dom_parser(const json_sax_dom_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition json.hpp:5855
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
bool number_unsigned(number_unsigned_t val)
Definition json.hpp:5891
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:5851
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition json.hpp:5961
JSON_HEDLEY_RETURNS_NON_NULL BasicJsonType * handle_value(Value &&v)
Definition json.hpp:5987
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:5852
bool start_object(std::size_t len)
Definition json.hpp:5915
constexpr bool is_errored() const
Definition json.hpp:5973
json_sax_dom_parser(json_sax_dom_parser &&)=default
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:5853
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
BasicJsonType & root
the parsed JSON value
Definition json.hpp:6010
bool number_float(number_float_t val, const string_t &)
Definition json.hpp:5897
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition json.hpp:5862
typename BasicJsonType::string_t string_t
Definition json.hpp:5854
bool number_integer(number_integer_t val)
Definition json.hpp:5885
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition json.hpp:6464
token_type
token types for the parser
Definition json.hpp:6441
@ value_float
an floating point number – use get_number_float() for actual value
@ begin_array
the character for array begin [
@ value_string
a string – use get_string() for actual value
@ end_array
the character for array end ]
@ uninitialized
indicating the scanner is uninitialized
@ parse_error
indicating a parse error
@ value_integer
a signed integer – use get_number_integer() for actual value
@ value_separator
the value separator ,
@ end_object
the character for object end }
@ begin_object
the character for object begin {
@ value_unsigned
an unsigned integer – use get_number_unsigned() for actual value
@ end_of_input
indicating the end of the input buffer
@ literal_or_value
a literal or the begin of a value (only for diagnostics)
lexical analysis
Definition json.hpp:6514
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition json.hpp:7832
number_float_t value_float
Definition json.hpp:8027
const bool ignore_comments
whether comments should be ignored (true) or signaled as errors (false)
Definition json.hpp:8004
void add(char_int_type c)
add a character to token_buffer
Definition json.hpp:7803
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition json.hpp:7722
token_type scan()
Definition json.hpp:7911
bool next_unget
whether the next get() call should just return current
Definition json.hpp:8010
char_int_type current
the current character
Definition json.hpp:8007
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:6517
typename std::char_traits< char_type >::int_type char_int_type
Definition json.hpp:6520
static JSON_HEDLEY_PURE char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition json.hpp:6545
number_integer_t value_integer
Definition json.hpp:8025
InputAdapterType ia
input adapter
Definition json.hpp:8001
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:6515
lexer & operator=(lexer &&)=default
static void strtof(float &f, const char *str, char **endptr) noexcept
Definition json.hpp:7314
const char_int_type decimal_point_char
the decimal point
Definition json.hpp:8030
bool skip_bom()
skip the UTF-8 byte order mark
Definition json.hpp:7888
const char * error_message
a description of occurred lexer errors
Definition json.hpp:8022
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition json.hpp:6525
position_t position
the start position of the current token
Definition json.hpp:8013
constexpr position_t get_position() const noexcept
return position of last read token
Definition json.hpp:7842
std::vector< char_type > token_string
raw input token string (for error messages)
Definition json.hpp:8016
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition json.hpp:7814
typename lexer_base< BasicJsonType >::token_type token_type
Definition json.hpp:6523
typename InputAdapterType::char_type char_type
Definition json.hpp:6519
char_int_type get()
Definition json.hpp:7739
token_type scan_number()
scan a number literal
Definition json.hpp:7371
lexer & operator=(lexer &)=delete
void unget()
unget current character (read it again on next get)
Definition json.hpp:7776
token_type scan_string()
scan a string literal
Definition json.hpp:6656
lexer(const lexer &)=delete
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition json.hpp:7820
string_t token_buffer
buffer for variable-length tokens (numbers, strings)
Definition json.hpp:8019
token_type scan_literal(const char_type *literal_text, const std::size_t length, token_type return_type)
Definition json.hpp:7702
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition json.hpp:7826
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition json.hpp:6571
std::string get_token_string() const
Definition json.hpp:7850
number_unsigned_t value_unsigned
Definition json.hpp:8026
lexer(lexer &&)=default
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:6516
bool next_byte_in_range(std::initializer_list< char_int_type > ranges)
check if the next byte(s) are inside a given range
Definition json.hpp:6619
typename BasicJsonType::string_t string_t
Definition json.hpp:6518
bool scan_comment()
scan a comment
Definition json.hpp:7246
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition json.hpp:7875
exception indicating other library errors
Definition json.hpp:3006
static other_error create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition json.hpp:3009
exception indicating access out of the defined range
Definition json.hpp:2989
static out_of_range create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition json.hpp:2992
output_adapter(std::basic_ostream< CharType > &s)
Definition json.hpp:13283
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition json.hpp:13279
output adapter for output streams
Definition json.hpp:13228
void write_character(CharType c) override
Definition json.hpp:13234
std::basic_ostream< CharType > & stream
Definition json.hpp:13246
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition json.hpp:13230
output adapter for basic_string
Definition json.hpp:13253
void write_character(CharType c) override
Definition json.hpp:13259
output_string_adapter(StringType &s) noexcept
Definition json.hpp:13255
output adapter for byte vectors
Definition json.hpp:13203
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition json.hpp:13205
void write_character(CharType c) override
Definition json.hpp:13209
std::vector< CharType, AllocatorType > & v
Definition json.hpp:13221
exception indicating a parse error
Definition json.hpp:2901
parse_error(int id_, std::size_t byte_, const char *what_arg)
Definition json.hpp:2941
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, const BasicJsonType &context)
Definition json.hpp:2921
const std::size_t byte
byte index of the parse error
Definition json.hpp:2938
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, const BasicJsonType &context)
create a parse error exception
Definition json.hpp:2913
static std::string position_string(const position_t &pos)
Definition json.hpp:2944
syntax analysis
Definition json.hpp:10760
lexer_t m_lexer
the lexer
Definition json.hpp:11200
bool sax_parse(SAX *sax, const bool strict=true)
Definition json.hpp:10860
token_type get_token()
get next token from lexer
Definition json.hpp:11160
token_type last_token
the type of the last read token
Definition json.hpp:11198
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition json.hpp:10770
bool accept(const bool strict=true)
public accept interface
Definition json.hpp:10852
typename BasicJsonType::string_t string_t
Definition json.hpp:10764
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:10762
typename lexer_t::token_type token_type
Definition json.hpp:10766
bool sax_parse_internal(SAX *sax)
Definition json.hpp:10879
const parser_callback_t< BasicJsonType > callback
callback function
Definition json.hpp:11196
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition json.hpp:10792
std::string exception_message(const token_type expected, const std::string &context)
Definition json.hpp:11165
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:10763
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition json.hpp:11202
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:10761
primitive_iterator_t operator+(difference_type n) noexcept
Definition json.hpp:11284
primitive_iterator_t & operator++() noexcept
Definition json.hpp:11296
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition json.hpp:11269
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition json.hpp:11328
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition json.hpp:11263
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition json.hpp:11279
void set_begin() noexcept
set iterator to a defined beginning
Definition json.hpp:11251
primitive_iterator_t const operator++(int) noexcept
Definition json.hpp:11302
static constexpr difference_type end_value
Definition json.hpp:11238
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition json.hpp:11274
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition json.hpp:11291
primitive_iterator_t & operator--() noexcept
Definition json.hpp:11309
void set_end() noexcept
set iterator to a defined past the end
Definition json.hpp:11257
constexpr difference_type get_value() const noexcept
Definition json.hpp:11245
primitive_iterator_t const operator--(int) noexcept
Definition json.hpp:11315
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition json.hpp:11322
static constexpr difference_type begin_value
Definition json.hpp:11237
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition json.hpp:17008
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:16090
const std::lconv * loc
the locale
Definition json.hpp:16993
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition json.hpp:16990
static constexpr std::uint8_t UTF8_ACCEPT
Definition json.hpp:16092
serializer(serializer &&)=delete
serializer & operator=(serializer &&)=delete
const char decimal_point
the locale's decimal point character
Definition json.hpp:16997
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:16088
const char thousands_sep
the locale's thousand separator character
Definition json.hpp:16995
serializer & operator=(const serializer &)=delete
static constexpr std::uint8_t UTF8_REJECT
Definition json.hpp:16093
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition json.hpp:16141
const char indent_char
the indentation character
Definition json.hpp:17003
std::size_t bytes_after_last_accept
Definition json.hpp:16432
std::array< char, 512 > string_buffer
string buffer
Definition json.hpp:17000
typename BasicJsonType::binary_t::value_type binary_char_t
Definition json.hpp:16091
JSON_PRIVATE_UNLESS_TESTED const bool ensure_ascii
Definition json.hpp:16426
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition json.hpp:16101
typename BasicJsonType::string_t string_t
Definition json.hpp:16087
serializer(const serializer &)=delete
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:16089
string_t indent_string
the indentation string
Definition json.hpp:17005
contiguous_bytes_input_adapter && get()
Definition json.hpp:5681
span_input_adapter(CharT b, std::size_t l)
Definition json.hpp:5671
contiguous_bytes_input_adapter ia
Definition json.hpp:5687
span_input_adapter(IteratorType first, IteratorType last)
Definition json.hpp:5678
exception indicating executing a member function with a wrong type
Definition json.hpp:2972
static type_error create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition json.hpp:2975
std::char_traits< char >::int_type get_character() noexcept
Definition json.hpp:5504
std::size_t utf8_bytes_index
index to the utf8_codes array for the next valid byte
Definition json.hpp:5534
std::size_t utf8_bytes_filled
number of valid bytes in the utf8_codes array
Definition json.hpp:5536
wide_string_input_adapter(BaseInputAdapter base)
Definition json.hpp:5501
std::array< std::char_traits< char >::int_type, 4 > utf8_bytes
a buffer for UTF-8 bytes
Definition json.hpp:5531
JSON Pointer defines a string syntax for identifying a specific value within a JSON document.
Definition json.hpp:12260
std::vector< std::string > reference_tokens
the reference tokens
Definition json.hpp:13061
JSON_PRIVATE_UNLESS_TESTED JSON pointer has no BasicJsonType()))
json_pointer & operator/=(std::string token)
append an unescaped reference token at the end of this JSON pointer
Definition json.hpp:12303
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition json.hpp:12293
friend json_pointer operator/(const json_pointer &lhs, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition json.hpp:12333
std::string to_string() const
return a string representation of the JSON pointer
Definition json.hpp:12274
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
Definition json.hpp:12676
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for equality
Definition json.hpp:13037
void pop_back()
remove last reference token
Definition json.hpp:12354
const std::string & back() const
return last reference token
Definition json.hpp:12366
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
Definition json.hpp:12724
bool empty() const noexcept
return whether pointer points to the root document
Definition json.hpp:12392
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for inequality
Definition json.hpp:13054
void push_back(const std::string &token)
append an unescaped token at the end of the reference pointer
Definition json.hpp:12378
json_pointer(const std::string &s="")
create JSON pointer
Definition json.hpp:12268
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition json.hpp:12318
bool contains(const BasicJsonType *ptr) const
Definition json.hpp:12772
static BasicJsonType unflatten(const BasicJsonType &value)
Definition json.hpp:12999
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
Definition json.hpp:12473
friend json_pointer operator/(const json_pointer &lhs, std::string token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition json.hpp:12326
static void flatten(const std::string &reference_string, const BasicJsonType &value, BasicJsonType &result)
Definition json.hpp:12928
void push_back(std::string &&token)
append an unescaped token at the end of the reference pointer
Definition json.hpp:12385
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition json.hpp:12619
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition json.hpp:12311
static BasicJsonType::size_type array_index(const std::string &s)
Definition json.hpp:12408
json_pointer result
Definition json.hpp:12459
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition json.hpp:12552
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition json.hpp:12340
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
Definition json.hpp:12860
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition json.hpp:4487
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition json.hpp:2485
#define JSON_HEDLEY_CONST
Definition json.hpp:1679
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition json.hpp:963
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition json.hpp:1309
#define JSON_PRIVATE_UNLESS_TESTED
Definition json.hpp:2448
#define NLOHMANN_JSON_VERSION_PATCH
Definition json.hpp:44
#define JSON_HEDLEY_LIKELY(expr)
Definition json.hpp:1574
#define JSON_HEDLEY_NON_NULL(...)
Definition json.hpp:1467
#define JSON_INTERNAL_CATCH(exception)
Definition json.hpp:2415
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition json.hpp:1908
#define JSON_CATCH(exception)
Definition json.hpp:2414
#define JSON_ASSERT(x)
Definition json.hpp:2441
#define JSON_THROW(exception)
Definition json.hpp:2412
#define NLOHMANN_JSON_VERSION_MAJOR
Definition json.hpp:42
#define NLOHMANN_BASIC_JSON_TPL
Definition json.hpp:2494
#define JSON_HEDLEY_UNLIKELY(expr)
Definition json.hpp:1575
#define JSON_TRY
Definition json.hpp:2413
#define NLOHMANN_JSON_VERSION_MINOR
Definition json.hpp:43
#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name)
Definition json.hpp:2660
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition json.hpp:964
#define JSON_EXPLICIT
Definition json.hpp:2697
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition json.hpp:1257
#define JSON_HEDLEY_PURE
Definition json.hpp:1648
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition json.hpp:15763
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition json.hpp:15915
Target reinterpret_bits(const Source source)
Definition json.hpp:14983
boundaries compute_boundaries(FloatType value)
Definition json.hpp:15124
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition json.hpp:15427
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition json.hpp:15481
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition json.hpp:15863
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition json.hpp:15522
cached_power get_cached_power_for_binary_exponent(int e)
Definition json.hpp:15263
detail namespace with internal helper functions
Definition json.hpp:100
typename std::enable_if< B, T >::type enable_if_t
Definition json.hpp:3055
typename T::reference reference_t
Definition json.hpp:3416
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition json.hpp:156
static void unescape(std::string &s)
string unescaping as described in RFC 6901 (Sect. 4)
Definition json.hpp:2757
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition json.hpp:3425
void to_json(BasicJsonType &j, T b) noexcept
Definition json.hpp:4753
value_type_t< iterator_traits< iterator_t< T > > > range_value_t
Definition json.hpp:3579
value_t
the JSON type enumeration
Definition json.hpp:130
@ number_integer
number value (signed integer)
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition json.hpp:3834
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition json.hpp:3159
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition json.hpp:8101
typename T::pointer pointer_t
Definition json.hpp:3413
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition json.hpp:8074
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition json.hpp:10751
typename T::difference_type difference_type_t
Definition json.hpp:3410
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition json.hpp:2286
void int_to_string(string_type &target, std::size_t value)
Definition json.hpp:4320
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition json.hpp:3989
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition json.hpp:8086
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition json.hpp:8058
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition json.hpp:8078
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition json.hpp:8062
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition json.hpp:16000
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition json.hpp:4876
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition json.hpp:3576
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition json.hpp:2299
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition json.hpp:3041
cbor_tag_handler_t
how to treat CBOR tags
Definition json.hpp:8202
@ store
store tags as binary type
@ error
throw a parse_error exception in case of a tag
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
error_handler_t
how to treat decoding errors
Definition json.hpp:16078
@ strict
throw a type_error exception in case of invalid UTF-8
@ ignore
ignore invalid UTF-8 sequences
@ replace
replace invalid UTF-8 sequences with U+FFFD
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition json.hpp:8082
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition json.hpp:5579
typename T::key_type key_type_t
Definition json.hpp:3404
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition json.hpp:5079
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition json.hpp:5097
static bool little_endianness(int num=1) noexcept
determine system byte order
Definition json.hpp:8215
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition json.hpp:3143
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition json.hpp:8066
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition json.hpp:2295
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition json.hpp:2292
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition json.hpp:8093
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 > >, priority_tag< 0 >)
Definition json.hpp:4178
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition json.hpp:3848
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition json.hpp:2280
typename make_void< Ts... >::type void_t
Definition json.hpp:2242
make_integer_sequence< size_t, N > make_index_sequence
Definition json.hpp:3151
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition json.hpp:13198
typename T::mapped_type mapped_type_t
Definition json.hpp:3401
std::string escape(std::string s)
string escaping as described in RFC 6901 (Sect. 4)
Definition json.hpp:2743
input_format_t
the supported input formats
Definition json.hpp:5233
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition json.hpp:4172
decltype(std::declval< T >().template get< U >()) get_template_function
Definition json.hpp:3428
std::array< T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType &&j, identity_tag< std::array< T, sizeof...(Idx)> >, index_sequence< Idx... >)
Definition json.hpp:4072
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition json.hpp:5636
decltype(std::declval< T & >().null()) null_function_t
Definition json.hpp:8054
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition json.hpp:4451
void replace_substring(std::string &s, const std::string &f, const std::string &t)
replace all occurrences of a substring by another string
Definition json.hpp:2725
typename T::iterator_category iterator_category_t
Definition json.hpp:3419
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition json.hpp:8070
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition json.hpp:8096
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition json.hpp:8089
T conditional_static_cast(U value)
Definition json.hpp:3798
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition json.hpp:3422
typename T::value_type value_type_t
Definition json.hpp:3407
namespace for Niels Lohmann
Definition json.hpp:98
basic_json<> json
default specialization
Definition json.hpp:3337
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition json.hpp:21838
Definition json.hpp:4471
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition json.hpp:21884
every row value
default JSONSerializer template argument
Definition json.hpp:4926
static auto from_json(BasicJsonType &&j, TargetType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition json.hpp:4930
static auto from_json(BasicJsonType &&j) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))
convert a JSON value to any value type
Definition json.hpp:4940
static auto to_json(BasicJsonType &j, TargetType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< TargetType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< TargetType >(val)), void())
convert any value type to a JSON value
Definition json.hpp:4950
std::false_type value_t
Definition json.hpp:2268
static constexpr int kPrecision
Definition json.hpp:14994
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition json.hpp:15082
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition json.hpp:15099
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition json.hpp:15017
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition json.hpp:14999
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition json.hpp:15005
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition json.hpp:4665
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition json.hpp:4694
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition json.hpp:4678
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition json.hpp:4653
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition json.hpp:4643
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition json.hpp:4582
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition json.hpp:4591
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition json.hpp:4536
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition json.hpp:4604
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition json.hpp:4630
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition json.hpp:4617
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition json.hpp:4723
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition json.hpp:4713
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition json.hpp:4734
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition json.hpp:4558
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition json.hpp:4569
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition json.hpp:4549
auto operator()(const BasicJsonType &j, T &&val) const noexcept(noexcept(from_json(j, std::forward< T >(val)))) -> decltype(from_json(j, std::forward< T >(val)))
Definition json.hpp:4269
typename BasicJsonType::template json_serializer< T, void > serializer
Definition json.hpp:3447
typename BasicJsonType::template json_serializer< T, void > serializer
Definition json.hpp:3477
static constexpr std::size_t size() noexcept
Definition json.hpp:3085
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition json.hpp:11355
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition json.hpp:11353
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition json.hpp:11351
static constexpr bool value
Definition json.hpp:3441
typename std::iterator_traits< T >::value_type value_type
Definition json.hpp:5556
static one test(decltype(&C::capacity))
detected_t< result_of_end, t_ref > sentinel
Definition json.hpp:3563
detected_t< result_of_begin, t_ref > iterator
Definition json.hpp:3562
static constexpr auto is_iterator_begin
Definition json.hpp:3568
typename std::add_lvalue_reference< T >::type t_ref
Definition json.hpp:3560
static constexpr bool value
Definition json.hpp:3572
typename BasicJsonType::string_t string_t
Definition json.hpp:8144
typename BasicJsonType::exception exception_t
Definition json.hpp:8146
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:8141
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:8143
typename BasicJsonType::binary_t binary_t
Definition json.hpp:8145
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:8142
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:8112
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:8111
typename BasicJsonType::exception exception_t
Definition json.hpp:8115
static constexpr bool value
Definition json.hpp:8118
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:8110
typename BasicJsonType::string_t string_t
Definition json.hpp:8113
typename BasicJsonType::binary_t binary_t
Definition json.hpp:8114
typename std::iterator_traits< iterator_type >::value_type char_type
Definition json.hpp:5544
static adapter_type create(IteratorType first, IteratorType last)
Definition json.hpp:5547
iterator_input_adapter< iterator_type > adapter_type
Definition json.hpp:5545
nonesuch(nonesuch const &)=delete
void operator=(nonesuch &&)=delete
nonesuch(nonesuch const &&)=delete
void operator=(nonesuch const &)=delete
abstract output adapter interface
Definition json.hpp:13184
virtual void write_characters(const CharType *s, std::size_t length)=0
virtual void write_character(CharType c)=0
output_adapter_protocol(output_adapter_protocol &&) noexcept=default
output_adapter_protocol(const output_adapter_protocol &)=default
struct to capture the start position of the current token
Definition json.hpp:2777
std::size_t lines_read
the number of lines read
Definition json.hpp:2783
std::size_t chars_read_current_line
the number of characters read in the current line
Definition json.hpp:2781
std::size_t chars_read_total
the total number of characters read
Definition json.hpp:2779
static constexpr T value
Definition json.hpp:3173
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition json.hpp:4898
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition json.hpp:3124
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition json.hpp:5436
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition json.hpp:5378
SAX interface.
Definition json.hpp:5718
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
virtual bool string(string_t &val)=0
a string value was read
virtual bool null()=0
a null value was read
typename BasicJsonType::number_integer_t number_integer_t
Definition json.hpp:5719
typename BasicJsonType::binary_t binary_t
Definition json.hpp:5723
virtual bool end_array()=0
the end of an array was read
virtual bool key(string_t &val)=0
an object key was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition json.hpp:5720
virtual bool binary(binary_t &val)=0
a binary value was read
typename BasicJsonType::number_float_t number_float_t
Definition json.hpp:5721
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
json_sax(json_sax &&) noexcept=default
virtual bool boolean(bool val)=0
a boolean value was read
json_sax(const json_sax &)=default
virtual bool end_object()=0
the end of an object was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
typename BasicJsonType::string_t string_t
Definition json.hpp:5722
virtual bool number_float(number_float_t val, const string_t &s)=0
a floating-point number was read
virtual bool number_integer(number_integer_t val)=0
an integer number was read
a minimal map-like container that preserves insertion order
Definition json.hpp:17040
T & at(const Key &key)
Definition json.hpp:17081
ordered_map(std::initializer_list< T > init, const Allocator &alloc=Allocator())
Definition json.hpp:17055
std::vector< std::pair< const Key, T >, Allocator > Container
Definition json.hpp:17043
const T & at(const Key &key) const
Definition json.hpp:17094
iterator find(const Key &key)
Definition json.hpp:17191
iterator erase(iterator pos)
Definition json.hpp:17126
void insert(InputIt first, InputIt last)
Definition json.hpp:17238
std::pair< iterator, bool > insert(value_type &&value)
Definition json.hpp:17215
const_iterator find(const Key &key) const
Definition json.hpp:17203
size_type erase(const Key &key)
Definition json.hpp:17107
T & operator[](const Key &key)
Definition json.hpp:17071
iterator erase(iterator first, iterator last)
Definition json.hpp:17131
typename Container::const_iterator const_iterator
Definition json.hpp:17045
ordered_map(const Allocator &alloc=Allocator())
Definition json.hpp:17051
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition json.hpp:17235
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition json.hpp:17053
std::pair< iterator, bool > insert(const value_type &value)
Definition json.hpp:17220
typename Container::size_type size_type
Definition json.hpp:17046
typename Container::value_type value_type
Definition json.hpp:17047
size_type count(const Key &key) const
Definition json.hpp:17179
typename Container::iterator iterator
Definition json.hpp:17044
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition json.hpp:17058
const T & operator[](const Key &key) const
Definition json.hpp:17076
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition json.hpp:21857
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition json.hpp:21871