JSON for Modern C++ 3.10.3
json.hpp
1/*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4| | |__ | | | | | | version 3.10.3
5|_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8SPDX-License-Identifier: MIT
9Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10
11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal
13in the Software without restriction, including without limitation the rights
14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15copies of the Software, and to permit persons to whom the Software is
16furnished to do so, subject to the following conditions:
17
18The above copyright notice and this permission notice shall be included in all
19copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27SOFTWARE.
28*/
29
30#ifndef INCLUDE_NLOHMANN_JSON_HPP_
31#define INCLUDE_NLOHMANN_JSON_HPP_
32
33#define NLOHMANN_JSON_VERSION_MAJOR 3
34#define NLOHMANN_JSON_VERSION_MINOR 10
35#define NLOHMANN_JSON_VERSION_PATCH 3
36
37#include <algorithm> // all_of, find, for_each
38#include <cstddef> // nullptr_t, ptrdiff_t, size_t
39#include <functional> // hash, less
40#include <initializer_list> // initializer_list
41#ifndef JSON_NO_IO
42 #include <iosfwd> // istream, ostream
43#endif // JSON_NO_IO
44#include <iterator> // random_access_iterator_tag
45#include <memory> // unique_ptr
46#include <numeric> // accumulate
47#include <string> // string, stoi, to_string
48#include <utility> // declval, forward, move, pair, swap
49#include <vector> // vector
50
51// #include <nlohmann/adl_serializer.hpp>
52
53
54#include <type_traits>
55#include <utility>
56
57// #include <nlohmann/detail/conversions/from_json.hpp>
58
59
60#include <algorithm> // transform
61#include <array> // array
62#include <forward_list> // forward_list
63#include <iterator> // inserter, front_inserter, end
64#include <map> // map
65#include <string> // string
66#include <tuple> // tuple, make_tuple
67#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
68#include <unordered_map> // unordered_map
69#include <utility> // pair, declval
70#include <valarray> // valarray
71
72// #include <nlohmann/detail/exceptions.hpp>
73
74
75#include <exception> // exception
76#include <stdexcept> // runtime_error
77#include <string> // to_string
78#include <vector> // vector
79
80// #include <nlohmann/detail/value_t.hpp>
81
82
83#include <array> // array
84#include <cstddef> // size_t
85#include <cstdint> // uint8_t
86#include <string> // string
87
88namespace nlohmann
89{
90namespace detail
91{
93// JSON type enumeration //
95
120enum class value_t : std::uint8_t
121{
122 null,
123 object,
124 array,
125 string,
126 boolean,
127 number_integer,
128 number_unsigned,
129 number_float,
130 binary,
131 discarded
132};
133
147inline bool operator<(const value_t lhs, const value_t rhs) noexcept
148{
149 static constexpr std::array<std::uint8_t, 9> order = {{
150 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
151 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
152 6 /* binary */
153 }
154 };
155
156 const auto l_index = static_cast<std::size_t>(lhs);
157 const auto r_index = static_cast<std::size_t>(rhs);
158 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
159}
160} // namespace detail
161} // namespace nlohmann
162
163// #include <nlohmann/detail/string_escape.hpp>
164
165
166#include <string>
167// #include <nlohmann/detail/macro_scope.hpp>
168
169
170#include <utility> // declval, pair
171// #include <nlohmann/thirdparty/hedley/hedley.hpp>
172
173
174/* Hedley - https://nemequ.github.io/hedley
175 * Created by Evan Nemerson <evan@nemerson.com>
176 *
177 * To the extent possible under law, the author(s) have dedicated all
178 * copyright and related and neighboring rights to this software to
179 * the public domain worldwide. This software is distributed without
180 * any warranty.
181 *
182 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
183 * SPDX-License-Identifier: CC0-1.0
184 */
185
186#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
187#if defined(JSON_HEDLEY_VERSION)
188 #undef JSON_HEDLEY_VERSION
189#endif
190#define JSON_HEDLEY_VERSION 15
191
192#if defined(JSON_HEDLEY_STRINGIFY_EX)
193 #undef JSON_HEDLEY_STRINGIFY_EX
194#endif
195#define JSON_HEDLEY_STRINGIFY_EX(x) #x
196
197#if defined(JSON_HEDLEY_STRINGIFY)
198 #undef JSON_HEDLEY_STRINGIFY
199#endif
200#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
201
202#if defined(JSON_HEDLEY_CONCAT_EX)
203 #undef JSON_HEDLEY_CONCAT_EX
204#endif
205#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
206
207#if defined(JSON_HEDLEY_CONCAT)
208 #undef JSON_HEDLEY_CONCAT
209#endif
210#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
211
212#if defined(JSON_HEDLEY_CONCAT3_EX)
213 #undef JSON_HEDLEY_CONCAT3_EX
214#endif
215#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
216
217#if defined(JSON_HEDLEY_CONCAT3)
218 #undef JSON_HEDLEY_CONCAT3
219#endif
220#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
221
222#if defined(JSON_HEDLEY_VERSION_ENCODE)
223 #undef JSON_HEDLEY_VERSION_ENCODE
224#endif
225#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
226
227#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
228 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
229#endif
230#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
231
232#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
233 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
234#endif
235#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
236
237#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
238 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
239#endif
240#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
241
242#if defined(JSON_HEDLEY_GNUC_VERSION)
243 #undef JSON_HEDLEY_GNUC_VERSION
244#endif
245#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
246 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
247#elif defined(__GNUC__)
248 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
249#endif
250
251#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
252 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
253#endif
254#if defined(JSON_HEDLEY_GNUC_VERSION)
255 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
256#else
257 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
258#endif
259
260#if defined(JSON_HEDLEY_MSVC_VERSION)
261 #undef JSON_HEDLEY_MSVC_VERSION
262#endif
263#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
264 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
265#elif defined(_MSC_FULL_VER) && !defined(__ICL)
266 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
267#elif defined(_MSC_VER) && !defined(__ICL)
268 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
269#endif
270
271#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
272 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
273#endif
274#if !defined(JSON_HEDLEY_MSVC_VERSION)
275 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
276#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
277 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
278#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
279 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
280#else
281 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
282#endif
283
284#if defined(JSON_HEDLEY_INTEL_VERSION)
285 #undef JSON_HEDLEY_INTEL_VERSION
286#endif
287#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
288 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
289#elif defined(__INTEL_COMPILER) && !defined(__ICL)
290 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
291#endif
292
293#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
294 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
295#endif
296#if defined(JSON_HEDLEY_INTEL_VERSION)
297 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
298#else
299 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
300#endif
301
302#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
303 #undef JSON_HEDLEY_INTEL_CL_VERSION
304#endif
305#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
306 #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
307#endif
308
309#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
310 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
311#endif
312#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
313 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
314#else
315 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
316#endif
317
318#if defined(JSON_HEDLEY_PGI_VERSION)
319 #undef JSON_HEDLEY_PGI_VERSION
320#endif
321#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
322 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
323#endif
324
325#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
326 #undef JSON_HEDLEY_PGI_VERSION_CHECK
327#endif
328#if defined(JSON_HEDLEY_PGI_VERSION)
329 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
330#else
331 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
332#endif
333
334#if defined(JSON_HEDLEY_SUNPRO_VERSION)
335 #undef JSON_HEDLEY_SUNPRO_VERSION
336#endif
337#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
338 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
339#elif defined(__SUNPRO_C)
340 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
341#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
342 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
343#elif defined(__SUNPRO_CC)
344 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
345#endif
346
347#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
348 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
349#endif
350#if defined(JSON_HEDLEY_SUNPRO_VERSION)
351 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
352#else
353 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
354#endif
355
356#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
357 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
358#endif
359#if defined(__EMSCRIPTEN__)
360 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
361#endif
362
363#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
364 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
365#endif
366#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
367 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
368#else
369 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
370#endif
371
372#if defined(JSON_HEDLEY_ARM_VERSION)
373 #undef JSON_HEDLEY_ARM_VERSION
374#endif
375#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
376 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
377#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
378 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
379#endif
380
381#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
382 #undef JSON_HEDLEY_ARM_VERSION_CHECK
383#endif
384#if defined(JSON_HEDLEY_ARM_VERSION)
385 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
386#else
387 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
388#endif
389
390#if defined(JSON_HEDLEY_IBM_VERSION)
391 #undef JSON_HEDLEY_IBM_VERSION
392#endif
393#if defined(__ibmxl__)
394 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
395#elif defined(__xlC__) && defined(__xlC_ver__)
396 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
397#elif defined(__xlC__)
398 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
399#endif
400
401#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
402 #undef JSON_HEDLEY_IBM_VERSION_CHECK
403#endif
404#if defined(JSON_HEDLEY_IBM_VERSION)
405 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
406#else
407 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
408#endif
409
410#if defined(JSON_HEDLEY_TI_VERSION)
411 #undef JSON_HEDLEY_TI_VERSION
412#endif
413#if \
414 defined(__TI_COMPILER_VERSION__) && \
415 ( \
416 defined(__TMS470__) || defined(__TI_ARM__) || \
417 defined(__MSP430__) || \
418 defined(__TMS320C2000__) \
419 )
420#if (__TI_COMPILER_VERSION__ >= 16000000)
421 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
422#endif
423#endif
424
425#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
426 #undef JSON_HEDLEY_TI_VERSION_CHECK
427#endif
428#if defined(JSON_HEDLEY_TI_VERSION)
429 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
430#else
431 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
432#endif
433
434#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
435 #undef JSON_HEDLEY_TI_CL2000_VERSION
436#endif
437#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
438 #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
439#endif
440
441#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
442 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
443#endif
444#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
445 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446#else
447 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
448#endif
449
450#if defined(JSON_HEDLEY_TI_CL430_VERSION)
451 #undef JSON_HEDLEY_TI_CL430_VERSION
452#endif
453#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
454 #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
455#endif
456
457#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
458 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
459#endif
460#if defined(JSON_HEDLEY_TI_CL430_VERSION)
461 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
462#else
463 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
464#endif
465
466#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
467 #undef JSON_HEDLEY_TI_ARMCL_VERSION
468#endif
469#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
470 #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
471#endif
472
473#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
474 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
475#endif
476#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
477 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
478#else
479 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
480#endif
481
482#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
483 #undef JSON_HEDLEY_TI_CL6X_VERSION
484#endif
485#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
486 #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
487#endif
488
489#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
490 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
491#endif
492#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
493 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
494#else
495 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
496#endif
497
498#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
499 #undef JSON_HEDLEY_TI_CL7X_VERSION
500#endif
501#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
502 #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
503#endif
504
505#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
506 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
507#endif
508#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
509 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
510#else
511 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
512#endif
513
514#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
515 #undef JSON_HEDLEY_TI_CLPRU_VERSION
516#endif
517#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
518 #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
519#endif
520
521#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
522 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
523#endif
524#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
525 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
526#else
527 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
528#endif
529
530#if defined(JSON_HEDLEY_CRAY_VERSION)
531 #undef JSON_HEDLEY_CRAY_VERSION
532#endif
533#if defined(_CRAYC)
534 #if defined(_RELEASE_PATCHLEVEL)
535 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
536 #else
537 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
538 #endif
539#endif
540
541#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
542 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
543#endif
544#if defined(JSON_HEDLEY_CRAY_VERSION)
545 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
546#else
547 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
548#endif
549
550#if defined(JSON_HEDLEY_IAR_VERSION)
551 #undef JSON_HEDLEY_IAR_VERSION
552#endif
553#if defined(__IAR_SYSTEMS_ICC__)
554 #if __VER__ > 1000
555 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
556 #else
557 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
558 #endif
559#endif
560
561#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
562 #undef JSON_HEDLEY_IAR_VERSION_CHECK
563#endif
564#if defined(JSON_HEDLEY_IAR_VERSION)
565 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
566#else
567 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
568#endif
569
570#if defined(JSON_HEDLEY_TINYC_VERSION)
571 #undef JSON_HEDLEY_TINYC_VERSION
572#endif
573#if defined(__TINYC__)
574 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
575#endif
576
577#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
578 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
579#endif
580#if defined(JSON_HEDLEY_TINYC_VERSION)
581 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
582#else
583 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
584#endif
585
586#if defined(JSON_HEDLEY_DMC_VERSION)
587 #undef JSON_HEDLEY_DMC_VERSION
588#endif
589#if defined(__DMC__)
590 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
591#endif
592
593#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
594 #undef JSON_HEDLEY_DMC_VERSION_CHECK
595#endif
596#if defined(JSON_HEDLEY_DMC_VERSION)
597 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
598#else
599 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
600#endif
601
602#if defined(JSON_HEDLEY_COMPCERT_VERSION)
603 #undef JSON_HEDLEY_COMPCERT_VERSION
604#endif
605#if defined(__COMPCERT_VERSION__)
606 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
607#endif
608
609#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
610 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
611#endif
612#if defined(JSON_HEDLEY_COMPCERT_VERSION)
613 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
614#else
615 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
616#endif
617
618#if defined(JSON_HEDLEY_PELLES_VERSION)
619 #undef JSON_HEDLEY_PELLES_VERSION
620#endif
621#if defined(__POCC__)
622 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
623#endif
624
625#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
626 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
627#endif
628#if defined(JSON_HEDLEY_PELLES_VERSION)
629 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
630#else
631 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
632#endif
633
634#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
635 #undef JSON_HEDLEY_MCST_LCC_VERSION
636#endif
637#if defined(__LCC__) && defined(__LCC_MINOR__)
638 #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
639#endif
640
641#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
642 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
643#endif
644#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
645 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
646#else
647 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
648#endif
649
650#if defined(JSON_HEDLEY_GCC_VERSION)
651 #undef JSON_HEDLEY_GCC_VERSION
652#endif
653#if \
654 defined(JSON_HEDLEY_GNUC_VERSION) && \
655 !defined(__clang__) && \
656 !defined(JSON_HEDLEY_INTEL_VERSION) && \
657 !defined(JSON_HEDLEY_PGI_VERSION) && \
658 !defined(JSON_HEDLEY_ARM_VERSION) && \
659 !defined(JSON_HEDLEY_CRAY_VERSION) && \
660 !defined(JSON_HEDLEY_TI_VERSION) && \
661 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
662 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
663 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
664 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
665 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
666 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
667 !defined(__COMPCERT__) && \
668 !defined(JSON_HEDLEY_MCST_LCC_VERSION)
669 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
670#endif
671
672#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
673 #undef JSON_HEDLEY_GCC_VERSION_CHECK
674#endif
675#if defined(JSON_HEDLEY_GCC_VERSION)
676 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
677#else
678 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
679#endif
680
681#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
682 #undef JSON_HEDLEY_HAS_ATTRIBUTE
683#endif
684#if \
685 defined(__has_attribute) && \
686 ( \
687 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
688 )
689# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
690#else
691# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
692#endif
693
694#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
695 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
696#endif
697#if defined(__has_attribute)
698 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
699#else
700 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
701#endif
702
703#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
704 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
705#endif
706#if defined(__has_attribute)
707 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
708#else
709 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
710#endif
711
712#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
713 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
714#endif
715#if \
716 defined(__has_cpp_attribute) && \
717 defined(__cplusplus) && \
718 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
719 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
720#else
721 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
722#endif
723
724#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
725 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
726#endif
727#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
728 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
729#elif \
730 !defined(JSON_HEDLEY_PGI_VERSION) && \
731 !defined(JSON_HEDLEY_IAR_VERSION) && \
732 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
733 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
734 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
735#else
736 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
737#endif
738
739#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
740 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
741#endif
742#if defined(__has_cpp_attribute) && defined(__cplusplus)
743 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
744#else
745 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
746#endif
747
748#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
749 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
750#endif
751#if defined(__has_cpp_attribute) && defined(__cplusplus)
752 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
753#else
754 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
755#endif
756
757#if defined(JSON_HEDLEY_HAS_BUILTIN)
758 #undef JSON_HEDLEY_HAS_BUILTIN
759#endif
760#if defined(__has_builtin)
761 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
762#else
763 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
764#endif
765
766#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
767 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
768#endif
769#if defined(__has_builtin)
770 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
771#else
772 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
773#endif
774
775#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
776 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
777#endif
778#if defined(__has_builtin)
779 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
780#else
781 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
782#endif
783
784#if defined(JSON_HEDLEY_HAS_FEATURE)
785 #undef JSON_HEDLEY_HAS_FEATURE
786#endif
787#if defined(__has_feature)
788 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
789#else
790 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
791#endif
792
793#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
794 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
795#endif
796#if defined(__has_feature)
797 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
798#else
799 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
800#endif
801
802#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
803 #undef JSON_HEDLEY_GCC_HAS_FEATURE
804#endif
805#if defined(__has_feature)
806 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
807#else
808 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
809#endif
810
811#if defined(JSON_HEDLEY_HAS_EXTENSION)
812 #undef JSON_HEDLEY_HAS_EXTENSION
813#endif
814#if defined(__has_extension)
815 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
816#else
817 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
818#endif
819
820#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
821 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
822#endif
823#if defined(__has_extension)
824 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
825#else
826 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
827#endif
828
829#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
830 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
831#endif
832#if defined(__has_extension)
833 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
834#else
835 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
836#endif
837
838#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
839 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
840#endif
841#if defined(__has_declspec_attribute)
842 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
843#else
844 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
845#endif
846
847#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
848 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
849#endif
850#if defined(__has_declspec_attribute)
851 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
852#else
853 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
854#endif
855
856#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
857 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
858#endif
859#if defined(__has_declspec_attribute)
860 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
861#else
862 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
863#endif
864
865#if defined(JSON_HEDLEY_HAS_WARNING)
866 #undef JSON_HEDLEY_HAS_WARNING
867#endif
868#if defined(__has_warning)
869 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
870#else
871 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
872#endif
873
874#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
875 #undef JSON_HEDLEY_GNUC_HAS_WARNING
876#endif
877#if defined(__has_warning)
878 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
879#else
880 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
881#endif
882
883#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
884 #undef JSON_HEDLEY_GCC_HAS_WARNING
885#endif
886#if defined(__has_warning)
887 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
888#else
889 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
890#endif
891
892#if \
893 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
894 defined(__clang__) || \
895 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
896 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
897 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
898 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
899 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
900 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
901 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
902 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
903 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
904 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
905 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
906 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
907 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
908 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
909 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
910 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
911 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
912#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
913 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
914#else
915 #define JSON_HEDLEY_PRAGMA(value)
916#endif
917
918#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
919 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
920#endif
921#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
922 #undef JSON_HEDLEY_DIAGNOSTIC_POP
923#endif
924#if defined(__clang__)
925 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
926 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
927#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
928 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
929 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
930#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
931 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
932 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
933#elif \
934 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
935 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
936 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
937 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
938#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
939 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
940 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
941#elif \
942 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
943 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
944 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
945 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
946 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
947 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
948 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
949 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
950#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
951 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
952 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
953#else
954 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
955 #define JSON_HEDLEY_DIAGNOSTIC_POP
956#endif
957
958/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
959 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
960#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
961 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
962#endif
963#if defined(__cplusplus)
964# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
965# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
966# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
967# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
968 JSON_HEDLEY_DIAGNOSTIC_PUSH \
969 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
970 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
971 _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
972 xpr \
973 JSON_HEDLEY_DIAGNOSTIC_POP
974# else
975# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
976 JSON_HEDLEY_DIAGNOSTIC_PUSH \
977 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
978 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
979 xpr \
980 JSON_HEDLEY_DIAGNOSTIC_POP
981# endif
982# else
983# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
984 JSON_HEDLEY_DIAGNOSTIC_PUSH \
985 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
986 xpr \
987 JSON_HEDLEY_DIAGNOSTIC_POP
988# endif
989# endif
990#endif
991#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
992 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
993#endif
994
995#if defined(JSON_HEDLEY_CONST_CAST)
996 #undef JSON_HEDLEY_CONST_CAST
997#endif
998#if defined(__cplusplus)
999# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1000#elif \
1001 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1002 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1003 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1004# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1005 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1006 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1007 ((T) (expr)); \
1008 JSON_HEDLEY_DIAGNOSTIC_POP \
1009 }))
1010#else
1011# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1012#endif
1013
1014#if defined(JSON_HEDLEY_REINTERPRET_CAST)
1015 #undef JSON_HEDLEY_REINTERPRET_CAST
1016#endif
1017#if defined(__cplusplus)
1018 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1019#else
1020 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1021#endif
1022
1023#if defined(JSON_HEDLEY_STATIC_CAST)
1024 #undef JSON_HEDLEY_STATIC_CAST
1025#endif
1026#if defined(__cplusplus)
1027 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1028#else
1029 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1030#endif
1031
1032#if defined(JSON_HEDLEY_CPP_CAST)
1033 #undef JSON_HEDLEY_CPP_CAST
1034#endif
1035#if defined(__cplusplus)
1036# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1037# define JSON_HEDLEY_CPP_CAST(T, expr) \
1038 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1039 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1040 ((T) (expr)) \
1041 JSON_HEDLEY_DIAGNOSTIC_POP
1042# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1043# define JSON_HEDLEY_CPP_CAST(T, expr) \
1044 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1045 _Pragma("diag_suppress=Pe137") \
1046 JSON_HEDLEY_DIAGNOSTIC_POP
1047# else
1048# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1049# endif
1050#else
1051# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1052#endif
1053
1054#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1055 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1056#endif
1057#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1058 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1059#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1060 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1061#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1062 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1063#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1064 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1065#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1066 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1067#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1068 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1069#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1070 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1071#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1072 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1073#elif \
1074 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1075 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1076 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1077 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1078 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1079 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1080 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1081 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1082 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1083 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1084 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1085 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1086#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1087 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1088#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1089 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1090#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1091 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1092#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1093 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1094#else
1095 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1096#endif
1097
1098#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1099 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1100#endif
1101#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1102 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1103#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1104 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1105#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1106 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1107#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1108 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1109#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1110 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1111#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1112 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1113#elif \
1114 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1115 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1116 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1117 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1118 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1119#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1120 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1121#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1122 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1123#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1124 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1125#else
1126 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1127#endif
1128
1129#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1130 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1131#endif
1132#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1133 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1134#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1135 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1136#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1137 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1138#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1139 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1140#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1141 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1142#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1143 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1144#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1145 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1146#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1147 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1148#elif \
1149 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1150 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1151 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1152 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1153#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1154 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1155#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1156 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1157#else
1158 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1159#endif
1160
1161#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1162 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1163#endif
1164#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1165 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1166#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1167 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1168#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1169 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1170#else
1171 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1172#endif
1173
1174#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1175 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1176#endif
1177#if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1178 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1179#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1180 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1181#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1182 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1183#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1184 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1185#else
1186 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1187#endif
1188
1189#if defined(JSON_HEDLEY_DEPRECATED)
1190 #undef JSON_HEDLEY_DEPRECATED
1191#endif
1192#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1193 #undef JSON_HEDLEY_DEPRECATED_FOR
1194#endif
1195#if \
1196 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1197 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1198 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1199 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1200#elif \
1201 (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1202 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1203 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1204 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1205 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1206 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1207 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1208 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1209 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1210 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1211 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1212 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1213 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1214 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1215#elif defined(__cplusplus) && (__cplusplus >= 201402L)
1216 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1217 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1218#elif \
1219 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1220 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1221 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1222 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1223 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1225 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1227 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1229 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1230 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1231 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1232 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1233 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1234 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1235 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1236 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1237#elif \
1238 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1239 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1240 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1241 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1242 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1243#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1244 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1245 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1246#else
1247 #define JSON_HEDLEY_DEPRECATED(since)
1248 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1249#endif
1250
1251#if defined(JSON_HEDLEY_UNAVAILABLE)
1252 #undef JSON_HEDLEY_UNAVAILABLE
1253#endif
1254#if \
1255 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1256 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1257 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1258 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1259 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1260#else
1261 #define JSON_HEDLEY_UNAVAILABLE(available_since)
1262#endif
1263
1264#if defined()
1265 #undef
1266#endif
1267#if defined(_MSG)
1268 #undef _MSG
1269#endif
1270#if \
1271 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1272 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1273 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1274 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1275 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1276 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1277 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1278 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1279 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1280 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1281 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1282 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1283 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1284 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1285 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1286 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1287 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1288 #define __attribute__((__warn_unused_result__))
1289 #define _MSG(msg) __attribute__((__warn_unused_result__))
1290#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1291 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1292 #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1293#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1294 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1295 #define _MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1296#elif defined(_Check_return_) /* SAL */
1297 #define _Check_return_
1298 #define _MSG(msg) _Check_return_
1299#else
1300 #define
1301 #define _MSG(msg)
1302#endif
1303
1304#if defined(JSON_HEDLEY_SENTINEL)
1305 #undef JSON_HEDLEY_SENTINEL
1306#endif
1307#if \
1308 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1309 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1310 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1311 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1312 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1313 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1314#else
1315 #define JSON_HEDLEY_SENTINEL(position)
1316#endif
1317
1318#if defined(JSON_HEDLEY_NO_RETURN)
1319 #undef JSON_HEDLEY_NO_RETURN
1320#endif
1321#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1322 #define JSON_HEDLEY_NO_RETURN __noreturn
1323#elif \
1324 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1325 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1326 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1327#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1328 #define JSON_HEDLEY_NO_RETURN _Noreturn
1329#elif defined(__cplusplus) && (__cplusplus >= 201103L)
1330 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1331#elif \
1332 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1333 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1334 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1335 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1336 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1337 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1338 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1339 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1340 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1341 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1342 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1343 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1344 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1345 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1346 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1347 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1348 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1349 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1350#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1351 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1352#elif \
1353 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1354 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1355 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1356#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1357 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1358#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1359 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1360#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1361 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1362#else
1363 #define JSON_HEDLEY_NO_RETURN
1364#endif
1365
1366#if defined(JSON_HEDLEY_NO_ESCAPE)
1367 #undef JSON_HEDLEY_NO_ESCAPE
1368#endif
1369#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1370 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1371#else
1372 #define JSON_HEDLEY_NO_ESCAPE
1373#endif
1374
1375#if defined(JSON_HEDLEY_UNREACHABLE)
1376 #undef JSON_HEDLEY_UNREACHABLE
1377#endif
1378#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1379 #undef JSON_HEDLEY_UNREACHABLE_RETURN
1380#endif
1381#if defined(JSON_HEDLEY_ASSUME)
1382 #undef JSON_HEDLEY_ASSUME
1383#endif
1384#if \
1385 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1386 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1387 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1388 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1389#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1390 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1391#elif \
1392 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1393 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1394 #if defined(__cplusplus)
1395 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1396 #else
1397 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1398 #endif
1399#endif
1400#if \
1401 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1402 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1403 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1404 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1405 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1406 JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1407 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1408 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1409#elif defined(JSON_HEDLEY_ASSUME)
1410 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1411#endif
1412#if !defined(JSON_HEDLEY_ASSUME)
1413 #if defined(JSON_HEDLEY_UNREACHABLE)
1414 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1415 #else
1416 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1417 #endif
1418#endif
1419#if defined(JSON_HEDLEY_UNREACHABLE)
1420 #if \
1421 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1422 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1423 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1424 #else
1425 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1426 #endif
1427#else
1428 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1429#endif
1430#if !defined(JSON_HEDLEY_UNREACHABLE)
1431 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1432#endif
1433
1434JSON_HEDLEY_DIAGNOSTIC_PUSH
1435#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1436 #pragma clang diagnostic ignored "-Wpedantic"
1437#endif
1438#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1439 #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1440#endif
1441#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1442 #if defined(__clang__)
1443 #pragma clang diagnostic ignored "-Wvariadic-macros"
1444 #elif defined(JSON_HEDLEY_GCC_VERSION)
1445 #pragma GCC diagnostic ignored "-Wvariadic-macros"
1446 #endif
1447#endif
1448#if defined(JSON_HEDLEY_NON_NULL)
1449 #undef JSON_HEDLEY_NON_NULL
1450#endif
1451#if \
1452 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1453 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1454 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1455 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1456 #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1457#else
1458 #define JSON_HEDLEY_NON_NULL(...)
1459#endif
1460JSON_HEDLEY_DIAGNOSTIC_POP
1461
1462#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1463 #undef JSON_HEDLEY_PRINTF_FORMAT
1464#endif
1465#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1466 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1467#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1468 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1469#elif \
1470 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1471 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1472 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1473 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1474 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1475 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1476 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1477 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1478 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1479 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1480 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1481 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1482 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1483 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1484 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1485 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1486 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1487 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1488#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1489 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1490#else
1491 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1492#endif
1493
1494#if defined(JSON_HEDLEY_CONSTEXPR)
1495 #undef JSON_HEDLEY_CONSTEXPR
1496#endif
1497#if defined(__cplusplus)
1498 #if __cplusplus >= 201103L
1499 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1500 #endif
1501#endif
1502#if !defined(JSON_HEDLEY_CONSTEXPR)
1503 #define JSON_HEDLEY_CONSTEXPR
1504#endif
1505
1506#if defined(JSON_HEDLEY_PREDICT)
1507 #undef JSON_HEDLEY_PREDICT
1508#endif
1509#if defined(JSON_HEDLEY_LIKELY)
1510 #undef JSON_HEDLEY_LIKELY
1511#endif
1512#if defined(JSON_HEDLEY_UNLIKELY)
1513 #undef JSON_HEDLEY_UNLIKELY
1514#endif
1515#if defined(JSON_HEDLEY_UNPREDICTABLE)
1516 #undef JSON_HEDLEY_UNPREDICTABLE
1517#endif
1518#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1519 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1520#endif
1521#if \
1522 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1523 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1524 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1525# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1526# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1527# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1528# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1529# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1530#elif \
1531 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1532 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1533 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1534 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1535 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1536 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1537 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1538 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1539 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1540 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1541 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1542 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1543 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1544 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1545 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1546 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1547# define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1548 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1549# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1550 (__extension__ ({ \
1551 double hedley_probability_ = (probability); \
1552 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1553 }))
1554# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1555 (__extension__ ({ \
1556 double hedley_probability_ = (probability); \
1557 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1558 }))
1559# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1560# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1561#else
1562# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1563# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1564# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1565# define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1566# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1567#endif
1568#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1569 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1570#endif
1571
1572#if defined(JSON_HEDLEY_MALLOC)
1573 #undef JSON_HEDLEY_MALLOC
1574#endif
1575#if \
1576 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1577 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1578 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1579 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1580 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1581 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1582 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1583 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1584 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1585 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1586 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1587 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1588 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1589 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1590 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1591 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1592 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1593 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1594 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1595#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1596 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1597#elif \
1598 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1599 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1600 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1601#else
1602 #define JSON_HEDLEY_MALLOC
1603#endif
1604
1605#if defined(JSON_HEDLEY_PURE)
1606 #undef JSON_HEDLEY_PURE
1607#endif
1608#if \
1609 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1610 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1611 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1612 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1613 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1614 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1615 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1616 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1617 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1618 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1619 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1620 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1621 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1622 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1623 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1624 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1625 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1626 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1627 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1628# define JSON_HEDLEY_PURE __attribute__((__pure__))
1629#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1630# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1631#elif defined(__cplusplus) && \
1632 ( \
1633 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1634 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1635 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1636 )
1637# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1638#else
1639# define JSON_HEDLEY_PURE
1640#endif
1641
1642#if defined(JSON_HEDLEY_CONST)
1643 #undef JSON_HEDLEY_CONST
1644#endif
1645#if \
1646 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1647 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1648 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1649 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1650 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1651 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1652 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1653 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1654 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1655 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1656 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1657 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1658 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1659 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1660 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1661 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1662 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1663 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1664 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1665 #define JSON_HEDLEY_CONST __attribute__((__const__))
1666#elif \
1667 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1668 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1669#else
1670 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1671#endif
1672
1673#if defined(JSON_HEDLEY_RESTRICT)
1674 #undef JSON_HEDLEY_RESTRICT
1675#endif
1676#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1677 #define JSON_HEDLEY_RESTRICT restrict
1678#elif \
1679 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1680 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1681 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1682 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1683 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1684 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1685 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1686 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1687 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1688 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1689 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1690 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1691 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1692 defined(__clang__) || \
1693 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1694 #define JSON_HEDLEY_RESTRICT __restrict
1695#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1696 #define JSON_HEDLEY_RESTRICT _Restrict
1697#else
1698 #define JSON_HEDLEY_RESTRICT
1699#endif
1700
1701#if defined(JSON_HEDLEY_INLINE)
1702 #undef JSON_HEDLEY_INLINE
1703#endif
1704#if \
1705 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1706 (defined(__cplusplus) && (__cplusplus >= 199711L))
1707 #define JSON_HEDLEY_INLINE inline
1708#elif \
1709 defined(JSON_HEDLEY_GCC_VERSION) || \
1710 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1711 #define JSON_HEDLEY_INLINE __inline__
1712#elif \
1713 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1714 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1715 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1716 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1717 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1718 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1719 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1720 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1721 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1722 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1723 #define JSON_HEDLEY_INLINE __inline
1724#else
1725 #define JSON_HEDLEY_INLINE
1726#endif
1727
1728#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1729 #undef JSON_HEDLEY_ALWAYS_INLINE
1730#endif
1731#if \
1732 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1733 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1734 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1735 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1736 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1737 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1738 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1739 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1740 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1741 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1742 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1743 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1744 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1745 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1746 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1747 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1748 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1749 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1750 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1751# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1752#elif \
1753 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1754 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1755# define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1756#elif defined(__cplusplus) && \
1757 ( \
1758 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1759 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1760 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1761 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1762 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1763 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1764 )
1765# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1766#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1767# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1768#else
1769# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1770#endif
1771
1772#if defined(JSON_HEDLEY_NEVER_INLINE)
1773 #undef JSON_HEDLEY_NEVER_INLINE
1774#endif
1775#if \
1776 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1777 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1778 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1779 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1780 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1781 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1782 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1783 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1784 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1785 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1786 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1787 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1788 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1789 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1790 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1791 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1792 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1793 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1794 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1795 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1796#elif \
1797 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1798 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1799 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1800#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1801 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1802#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1803 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1804#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1805 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1806#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1807 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1808#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1809 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1810#else
1811 #define JSON_HEDLEY_NEVER_INLINE
1812#endif
1813
1814#if defined(JSON_HEDLEY_PRIVATE)
1815 #undef JSON_HEDLEY_PRIVATE
1816#endif
1817#if defined(JSON_HEDLEY_PUBLIC)
1818 #undef JSON_HEDLEY_PUBLIC
1819#endif
1820#if defined(JSON_HEDLEY_IMPORT)
1821 #undef JSON_HEDLEY_IMPORT
1822#endif
1823#if defined(_WIN32) || defined(__CYGWIN__)
1824# define JSON_HEDLEY_PRIVATE
1825# define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1826# define JSON_HEDLEY_IMPORT __declspec(dllimport)
1827#else
1828# if \
1829 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1830 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1831 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1832 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1833 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1834 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1835 ( \
1836 defined(__TI_EABI__) && \
1837 ( \
1838 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1839 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1840 ) \
1841 ) || \
1842 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1843# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1844# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1845# else
1846# define JSON_HEDLEY_PRIVATE
1847# define JSON_HEDLEY_PUBLIC
1848# endif
1849# define JSON_HEDLEY_IMPORT extern
1850#endif
1851
1852#if defined(JSON_HEDLEY_NO_THROW)
1853 #undef JSON_HEDLEY_NO_THROW
1854#endif
1855#if \
1856 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1857 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1858 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1859 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1860 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1861#elif \
1862 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1863 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1864 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1865 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1866#else
1867 #define JSON_HEDLEY_NO_THROW
1868#endif
1869
1870#if defined(JSON_HEDLEY_FALL_THROUGH)
1871 #undef JSON_HEDLEY_FALL_THROUGH
1872#endif
1873#if \
1874 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1875 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
1876 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1877 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1878#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1879 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1880#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1881 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1882#elif defined(__fallthrough) /* SAL */
1883 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1884#else
1885 #define JSON_HEDLEY_FALL_THROUGH
1886#endif
1887
1888#if defined()
1889 #undef
1890#endif
1891#if \
1892 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1893 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1894 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1895 #define __attribute__((__returns_nonnull__))
1896#elif defined(_Ret_notnull_) /* SAL */
1897 #define _Ret_notnull_
1898#else
1899 #define
1900#endif
1901
1902#if defined(JSON_HEDLEY_ARRAY_PARAM)
1903 #undef JSON_HEDLEY_ARRAY_PARAM
1904#endif
1905#if \
1906 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1907 !defined(__STDC_NO_VLA__) && \
1908 !defined(__cplusplus) && \
1909 !defined(JSON_HEDLEY_PGI_VERSION) && \
1910 !defined(JSON_HEDLEY_TINYC_VERSION)
1911 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1912#else
1913 #define JSON_HEDLEY_ARRAY_PARAM(name)
1914#endif
1915
1916#if defined(JSON_HEDLEY_IS_CONSTANT)
1917 #undef JSON_HEDLEY_IS_CONSTANT
1918#endif
1919#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1920 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1921#endif
1922/* JSON_HEDLEY_IS_CONSTEXPR_ is for
1923 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1924#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1925 #undef JSON_HEDLEY_IS_CONSTEXPR_
1926#endif
1927#if \
1928 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1929 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1930 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1931 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1932 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1933 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1934 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1935 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1936 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1937 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1938 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1939#endif
1940#if !defined(__cplusplus)
1941# if \
1942 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1943 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1944 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1945 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1946 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1947 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1948 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1949#if defined(__INTPTR_TYPE__)
1950 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1951#else
1952 #include <stdint.h>
1953 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1954#endif
1955# elif \
1956 ( \
1957 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1958 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1959 !defined(JSON_HEDLEY_PGI_VERSION) && \
1960 !defined(JSON_HEDLEY_IAR_VERSION)) || \
1961 (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1962 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1963 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1964 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1965 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1966#if defined(__INTPTR_TYPE__)
1967 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1968#else
1969 #include <stdint.h>
1970 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1971#endif
1972# elif \
1973 defined(JSON_HEDLEY_GCC_VERSION) || \
1974 defined(JSON_HEDLEY_INTEL_VERSION) || \
1975 defined(JSON_HEDLEY_TINYC_VERSION) || \
1976 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1977 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1978 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1979 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1980 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1981 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1982 defined(__clang__)
1983# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1984 sizeof(void) != \
1985 sizeof(*( \
1986 1 ? \
1987 ((void*) ((expr) * 0L) ) : \
1988((struct { char v[sizeof(void) * 2]; } *) 1) \
1989 ) \
1990 ) \
1991 )
1992# endif
1993#endif
1994#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1995 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1996 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1997 #endif
1998 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1999#else
2000 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2001 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2002 #endif
2003 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2004#endif
2005
2006#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2007 #undef JSON_HEDLEY_BEGIN_C_DECLS
2008#endif
2009#if defined(JSON_HEDLEY_END_C_DECLS)
2010 #undef JSON_HEDLEY_END_C_DECLS
2011#endif
2012#if defined(JSON_HEDLEY_C_DECL)
2013 #undef JSON_HEDLEY_C_DECL
2014#endif
2015#if defined(__cplusplus)
2016 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2017 #define JSON_HEDLEY_END_C_DECLS }
2018 #define JSON_HEDLEY_C_DECL extern "C"
2019#else
2020 #define JSON_HEDLEY_BEGIN_C_DECLS
2021 #define JSON_HEDLEY_END_C_DECLS
2022 #define JSON_HEDLEY_C_DECL
2023#endif
2024
2025#if defined(JSON_HEDLEY_STATIC_ASSERT)
2026 #undef JSON_HEDLEY_STATIC_ASSERT
2027#endif
2028#if \
2029 !defined(__cplusplus) && ( \
2030 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2031 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2032 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2033 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2034 defined(_Static_assert) \
2035 )
2036# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2037#elif \
2038 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2039 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2040 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2041# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2042#else
2043# define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2044#endif
2045
2046#if defined(JSON_HEDLEY_NULL)
2047 #undef JSON_HEDLEY_NULL
2048#endif
2049#if defined(__cplusplus)
2050 #if __cplusplus >= 201103L
2051 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2052 #elif defined(NULL)
2053 #define JSON_HEDLEY_NULL NULL
2054 #else
2055 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2056 #endif
2057#elif defined(NULL)
2058 #define JSON_HEDLEY_NULL NULL
2059#else
2060 #define JSON_HEDLEY_NULL ((void*) 0)
2061#endif
2062
2063#if defined(JSON_HEDLEY_MESSAGE)
2064 #undef JSON_HEDLEY_MESSAGE
2065#endif
2066#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2067# define JSON_HEDLEY_MESSAGE(msg) \
2068 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2069 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2070 JSON_HEDLEY_PRAGMA(message msg) \
2071 JSON_HEDLEY_DIAGNOSTIC_POP
2072#elif \
2073 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2074 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2075# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2076#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2077# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2078#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2079# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2080#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2081# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2082#else
2083# define JSON_HEDLEY_MESSAGE(msg)
2084#endif
2085
2086#if defined(JSON_HEDLEY_WARNING)
2087 #undef JSON_HEDLEY_WARNING
2088#endif
2089#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2090# define JSON_HEDLEY_WARNING(msg) \
2091 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2092 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2093 JSON_HEDLEY_PRAGMA(clang warning msg) \
2094 JSON_HEDLEY_DIAGNOSTIC_POP
2095#elif \
2096 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2097 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2098 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2099# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2100#elif \
2101 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2102 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2103# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2104#else
2105# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2106#endif
2107
2108#if defined(JSON_HEDLEY_REQUIRE)
2109 #undef JSON_HEDLEY_REQUIRE
2110#endif
2111#if defined(JSON_HEDLEY_REQUIRE_MSG)
2112 #undef JSON_HEDLEY_REQUIRE_MSG
2113#endif
2114#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2115# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2116# define JSON_HEDLEY_REQUIRE(expr) \
2117 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2118 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2119 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2120 JSON_HEDLEY_DIAGNOSTIC_POP
2121# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2122 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2123 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2124 __attribute__((diagnose_if(!(expr), msg, "error"))) \
2125 JSON_HEDLEY_DIAGNOSTIC_POP
2126# else
2127# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2128# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2129# endif
2130#else
2131# define JSON_HEDLEY_REQUIRE(expr)
2132# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2133#endif
2134
2135#if defined(JSON_HEDLEY_FLAGS)
2136 #undef JSON_HEDLEY_FLAGS
2137#endif
2138#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2139 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2140#else
2141 #define JSON_HEDLEY_FLAGS
2142#endif
2143
2144#if defined(JSON_HEDLEY_FLAGS_CAST)
2145 #undef JSON_HEDLEY_FLAGS_CAST
2146#endif
2147#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2148# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2149 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2150 _Pragma("warning(disable:188)") \
2151 ((T) (expr)); \
2152 JSON_HEDLEY_DIAGNOSTIC_POP \
2153 }))
2154#else
2155# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2156#endif
2157
2158#if defined(JSON_HEDLEY_EMPTY_BASES)
2159 #undef JSON_HEDLEY_EMPTY_BASES
2160#endif
2161#if \
2162 (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2163 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2164 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2165#else
2166 #define JSON_HEDLEY_EMPTY_BASES
2167#endif
2168
2169/* Remaining macros are deprecated. */
2170
2171#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2172 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2173#endif
2174#if defined(__clang__)
2175 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2176#else
2177 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2178#endif
2179
2180#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2181 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2182#endif
2183#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2184
2185#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2186 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2187#endif
2188#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2189
2190#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2191 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2192#endif
2193#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2194
2195#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2196 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2197#endif
2198#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2199
2200#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2201 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2202#endif
2203#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2204
2205#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2206 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2207#endif
2208#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2209
2210#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2211 #undef JSON_HEDLEY_CLANG_HAS_WARNING
2212#endif
2213#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2214
2215#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2216
2217// #include <nlohmann/detail/meta/detected.hpp>
2218
2219
2220#include <type_traits>
2221
2222// #include <nlohmann/detail/meta/void_t.hpp>
2223
2224
2225namespace nlohmann
2226{
2227namespace detail
2228{
2229template<typename ...Ts> struct make_void
2230{
2231 using type = void;
2232};
2233template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2234} // namespace detail
2235} // namespace nlohmann
2236
2237
2238// https://en.cppreference.com/w/cpp/experimental/is_detected
2239namespace nlohmann
2240{
2241namespace detail
2242{
2243struct nonesuch
2244{
2245 nonesuch() = delete;
2246 ~nonesuch() = delete;
2247 nonesuch(nonesuch const&) = delete;
2248 nonesuch(nonesuch const&&) = delete;
2249 void operator=(nonesuch const&) = delete;
2250 void operator=(nonesuch&&) = delete;
2251};
2252
2253template<class Default,
2254 class AlwaysVoid,
2255 template<class...> class Op,
2256 class... Args>
2257struct detector
2258{
2259 using value_t = std::false_type;
2260 using type = Default;
2261};
2262
2263template<class Default, template<class...> class Op, class... Args>
2264struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2265{
2266 using value_t = std::true_type;
2267 using type = Op<Args...>;
2268};
2269
2270template<template<class...> class Op, class... Args>
2271using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2272
2273template<template<class...> class Op, class... Args>
2274struct is_detected_lazy : is_detected<Op, Args...> { };
2275
2276template<template<class...> class Op, class... Args>
2277using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2278
2279template<class Default, template<class...> class Op, class... Args>
2280using detected_or = detector<Default, void, Op, Args...>;
2281
2282template<class Default, template<class...> class Op, class... Args>
2283using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2284
2285template<class Expected, template<class...> class Op, class... Args>
2286using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2287
2288template<class To, template<class...> class Op, class... Args>
2289using is_detected_convertible =
2290 std::is_convertible<detected_t<Op, Args...>, To>;
2291} // namespace detail
2292} // namespace nlohmann
2293
2294
2295// This file contains all internal macro definitions
2296// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2297
2298// exclude unsupported compilers
2299#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2300 #if defined(__clang__)
2301 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2302 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2303 #endif
2304 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2305 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2306 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2307 #endif
2308 #endif
2309#endif
2310
2311// C++ language standard detection
2312// if the user manually specified the used c++ version this is skipped
2313#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2314 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2315 #define JSON_HAS_CPP_20
2316 #define JSON_HAS_CPP_17
2317 #define JSON_HAS_CPP_14
2318 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2319 #define JSON_HAS_CPP_17
2320 #define JSON_HAS_CPP_14
2321 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2322 #define JSON_HAS_CPP_14
2323 #endif
2324 // the cpp 11 flag is always specified because it is the minimal required version
2325 #define JSON_HAS_CPP_11
2326#endif
2327
2328// disable documentation warnings on clang
2329#if defined(__clang__)
2330 #pragma clang diagnostic push
2331 #pragma clang diagnostic ignored "-Wdocumentation"
2332 #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2333#endif
2334
2335// allow to disable exceptions
2336#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2337 #define JSON_THROW(exception) throw exception
2338 #define JSON_TRY try
2339 #define JSON_CATCH(exception) catch(exception)
2340 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2341#else
2342 #include <cstdlib>
2343 #define JSON_THROW(exception) std::abort()
2344 #define JSON_TRY if(true)
2345 #define JSON_CATCH(exception) if(false)
2346 #define JSON_INTERNAL_CATCH(exception) if(false)
2347#endif
2348
2349// override exception macros
2350#if defined(JSON_THROW_USER)
2351 #undef JSON_THROW
2352 #define JSON_THROW JSON_THROW_USER
2353#endif
2354#if defined(JSON_TRY_USER)
2355 #undef JSON_TRY
2356 #define JSON_TRY JSON_TRY_USER
2357#endif
2358#if defined(JSON_CATCH_USER)
2359 #undef JSON_CATCH
2360 #define JSON_CATCH JSON_CATCH_USER
2361 #undef JSON_INTERNAL_CATCH
2362 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2363#endif
2364#if defined(JSON_INTERNAL_CATCH_USER)
2365 #undef JSON_INTERNAL_CATCH
2366 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2367#endif
2368
2369// allow to override assert
2370#if !defined(JSON_ASSERT)
2371 #include <cassert> // assert
2372 #define JSON_ASSERT(x) assert(x)
2373#endif
2374
2375// allow to access some private functions (needed by the test suite)
2376#if defined(JSON_TESTS_PRIVATE)
2377 #define JSON_PRIVATE_UNLESS_TESTED public
2378#else
2379 #define JSON_PRIVATE_UNLESS_TESTED private
2380#endif
2381
2387#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2388 template<typename BasicJsonType> \
2389 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2390 { \
2391 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2392 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2393 auto it = std::find_if(std::begin(m), std::end(m), \
2394 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2395 { \
2396 return ej_pair.first == e; \
2397 }); \
2398 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2399 } \
2400 template<typename BasicJsonType> \
2401 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2402 { \
2403 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2404 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2405 auto it = std::find_if(std::begin(m), std::end(m), \
2406 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2407 { \
2408 return ej_pair.second == j; \
2409 }); \
2410 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2411 }
2412
2413// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2414// may be removed in the future once the class is split.
2415
2416#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2417 template<template<typename, typename, typename...> class ObjectType, \
2418 template<typename, typename...> class ArrayType, \
2419 class StringType, class BooleanType, class NumberIntegerType, \
2420 class NumberUnsignedType, class NumberFloatType, \
2421 template<typename> class AllocatorType, \
2422 template<typename, typename = void> class JSONSerializer, \
2423 class BinaryType>
2424
2425#define NLOHMANN_BASIC_JSON_TPL \
2426 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2427 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2428 AllocatorType, JSONSerializer, BinaryType>
2429
2430// Macros to simplify conversion from/to types
2431
2432#define NLOHMANN_JSON_EXPAND( x ) x
2433#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2434#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2435 NLOHMANN_JSON_PASTE64, \
2436 NLOHMANN_JSON_PASTE63, \
2437 NLOHMANN_JSON_PASTE62, \
2438 NLOHMANN_JSON_PASTE61, \
2439 NLOHMANN_JSON_PASTE60, \
2440 NLOHMANN_JSON_PASTE59, \
2441 NLOHMANN_JSON_PASTE58, \
2442 NLOHMANN_JSON_PASTE57, \
2443 NLOHMANN_JSON_PASTE56, \
2444 NLOHMANN_JSON_PASTE55, \
2445 NLOHMANN_JSON_PASTE54, \
2446 NLOHMANN_JSON_PASTE53, \
2447 NLOHMANN_JSON_PASTE52, \
2448 NLOHMANN_JSON_PASTE51, \
2449 NLOHMANN_JSON_PASTE50, \
2450 NLOHMANN_JSON_PASTE49, \
2451 NLOHMANN_JSON_PASTE48, \
2452 NLOHMANN_JSON_PASTE47, \
2453 NLOHMANN_JSON_PASTE46, \
2454 NLOHMANN_JSON_PASTE45, \
2455 NLOHMANN_JSON_PASTE44, \
2456 NLOHMANN_JSON_PASTE43, \
2457 NLOHMANN_JSON_PASTE42, \
2458 NLOHMANN_JSON_PASTE41, \
2459 NLOHMANN_JSON_PASTE40, \
2460 NLOHMANN_JSON_PASTE39, \
2461 NLOHMANN_JSON_PASTE38, \
2462 NLOHMANN_JSON_PASTE37, \
2463 NLOHMANN_JSON_PASTE36, \
2464 NLOHMANN_JSON_PASTE35, \
2465 NLOHMANN_JSON_PASTE34, \
2466 NLOHMANN_JSON_PASTE33, \
2467 NLOHMANN_JSON_PASTE32, \
2468 NLOHMANN_JSON_PASTE31, \
2469 NLOHMANN_JSON_PASTE30, \
2470 NLOHMANN_JSON_PASTE29, \
2471 NLOHMANN_JSON_PASTE28, \
2472 NLOHMANN_JSON_PASTE27, \
2473 NLOHMANN_JSON_PASTE26, \
2474 NLOHMANN_JSON_PASTE25, \
2475 NLOHMANN_JSON_PASTE24, \
2476 NLOHMANN_JSON_PASTE23, \
2477 NLOHMANN_JSON_PASTE22, \
2478 NLOHMANN_JSON_PASTE21, \
2479 NLOHMANN_JSON_PASTE20, \
2480 NLOHMANN_JSON_PASTE19, \
2481 NLOHMANN_JSON_PASTE18, \
2482 NLOHMANN_JSON_PASTE17, \
2483 NLOHMANN_JSON_PASTE16, \
2484 NLOHMANN_JSON_PASTE15, \
2485 NLOHMANN_JSON_PASTE14, \
2486 NLOHMANN_JSON_PASTE13, \
2487 NLOHMANN_JSON_PASTE12, \
2488 NLOHMANN_JSON_PASTE11, \
2489 NLOHMANN_JSON_PASTE10, \
2490 NLOHMANN_JSON_PASTE9, \
2491 NLOHMANN_JSON_PASTE8, \
2492 NLOHMANN_JSON_PASTE7, \
2493 NLOHMANN_JSON_PASTE6, \
2494 NLOHMANN_JSON_PASTE5, \
2495 NLOHMANN_JSON_PASTE4, \
2496 NLOHMANN_JSON_PASTE3, \
2497 NLOHMANN_JSON_PASTE2, \
2498 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2499#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2500#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2501#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2502#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2503#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2504#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2505#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2506#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2507#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2508#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2509#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2510#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2511#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2512#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2513#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2514#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2515#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2516#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2517#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2518#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2519#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2520#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2521#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2522#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2523#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2524#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2525#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2526#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2527#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2528#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2529#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2530#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2531#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2532#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2533#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2534#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2535#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2536#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2537#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2538#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2539#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2540#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2541#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2542#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2543#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2544#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2545#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2546#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2547#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2548#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2549#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2550#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2551#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2552#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2553#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2554#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2555#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2556#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2557#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2558#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2559#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2560#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2561#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2562
2563#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2564#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2565
2571#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2572 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2573 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2574
2580#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2581 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2582 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2583
2584
2585// inspired from https://stackoverflow.com/a/26745591
2586// allows to call any std function as if (e.g. with begin):
2587// using std::begin; begin(x);
2588//
2589// it allows using the detected idiom to retrieve the return type
2590// of such an expression
2591#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2592 namespace detail { \
2593 using std::std_name; \
2594 \
2595 template<typename... T> \
2596 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2597 } \
2598 \
2599 namespace detail2 { \
2600 struct std_name##_tag \
2601 { \
2602 }; \
2603 \
2604 template<typename... T> \
2605 std_name##_tag std_name(T&&...); \
2606 \
2607 template<typename... T> \
2608 using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2609 \
2610 template<typename... T> \
2611 struct would_call_std_##std_name \
2612 { \
2613 static constexpr auto const value = ::nlohmann::detail:: \
2614 is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2615 }; \
2616 } /* namespace detail2 */ \
2617 \
2618 template<typename... T> \
2619 struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2620 { \
2621 }
2622
2623#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2624 #define JSON_USE_IMPLICIT_CONVERSIONS 1
2625#endif
2626
2627#if JSON_USE_IMPLICIT_CONVERSIONS
2628 #define JSON_EXPLICIT
2629#else
2630 #define JSON_EXPLICIT explicit
2631#endif
2632
2633#ifndef JSON_DIAGNOSTICS
2634 #define JSON_DIAGNOSTICS 0
2635#endif
2636
2637
2638namespace nlohmann
2639{
2640namespace detail
2641{
2642
2656inline void replace_substring(std::string& s, const std::string& f,
2657 const std::string& t)
2658{
2659 JSON_ASSERT(!f.empty());
2660 for (auto pos = s.find(f); // find first occurrence of f
2661 pos != std::string::npos; // make sure f was found
2662 s.replace(pos, f.size(), t), // replace with t, and
2663 pos = s.find(f, pos + t.size())) // find next occurrence of f
2664 {}
2665}
2666
2674inline std::string escape(std::string s)
2675{
2676 replace_substring(s, "~", "~0");
2677 replace_substring(s, "/", "~1");
2678 return s;
2679}
2680
2688static void unescape(std::string& s)
2689{
2690 replace_substring(s, "~1", "/");
2691 replace_substring(s, "~0", "~");
2692}
2693
2694} // namespace detail
2695} // namespace nlohmann
2696
2697// #include <nlohmann/detail/input/position_t.hpp>
2698
2699
2700#include <cstddef> // size_t
2701
2702namespace nlohmann
2703{
2704namespace detail
2705{
2707struct position_t
2708{
2710 std::size_t chars_read_total = 0;
2712 std::size_t chars_read_current_line = 0;
2714 std::size_t lines_read = 0;
2715
2717 constexpr operator size_t() const
2718 {
2719 return chars_read_total;
2720 }
2721};
2722
2723} // namespace detail
2724} // namespace nlohmann
2725
2726// #include <nlohmann/detail/macro_scope.hpp>
2727
2728
2729namespace nlohmann
2730{
2731namespace detail
2732{
2734// exceptions //
2736
2765class exception : public std::exception
2766{
2767 public:
2769 const char* what() const noexcept override
2770 {
2771 return m.what();
2772 }
2773
2775 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
2776
2777 protected:
2778 JSON_HEDLEY_NON_NULL(3)
2779 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2780
2781 static std::string name(const std::string& ename, int id_)
2782 {
2783 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2784 }
2785
2786 template<typename BasicJsonType>
2787 static std::string diagnostics(const BasicJsonType& leaf_element)
2788 {
2789#if JSON_DIAGNOSTICS
2790 std::vector<std::string> tokens;
2791 for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
2792 {
2793 switch (current->m_parent->type())
2794 {
2795 case value_t::array:
2796 {
2797 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
2798 {
2799 if (&current->m_parent->m_value.array->operator[](i) == current)
2800 {
2801 tokens.emplace_back(std::to_string(i));
2802 break;
2803 }
2804 }
2805 break;
2806 }
2807
2808 case value_t::object:
2809 {
2810 for (const auto& element : *current->m_parent->m_value.object)
2811 {
2812 if (&element.second == current)
2813 {
2814 tokens.emplace_back(element.first.c_str());
2815 break;
2816 }
2817 }
2818 break;
2819 }
2820
2821 case value_t::null: // LCOV_EXCL_LINE
2822 case value_t::string: // LCOV_EXCL_LINE
2823 case value_t::boolean: // LCOV_EXCL_LINE
2824 case value_t::number_integer: // LCOV_EXCL_LINE
2825 case value_t::number_unsigned: // LCOV_EXCL_LINE
2826 case value_t::number_float: // LCOV_EXCL_LINE
2827 case value_t::binary: // LCOV_EXCL_LINE
2828 case value_t::discarded: // LCOV_EXCL_LINE
2829 default: // LCOV_EXCL_LINE
2830 break; // LCOV_EXCL_LINE
2831 }
2832 }
2833
2834 if (tokens.empty())
2835 {
2836 return "";
2837 }
2838
2839 return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
2840 [](const std::string & a, const std::string & b)
2841 {
2842 return a + "/" + detail::escape(b);
2843 }) + ") ";
2844#else
2845 static_cast<void>(leaf_element);
2846 return "";
2847#endif
2848 }
2849
2850 private:
2852 std::runtime_error m;
2853};
2854
2900class parse_error : public exception
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 parse_error(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 parse_error(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
2988class invalid_iterator : public exception
2989{
2990 public:
2991 template<typename BasicJsonType>
2992 static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
2993 {
2994 std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
2995 return invalid_iterator(id_, w.c_str());
2996 }
2997
2998 private:
2999 JSON_HEDLEY_NON_NULL(3)
3000 invalid_iterator(int id_, const char* what_arg)
3001 : exception(id_, what_arg) {}
3002};
3003
3043class type_error : public exception
3044{
3045 public:
3046 template<typename BasicJsonType>
3047 static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3048 {
3049 std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
3050 return type_error(id_, w.c_str());
3051 }
3052
3053 private:
3054 JSON_HEDLEY_NON_NULL(3)
3055 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3056};
3057
3091class out_of_range : public exception
3092{
3093 public:
3094 template<typename BasicJsonType>
3095 static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
3096 {
3097 std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
3098 return out_of_range(id_, w.c_str());
3099 }
3100
3101 private:
3102 JSON_HEDLEY_NON_NULL(3)
3103 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
3104};
3105
3130class other_error : public exception
3131{
3132 public:
3133 template<typename BasicJsonType>
3134 static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3135 {
3136 std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
3137 return other_error(id_, w.c_str());
3138 }
3139
3140 private:
3141 JSON_HEDLEY_NON_NULL(3)
3142 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3143};
3144} // namespace detail
3145} // namespace nlohmann
3146
3147// #include <nlohmann/detail/macro_scope.hpp>
3148
3149// #include <nlohmann/detail/meta/cpp_future.hpp>
3150
3151
3152#include <cstddef> // size_t
3153#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3154#include <utility> // index_sequence, make_index_sequence, index_sequence_for
3155
3156// #include <nlohmann/detail/macro_scope.hpp>
3157
3158
3159namespace nlohmann
3160{
3161namespace detail
3162{
3163
3164template<typename T>
3165using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3166
3167#ifdef JSON_HAS_CPP_14
3168
3169// the following utilities are natively available in C++14
3170using std::enable_if_t;
3171using std::index_sequence;
3172using std::make_index_sequence;
3173using std::index_sequence_for;
3174
3175#else
3176
3177// alias templates to reduce boilerplate
3178template<bool B, typename T = void>
3179using enable_if_t = typename std::enable_if<B, T>::type;
3180
3181// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3182// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3183
3185
3186// integer_sequence
3187//
3188// Class template representing a compile-time integer sequence. An instantiation
3189// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3190// type through its template arguments (which is a common need when
3191// working with C++11 variadic templates). `absl::integer_sequence` is designed
3192// to be a drop-in replacement for C++14's `std::integer_sequence`.
3193//
3194// Example:
3195//
3196// template< class T, T... Ints >
3197// void user_function(integer_sequence<T, Ints...>);
3198//
3199// int main()
3200// {
3201// // user_function's `T` will be deduced to `int` and `Ints...`
3202// // will be deduced to `0, 1, 2, 3, 4`.
3203// user_function(make_integer_sequence<int, 5>());
3204// }
3205template <typename T, T... Ints>
3206struct integer_sequence
3207{
3208 using value_type = T;
3209 static constexpr std::size_t size() noexcept
3210 {
3211 return sizeof...(Ints);
3212 }
3213};
3214
3215// index_sequence
3216//
3217// A helper template for an `integer_sequence` of `size_t`,
3218// `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3219// `std::index_sequence`.
3220template <size_t... Ints>
3221using index_sequence = integer_sequence<size_t, Ints...>;
3222
3223namespace utility_internal
3224{
3225
3226template <typename Seq, size_t SeqSize, size_t Rem>
3227struct Extend;
3228
3229// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3230template <typename T, T... Ints, size_t SeqSize>
3231struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3232{
3233 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3234};
3235
3236template <typename T, T... Ints, size_t SeqSize>
3237struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3238{
3239 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3240};
3241
3242// Recursion helper for 'make_integer_sequence<T, N>'.
3243// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3244template <typename T, size_t N>
3245struct Gen
3246{
3247 using type =
3248 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3249};
3250
3251template <typename T>
3252struct Gen<T, 0>
3253{
3254 using type = integer_sequence<T>;
3255};
3256
3257} // namespace utility_internal
3258
3259// Compile-time sequences of integers
3260
3261// make_integer_sequence
3262//
3263// This template alias is equivalent to
3264// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3265// replacement for C++14's `std::make_integer_sequence`.
3266template <typename T, T N>
3267using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
3268
3269// make_index_sequence
3270//
3271// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3272// and is designed to be a drop-in replacement for C++14's
3273// `std::make_index_sequence`.
3274template <size_t N>
3275using make_index_sequence = make_integer_sequence<size_t, N>;
3276
3277// index_sequence_for
3278//
3279// Converts a typename pack into an index sequence of the same length, and
3280// is designed to be a drop-in replacement for C++14's
3281// `std::index_sequence_for()`
3282template <typename... Ts>
3283using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
3284
3286
3287#endif
3288
3289// dispatch utility (taken from ranges-v3)
3290template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3291template<> struct priority_tag<0> {};
3292
3293// taken from ranges-v3
3294template<typename T>
3295struct static_const
3296{
3297 static constexpr T value{};
3298};
3299
3300template<typename T>
3301constexpr T static_const<T>::value;
3302
3303} // namespace detail
3304} // namespace nlohmann
3305
3306// #include <nlohmann/detail/meta/identity_tag.hpp>
3307
3308
3309namespace nlohmann
3310{
3311namespace detail
3312{
3313// dispatching helper struct
3314template <class T> struct identity_tag {};
3315} // namespace detail
3316} // namespace nlohmann
3317
3318// #include <nlohmann/detail/meta/type_traits.hpp>
3319
3320
3321#include <limits> // numeric_limits
3322#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3323#include <utility> // declval
3324#include <tuple> // tuple
3325
3326// #include <nlohmann/detail/macro_scope.hpp>
3327
3328
3329// #include <nlohmann/detail/iterators/iterator_traits.hpp>
3330
3331
3332#include <iterator> // random_access_iterator_tag
3333
3334// #include <nlohmann/detail/meta/void_t.hpp>
3335
3336// #include <nlohmann/detail/meta/cpp_future.hpp>
3337
3338
3339namespace nlohmann
3340{
3341namespace detail
3342{
3343template<typename It, typename = void>
3344struct iterator_types {};
3345
3346template<typename It>
3347struct iterator_types <
3348 It,
3349 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3350 typename It::reference, typename It::iterator_category >>
3351{
3352 using difference_type = typename It::difference_type;
3353 using value_type = typename It::value_type;
3354 using pointer = typename It::pointer;
3355 using reference = typename It::reference;
3356 using iterator_category = typename It::iterator_category;
3357};
3358
3359// This is required as some compilers implement std::iterator_traits in a way that
3360// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3361template<typename T, typename = void>
3362struct iterator_traits
3363{
3364};
3365
3366template<typename T>
3367struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3368 : iterator_types<T>
3369{
3370};
3371
3372template<typename T>
3373struct iterator_traits<T*, enable_if_t<std::is_object<T>::value>>
3374{
3375 using iterator_category = std::random_access_iterator_tag;
3376 using value_type = T;
3377 using difference_type = ptrdiff_t;
3378 using pointer = T*;
3379 using reference = T&;
3380};
3381} // namespace detail
3382} // namespace nlohmann
3383
3384// #include <nlohmann/detail/meta/call_std/begin.hpp>
3385
3386
3387// #include <nlohmann/detail/macro_scope.hpp>
3388
3389
3390namespace nlohmann
3391{
3393} // namespace nlohmann
3394
3395// #include <nlohmann/detail/meta/call_std/end.hpp>
3396
3397
3398// #include <nlohmann/detail/macro_scope.hpp>
3399
3400
3401namespace nlohmann
3402{
3404} // namespace nlohmann
3405
3406// #include <nlohmann/detail/meta/cpp_future.hpp>
3407
3408// #include <nlohmann/detail/meta/detected.hpp>
3409
3410// #include <nlohmann/json_fwd.hpp>
3411#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3412#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3413
3414#include <cstdint> // int64_t, uint64_t
3415#include <map> // map
3416#include <memory> // allocator
3417#include <string> // string
3418#include <vector> // vector
3419
3425namespace nlohmann
3426{
3434template<typename T = void, typename SFINAE = void>
3435struct adl_serializer;
3436
3437template<template<typename U, typename V, typename... Args> class ObjectType =
3438 std::map,
3439 template<typename U, typename... Args> class ArrayType = std::vector,
3440 class StringType = std::string, class BooleanType = bool,
3441 class NumberIntegerType = std::int64_t,
3442 class NumberUnsignedType = std::uint64_t,
3443 class NumberFloatType = double,
3444 template<typename U> class AllocatorType = std::allocator,
3445 template<typename T, typename SFINAE = void> class JSONSerializer =
3446 adl_serializer,
3447 class BinaryType = std::vector<std::uint8_t>>
3448class basic_json;
3449
3461template<typename BasicJsonType>
3462class json_pointer;
3463
3473
3474template<class Key, class T, class IgnoredLess, class Allocator>
3475struct ordered_map;
3476
3485
3486} // namespace nlohmann
3487
3488#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3489
3490
3491namespace nlohmann
3492{
3501namespace detail
3502{
3504// helpers //
3506
3507// Note to maintainers:
3508//
3509// Every trait in this file expects a non CV-qualified type.
3510// The only exceptions are in the 'aliases for detected' section
3511// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3512//
3513// In this case, T has to be properly CV-qualified to constraint the function arguments
3514// (e.g. to_json(BasicJsonType&, const T&))
3515
3516template<typename> struct is_basic_json : std::false_type {};
3517
3518NLOHMANN_BASIC_JSON_TPL_DECLARATION
3519struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3520
3522// json_ref helpers //
3524
3525template<typename>
3526class json_ref;
3527
3528template<typename>
3529struct is_json_ref : std::false_type {};
3530
3531template<typename T>
3532struct is_json_ref<json_ref<T>> : std::true_type {};
3533
3535// aliases for detected //
3537
3538template<typename T>
3539using mapped_type_t = typename T::mapped_type;
3540
3541template<typename T>
3542using key_type_t = typename T::key_type;
3543
3544template<typename T>
3545using value_type_t = typename T::value_type;
3546
3547template<typename T>
3548using difference_type_t = typename T::difference_type;
3549
3550template<typename T>
3551using pointer_t = typename T::pointer;
3552
3553template<typename T>
3554using reference_t = typename T::reference;
3555
3556template<typename T>
3557using iterator_category_t = typename T::iterator_category;
3558
3559template<typename T, typename... Args>
3560using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3561
3562template<typename T, typename... Args>
3563using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3564
3565template<typename T, typename U>
3566using get_template_function = decltype(std::declval<T>().template get<U>());
3567
3568// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3569template<typename BasicJsonType, typename T, typename = void>
3570struct has_from_json : std::false_type {};
3571
3572// trait checking if j.get<T> is valid
3573// use this trait instead of std::is_constructible or std::is_convertible,
3574// both rely on, or make use of implicit conversions, and thus fail when T
3575// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3576template <typename BasicJsonType, typename T>
3577struct is_getable
3578{
3579 static constexpr bool value = is_detected<get_template_function, const BasicJsonType&, T>::value;
3580};
3581
3582template<typename BasicJsonType, typename T>
3583struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3584{
3585 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3586
3587 static constexpr bool value =
3588 is_detected_exact<void, from_json_function, serializer,
3589 const BasicJsonType&, T&>::value;
3590};
3591
3592// This trait checks if JSONSerializer<T>::from_json(json const&) exists
3593// this overload is used for non-default-constructible user-defined-types
3594template<typename BasicJsonType, typename T, typename = void>
3595struct has_non_default_from_json : std::false_type {};
3596
3597template<typename BasicJsonType, typename T>
3598struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3599{
3600 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3601
3602 static constexpr bool value =
3603 is_detected_exact<T, from_json_function, serializer,
3604 const BasicJsonType&>::value;
3605};
3606
3607// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3608// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3609template<typename BasicJsonType, typename T, typename = void>
3610struct has_to_json : std::false_type {};
3611
3612template<typename BasicJsonType, typename T>
3613struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3614{
3615 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3616
3617 static constexpr bool value =
3618 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3619 T>::value;
3620};
3621
3622
3624// is_ functions //
3626
3627// https://en.cppreference.com/w/cpp/types/conjunction
3628template<class...> struct conjunction : std::true_type { };
3629template<class B1> struct conjunction<B1> : B1 { };
3630template<class B1, class... Bn>
3631struct conjunction<B1, Bn...>
3632: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3633
3634// https://en.cppreference.com/w/cpp/types/negation
3635template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3636
3637// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3638// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3639// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3640template <typename T>
3641struct is_default_constructible : std::is_default_constructible<T> {};
3642
3643template <typename T1, typename T2>
3644struct is_default_constructible<std::pair<T1, T2>>
3645 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3646
3647template <typename T1, typename T2>
3648struct is_default_constructible<const std::pair<T1, T2>>
3649 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3650
3651template <typename... Ts>
3652struct is_default_constructible<std::tuple<Ts...>>
3653 : conjunction<is_default_constructible<Ts>...> {};
3654
3655template <typename... Ts>
3656struct is_default_constructible<const std::tuple<Ts...>>
3657 : conjunction<is_default_constructible<Ts>...> {};
3658
3659
3660template <typename T, typename... Args>
3661struct is_constructible : std::is_constructible<T, Args...> {};
3662
3663template <typename T1, typename T2>
3664struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3665
3666template <typename T1, typename T2>
3667struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3668
3669template <typename... Ts>
3670struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3671
3672template <typename... Ts>
3673struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3674
3675
3676template<typename T, typename = void>
3677struct is_iterator_traits : std::false_type {};
3678
3679template<typename T>
3680struct is_iterator_traits<iterator_traits<T>>
3681{
3682 private:
3683 using traits = iterator_traits<T>;
3684
3685 public:
3686 static constexpr auto value =
3687 is_detected<value_type_t, traits>::value &&
3688 is_detected<difference_type_t, traits>::value &&
3689 is_detected<pointer_t, traits>::value &&
3690 is_detected<iterator_category_t, traits>::value &&
3691 is_detected<reference_t, traits>::value;
3692};
3693
3694template<typename T>
3695struct is_range
3696{
3697 private:
3698 using t_ref = typename std::add_lvalue_reference<T>::type;
3699
3700 using iterator = detected_t<result_of_begin, t_ref>;
3701 using sentinel = detected_t<result_of_end, t_ref>;
3702
3703 // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3704 // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3705 // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3706 static constexpr auto is_iterator_begin =
3707 is_iterator_traits<iterator_traits<iterator>>::value;
3708
3709 public:
3710 static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3711};
3712
3713template<typename R>
3714using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3715
3716template<typename T>
3717using range_value_t = value_type_t<iterator_traits<iterator_t<T>>>;
3718
3719// The following implementation of is_complete_type is taken from
3720// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3721// and is written by Xiang Fan who agreed to using it in this library.
3722
3723template<typename T, typename = void>
3724struct is_complete_type : std::false_type {};
3725
3726template<typename T>
3727struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3728
3729template<typename BasicJsonType, typename CompatibleObjectType,
3730 typename = void>
3731struct is_compatible_object_type_impl : std::false_type {};
3732
3733template<typename BasicJsonType, typename CompatibleObjectType>
3734struct is_compatible_object_type_impl <
3735 BasicJsonType, CompatibleObjectType,
3736 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3737 is_detected<key_type_t, CompatibleObjectType>::value >>
3738{
3739 using object_t = typename BasicJsonType::object_t;
3740
3741 // macOS's is_constructible does not play well with nonesuch...
3742 static constexpr bool value =
3743 is_constructible<typename object_t::key_type,
3744 typename CompatibleObjectType::key_type>::value &&
3745 is_constructible<typename object_t::mapped_type,
3746 typename CompatibleObjectType::mapped_type>::value;
3747};
3748
3749template<typename BasicJsonType, typename CompatibleObjectType>
3750struct is_compatible_object_type
3751 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3752
3753template<typename BasicJsonType, typename ConstructibleObjectType,
3754 typename = void>
3755struct is_constructible_object_type_impl : std::false_type {};
3756
3757template<typename BasicJsonType, typename ConstructibleObjectType>
3758struct is_constructible_object_type_impl <
3759 BasicJsonType, ConstructibleObjectType,
3760 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3761 is_detected<key_type_t, ConstructibleObjectType>::value >>
3762{
3763 using object_t = typename BasicJsonType::object_t;
3764
3765 static constexpr bool value =
3766 (is_default_constructible<ConstructibleObjectType>::value &&
3767 (std::is_move_assignable<ConstructibleObjectType>::value ||
3768 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3769 (is_constructible<typename ConstructibleObjectType::key_type,
3770 typename object_t::key_type>::value &&
3771 std::is_same <
3772 typename object_t::mapped_type,
3773 typename ConstructibleObjectType::mapped_type >::value)) ||
3774 (has_from_json<BasicJsonType,
3775 typename ConstructibleObjectType::mapped_type>::value ||
3776 has_non_default_from_json <
3777 BasicJsonType,
3778 typename ConstructibleObjectType::mapped_type >::value);
3779};
3780
3781template<typename BasicJsonType, typename ConstructibleObjectType>
3782struct is_constructible_object_type
3783 : is_constructible_object_type_impl<BasicJsonType,
3784 ConstructibleObjectType> {};
3785
3786template<typename BasicJsonType, typename CompatibleStringType,
3787 typename = void>
3788struct is_compatible_string_type_impl : std::false_type {};
3789
3790template<typename BasicJsonType, typename CompatibleStringType>
3791struct is_compatible_string_type_impl <
3792 BasicJsonType, CompatibleStringType,
3793 enable_if_t<is_detected_convertible<typename BasicJsonType::string_t::value_type,
3794 range_value_t,
3795 CompatibleStringType>::value >>
3796{
3797 static constexpr auto value =
3798 is_constructible<typename BasicJsonType::string_t, CompatibleStringType>::value;
3799};
3800
3801template<typename BasicJsonType, typename ConstructibleStringType>
3802struct is_compatible_string_type
3803 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3804
3805template<typename BasicJsonType, typename ConstructibleStringType,
3806 typename = void>
3807struct is_constructible_string_type_impl : std::false_type {};
3808
3809template<typename BasicJsonType, typename ConstructibleStringType>
3810struct is_constructible_string_type_impl <
3811 BasicJsonType, ConstructibleStringType,
3812 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3813 value_type_t, ConstructibleStringType>::value >>
3814{
3815 static constexpr auto value =
3816 is_constructible<ConstructibleStringType,
3817 typename BasicJsonType::string_t>::value;
3818};
3819
3820template<typename BasicJsonType, typename ConstructibleStringType>
3821struct is_constructible_string_type
3822 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3823
3824template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3825struct is_compatible_array_type_impl : std::false_type {};
3826
3827template<typename BasicJsonType, typename CompatibleArrayType>
3828struct is_compatible_array_type_impl <
3829 BasicJsonType, CompatibleArrayType,
3830 enable_if_t <
3831 is_detected<iterator_t, CompatibleArrayType>::value&&
3832 is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value >>
3833{
3834 static constexpr bool value =
3835 is_constructible<BasicJsonType,
3836 range_value_t<CompatibleArrayType>>::value;
3837};
3838
3839template<typename BasicJsonType, typename CompatibleArrayType>
3840struct is_compatible_array_type
3841 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3842
3843template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3844struct is_constructible_array_type_impl : std::false_type {};
3845
3846template<typename BasicJsonType, typename ConstructibleArrayType>
3847struct is_constructible_array_type_impl <
3848 BasicJsonType, ConstructibleArrayType,
3849 enable_if_t<std::is_same<ConstructibleArrayType,
3850 typename BasicJsonType::value_type>::value >>
3851 : std::true_type {};
3852
3853template<typename BasicJsonType, typename ConstructibleArrayType>
3854struct is_constructible_array_type_impl <
3855 BasicJsonType, ConstructibleArrayType,
3856 enable_if_t < !std::is_same<ConstructibleArrayType,
3857 typename BasicJsonType::value_type>::value&&
3858 !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3859 is_default_constructible<ConstructibleArrayType>::value&&
3860(std::is_move_assignable<ConstructibleArrayType>::value ||
3861 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3862is_detected<iterator_t, ConstructibleArrayType>::value&&
3863is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3864is_detected<range_value_t, ConstructibleArrayType>::value&&
3865is_complete_type <
3866detected_t<range_value_t, ConstructibleArrayType >>::value >>
3867{
3868 using value_type = range_value_t<ConstructibleArrayType>;
3869
3870 static constexpr bool value =
3871 std::is_same<value_type,
3872 typename BasicJsonType::array_t::value_type>::value ||
3873 has_from_json<BasicJsonType,
3874 value_type>::value ||
3875 has_non_default_from_json <
3876 BasicJsonType,
3877 value_type >::value;
3878};
3879
3880template<typename BasicJsonType, typename ConstructibleArrayType>
3881struct is_constructible_array_type
3882 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3883
3884template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3885 typename = void>
3886struct is_compatible_integer_type_impl : std::false_type {};
3887
3888template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3889struct is_compatible_integer_type_impl <
3890 RealIntegerType, CompatibleNumberIntegerType,
3891 enable_if_t < std::is_integral<RealIntegerType>::value&&
3892 std::is_integral<CompatibleNumberIntegerType>::value&&
3893 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3894{
3895 // is there an assert somewhere on overflows?
3896 using RealLimits = std::numeric_limits<RealIntegerType>;
3897 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3898
3899 static constexpr auto value =
3900 is_constructible<RealIntegerType,
3901 CompatibleNumberIntegerType>::value &&
3902 CompatibleLimits::is_integer &&
3903 RealLimits::is_signed == CompatibleLimits::is_signed;
3904};
3905
3906template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3907struct is_compatible_integer_type
3908 : is_compatible_integer_type_impl<RealIntegerType,
3909 CompatibleNumberIntegerType> {};
3910
3911template<typename BasicJsonType, typename CompatibleType, typename = void>
3912struct is_compatible_type_impl: std::false_type {};
3913
3914template<typename BasicJsonType, typename CompatibleType>
3915struct is_compatible_type_impl <
3916 BasicJsonType, CompatibleType,
3917 enable_if_t<is_complete_type<CompatibleType>::value >>
3918{
3919 static constexpr bool value =
3920 has_to_json<BasicJsonType, CompatibleType>::value;
3921};
3922
3923template<typename BasicJsonType, typename CompatibleType>
3924struct is_compatible_type
3925 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3926
3927template<typename T1, typename T2>
3928struct is_constructible_tuple : std::false_type {};
3929
3930template<typename T1, typename... Args>
3931struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3932
3933// a naive helper to check if a type is an ordered_map (exploits the fact that
3934// ordered_map inherits capacity() from std::vector)
3935template <typename T>
3936struct is_ordered_map
3937{
3938 using one = char;
3939
3940 struct two
3941 {
3942 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3943 };
3944
3945 template <typename C> static one test( decltype(&C::capacity) ) ;
3946 template <typename C> static two test(...);
3947
3948 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3949};
3950
3951// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3952template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3953T conditional_static_cast(U value)
3954{
3955 return static_cast<T>(value);
3956}
3957
3958template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3959T conditional_static_cast(U value)
3960{
3961 return value;
3962}
3963
3964} // namespace detail
3965} // namespace nlohmann
3966
3967// #include <nlohmann/detail/value_t.hpp>
3968
3969
3970namespace nlohmann
3971{
3972namespace detail
3973{
3974template<typename BasicJsonType>
3975void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3976{
3977 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3978 {
3979 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
3980 }
3981 n = nullptr;
3982}
3983
3984// overloads for basic_json template parameters
3985template < typename BasicJsonType, typename ArithmeticType,
3986 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3987 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3988 int > = 0 >
3989void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3990{
3991 switch (static_cast<value_t>(j))
3992 {
3993 case value_t::number_unsigned:
3994 {
3995 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3996 break;
3997 }
3998 case value_t::number_integer:
3999 {
4000 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4001 break;
4002 }
4003 case value_t::number_float:
4004 {
4005 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4006 break;
4007 }
4008
4009 case value_t::null:
4010 case value_t::object:
4011 case value_t::array:
4012 case value_t::string:
4013 case value_t::boolean:
4014 case value_t::binary:
4015 case value_t::discarded:
4016 default:
4017 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4018 }
4019}
4020
4021template<typename BasicJsonType>
4022void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4023{
4024 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4025 {
4026 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
4027 }
4028 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4029}
4030
4031template<typename BasicJsonType>
4032void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4033{
4034 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4035 {
4036 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4037 }
4038 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4039}
4040
4041template <
4042 typename BasicJsonType, typename ConstructibleStringType,
4043 enable_if_t <
4044 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
4045 !std::is_same<typename BasicJsonType::string_t,
4046 ConstructibleStringType>::value,
4047 int > = 0 >
4048void from_json(const BasicJsonType& j, ConstructibleStringType& s)
4049{
4050 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4051 {
4052 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
4053 }
4054
4055 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4056}
4057
4058template<typename BasicJsonType>
4059void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4060{
4061 get_arithmetic_value(j, val);
4062}
4063
4064template<typename BasicJsonType>
4065void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4066{
4067 get_arithmetic_value(j, val);
4068}
4069
4070template<typename BasicJsonType>
4071void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4072{
4073 get_arithmetic_value(j, val);
4074}
4075
4076template<typename BasicJsonType, typename EnumType,
4077 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4078void from_json(const BasicJsonType& j, EnumType& e)
4079{
4080 typename std::underlying_type<EnumType>::type val;
4081 get_arithmetic_value(j, val);
4082 e = static_cast<EnumType>(val);
4083}
4084
4085// forward_list doesn't have an insert method
4086template<typename BasicJsonType, typename T, typename Allocator,
4087 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4088void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4089{
4090 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4091 {
4092 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4093 }
4094 l.clear();
4095 std::transform(j.rbegin(), j.rend(),
4096 std::front_inserter(l), [](const BasicJsonType & i)
4097 {
4098 return i.template get<T>();
4099 });
4100}
4101
4102// valarray doesn't have an insert method
4103template<typename BasicJsonType, typename T,
4104 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4105void from_json(const BasicJsonType& j, std::valarray<T>& l)
4106{
4107 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4108 {
4109 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4110 }
4111 l.resize(j.size());
4112 std::transform(j.begin(), j.end(), std::begin(l),
4113 [](const BasicJsonType & elem)
4114 {
4115 return elem.template get<T>();
4116 });
4117}
4118
4119template<typename BasicJsonType, typename T, std::size_t N>
4120auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4121-> decltype(j.template get<T>(), void())
4122{
4123 for (std::size_t i = 0; i < N; ++i)
4124 {
4125 arr[i] = j.at(i).template get<T>();
4126 }
4127}
4128
4129template<typename BasicJsonType>
4130void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4131{
4132 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4133}
4134
4135template<typename BasicJsonType, typename T, std::size_t N>
4136auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4137 priority_tag<2> /*unused*/)
4138-> decltype(j.template get<T>(), void())
4139{
4140 for (std::size_t i = 0; i < N; ++i)
4141 {
4142 arr[i] = j.at(i).template get<T>();
4143 }
4144}
4145
4146template<typename BasicJsonType, typename ConstructibleArrayType,
4147 enable_if_t<
4148 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4149 int> = 0>
4150auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4151-> decltype(
4152 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4153 j.template get<typename ConstructibleArrayType::value_type>(),
4154 void())
4155{
4156 using std::end;
4157
4158 ConstructibleArrayType ret;
4159 ret.reserve(j.size());
4160 std::transform(j.begin(), j.end(),
4161 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4162 {
4163 // get<BasicJsonType>() returns *this, this won't call a from_json
4164 // method when value_type is BasicJsonType
4165 return i.template get<typename ConstructibleArrayType::value_type>();
4166 });
4167 arr = std::move(ret);
4168}
4169
4170template<typename BasicJsonType, typename ConstructibleArrayType,
4171 enable_if_t<
4172 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4173 int> = 0>
4174void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4175 priority_tag<0> /*unused*/)
4176{
4177 using std::end;
4178
4179 ConstructibleArrayType ret;
4180 std::transform(
4181 j.begin(), j.end(), std::inserter(ret, end(ret)),
4182 [](const BasicJsonType & i)
4183 {
4184 // get<BasicJsonType>() returns *this, this won't call a from_json
4185 // method when value_type is BasicJsonType
4186 return i.template get<typename ConstructibleArrayType::value_type>();
4187 });
4188 arr = std::move(ret);
4189}
4190
4191template < typename BasicJsonType, typename ConstructibleArrayType,
4192 enable_if_t <
4193 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4194 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4195 !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
4196 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4197 !is_basic_json<ConstructibleArrayType>::value,
4198 int > = 0 >
4199auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4200-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4201j.template get<typename ConstructibleArrayType::value_type>(),
4202void())
4203{
4204 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4205 {
4206 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4207 }
4208
4209 from_json_array_impl(j, arr, priority_tag<3> {});
4210}
4211
4212template < typename BasicJsonType, typename T, std::size_t... Idx >
4213std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4214 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4215{
4216 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4217}
4218
4219template < typename BasicJsonType, typename T, std::size_t N >
4220auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4221-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4222{
4223 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4224 {
4225 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4226 }
4227
4228 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4229}
4230
4231template<typename BasicJsonType>
4232void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4233{
4234 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4235 {
4236 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
4237 }
4238
4239 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4240}
4241
4242template<typename BasicJsonType, typename ConstructibleObjectType,
4243 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4244void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4245{
4246 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4247 {
4248 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
4249 }
4250
4251 ConstructibleObjectType ret;
4252 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4253 using value_type = typename ConstructibleObjectType::value_type;
4254 std::transform(
4255 inner_object->begin(), inner_object->end(),
4256 std::inserter(ret, ret.begin()),
4257 [](typename BasicJsonType::object_t::value_type const & p)
4258 {
4259 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4260 });
4261 obj = std::move(ret);
4262}
4263
4264// overload for arithmetic types, not chosen for basic_json template arguments
4265// (BooleanType, etc..); note: Is it really necessary to provide explicit
4266// overloads for boolean_t etc. in case of a custom BooleanType which is not
4267// an arithmetic type?
4268template < typename BasicJsonType, typename ArithmeticType,
4269 enable_if_t <
4270 std::is_arithmetic<ArithmeticType>::value&&
4271 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4272 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4273 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4274 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4275 int > = 0 >
4276void from_json(const BasicJsonType& j, ArithmeticType& val)
4277{
4278 switch (static_cast<value_t>(j))
4279 {
4280 case value_t::number_unsigned:
4281 {
4282 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4283 break;
4284 }
4285 case value_t::number_integer:
4286 {
4287 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4288 break;
4289 }
4290 case value_t::number_float:
4291 {
4292 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4293 break;
4294 }
4295 case value_t::boolean:
4296 {
4297 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4298 break;
4299 }
4300
4301 case value_t::null:
4302 case value_t::object:
4303 case value_t::array:
4304 case value_t::string:
4305 case value_t::binary:
4306 case value_t::discarded:
4307 default:
4308 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4309 }
4310}
4311
4312template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4313std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4314{
4315 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4316}
4317
4318template < typename BasicJsonType, class A1, class A2 >
4319std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4320{
4321 return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4322 std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4323}
4324
4325template<typename BasicJsonType, typename A1, typename A2>
4326void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4327{
4328 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4329}
4330
4331template<typename BasicJsonType, typename... Args>
4332std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4333{
4334 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4335}
4336
4337template<typename BasicJsonType, typename... Args>
4338void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4339{
4340 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4341}
4342
4343template<typename BasicJsonType, typename TupleRelated>
4344auto from_json(BasicJsonType&& j, TupleRelated&& t)
4345-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4346{
4347 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4348 {
4349 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4350 }
4351
4352 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4353}
4354
4355template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4356 typename = enable_if_t < !std::is_constructible <
4357 typename BasicJsonType::string_t, Key >::value >>
4358void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4359{
4360 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4361 {
4362 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4363 }
4364 m.clear();
4365 for (const auto& p : j)
4366 {
4367 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4368 {
4369 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4370 }
4371 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4372 }
4373}
4374
4375template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4376 typename = enable_if_t < !std::is_constructible <
4377 typename BasicJsonType::string_t, Key >::value >>
4378void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4379{
4380 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4381 {
4382 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4383 }
4384 m.clear();
4385 for (const auto& p : j)
4386 {
4387 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4388 {
4389 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4390 }
4391 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4392 }
4393}
4394
4395struct from_json_fn
4396{
4397 template<typename BasicJsonType, typename T>
4398 auto operator()(const BasicJsonType& j, T&& val) const
4399 noexcept(noexcept(from_json(j, std::forward<T>(val))))
4400 -> decltype(from_json(j, std::forward<T>(val)))
4401 {
4402 return from_json(j, std::forward<T>(val));
4403 }
4404};
4405} // namespace detail
4406
4410namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4411{
4412constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4413} // namespace
4414} // namespace nlohmann
4415
4416// #include <nlohmann/detail/conversions/to_json.hpp>
4417
4418
4419#include <algorithm> // copy
4420#include <iterator> // begin, end
4421#include <string> // string
4422#include <tuple> // tuple, get
4423#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4424#include <utility> // move, forward, declval, pair
4425#include <valarray> // valarray
4426#include <vector> // vector
4427
4428// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4429
4430
4431#include <cstddef> // size_t
4432#include <iterator> // input_iterator_tag
4433#include <string> // string, to_string
4434#include <tuple> // tuple_size, get, tuple_element
4435#include <utility> // move
4436
4437// #include <nlohmann/detail/meta/type_traits.hpp>
4438
4439// #include <nlohmann/detail/value_t.hpp>
4440
4441
4442namespace nlohmann
4443{
4444namespace detail
4445{
4446template<typename string_type>
4447void int_to_string( string_type& target, std::size_t value )
4448{
4449 // For ADL
4450 using std::to_string;
4451 target = to_string(value);
4452}
4453template<typename IteratorType> class iteration_proxy_value
4454{
4455 public:
4456 using difference_type = std::ptrdiff_t;
4457 using value_type = iteration_proxy_value;
4458 using pointer = value_type * ;
4459 using reference = value_type & ;
4460 using iterator_category = std::input_iterator_tag;
4461 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4462
4463 private:
4465 IteratorType anchor;
4467 std::size_t array_index = 0;
4469 mutable std::size_t array_index_last = 0;
4471 mutable string_type array_index_str = "0";
4473 const string_type empty_str{};
4474
4475 public:
4476 explicit iteration_proxy_value(IteratorType it) noexcept
4477 : anchor(std::move(it))
4478 {}
4479
4481 iteration_proxy_value& operator*()
4482 {
4483 return *this;
4484 }
4485
4487 iteration_proxy_value& operator++()
4488 {
4489 ++anchor;
4490 ++array_index;
4491
4492 return *this;
4493 }
4494
4496 bool operator==(const iteration_proxy_value& o) const
4497 {
4498 return anchor == o.anchor;
4499 }
4500
4502 bool operator!=(const iteration_proxy_value& o) const
4503 {
4504 return anchor != o.anchor;
4505 }
4506
4508 const string_type& key() const
4509 {
4510 JSON_ASSERT(anchor.m_object != nullptr);
4511
4512 switch (anchor.m_object->type())
4513 {
4514 // use integer array index as key
4515 case value_t::array:
4516 {
4517 if (array_index != array_index_last)
4518 {
4519 int_to_string( array_index_str, array_index );
4520 array_index_last = array_index;
4521 }
4522 return array_index_str;
4523 }
4524
4525 // use key from the object
4526 case value_t::object:
4527 return anchor.key();
4528
4529 // use an empty key for all primitive types
4530 case value_t::null:
4531 case value_t::string:
4532 case value_t::boolean:
4533 case value_t::number_integer:
4534 case value_t::number_unsigned:
4535 case value_t::number_float:
4536 case value_t::binary:
4537 case value_t::discarded:
4538 default:
4539 return empty_str;
4540 }
4541 }
4542
4544 typename IteratorType::reference value() const
4545 {
4546 return anchor.value();
4547 }
4548};
4549
4551template<typename IteratorType> class iteration_proxy
4552{
4553 private:
4555 typename IteratorType::reference container;
4556
4557 public:
4559 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4560 : container(cont) {}
4561
4563 iteration_proxy_value<IteratorType> begin() noexcept
4564 {
4565 return iteration_proxy_value<IteratorType>(container.begin());
4566 }
4567
4569 iteration_proxy_value<IteratorType> end() noexcept
4570 {
4571 return iteration_proxy_value<IteratorType>(container.end());
4572 }
4573};
4574// Structured Bindings Support
4575// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4576// And see https://github.com/nlohmann/json/pull/1391
4577template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4578auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.key())
4579{
4580 return i.key();
4581}
4582// Structured Bindings Support
4583// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4584// And see https://github.com/nlohmann/json/pull/1391
4585template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4586auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4587{
4588 return i.value();
4589}
4590} // namespace detail
4591} // namespace nlohmann
4592
4593// The Addition to the STD Namespace is required to add
4594// Structured Bindings Support to the iteration_proxy_value class
4595// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4596// And see https://github.com/nlohmann/json/pull/1391
4597namespace std
4598{
4599#if defined(__clang__)
4600 // Fix: https://github.com/nlohmann/json/issues/1401
4601 #pragma clang diagnostic push
4602 #pragma clang diagnostic ignored "-Wmismatched-tags"
4603#endif
4604template<typename IteratorType>
4605class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4606 : public std::integral_constant<std::size_t, 2> {};
4607
4608template<std::size_t N, typename IteratorType>
4609class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4610{
4611 public:
4612 using type = decltype(
4613 get<N>(std::declval <
4614 ::nlohmann::detail::iteration_proxy_value<IteratorType >> ()));
4615};
4616#if defined(__clang__)
4617 #pragma clang diagnostic pop
4618#endif
4619} // namespace std
4620
4621// #include <nlohmann/detail/meta/cpp_future.hpp>
4622
4623// #include <nlohmann/detail/meta/type_traits.hpp>
4624
4625// #include <nlohmann/detail/value_t.hpp>
4626
4627
4628namespace nlohmann
4629{
4630namespace detail
4631{
4633// constructors //
4635
4636/*
4637 * Note all external_constructor<>::construct functions need to call
4638 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4639 * allocated value (e.g., a string). See bug issue
4640 * https://github.com/nlohmann/json/issues/2865 for more information.
4641 */
4642
4643template<value_t> struct external_constructor;
4644
4645template<>
4646struct external_constructor<value_t::boolean>
4647{
4648 template<typename BasicJsonType>
4649 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4650 {
4651 j.m_value.destroy(j.m_type);
4652 j.m_type = value_t::boolean;
4653 j.m_value = b;
4654 j.assert_invariant();
4655 }
4656};
4657
4658template<>
4659struct external_constructor<value_t::string>
4660{
4661 template<typename BasicJsonType>
4662 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4663 {
4664 j.m_value.destroy(j.m_type);
4665 j.m_type = value_t::string;
4666 j.m_value = s;
4667 j.assert_invariant();
4668 }
4669
4670 template<typename BasicJsonType>
4671 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4672 {
4673 j.m_value.destroy(j.m_type);
4674 j.m_type = value_t::string;
4675 j.m_value = std::move(s);
4676 j.assert_invariant();
4677 }
4678
4679 template < typename BasicJsonType, typename CompatibleStringType,
4680 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4681 int > = 0 >
4682 static void construct(BasicJsonType& j, const CompatibleStringType& str)
4683 {
4684 j.m_value.destroy(j.m_type);
4685 j.m_type = value_t::string;
4686 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4687 j.assert_invariant();
4688 }
4689};
4690
4691template<>
4692struct external_constructor<value_t::binary>
4693{
4694 template<typename BasicJsonType>
4695 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4696 {
4697 j.m_value.destroy(j.m_type);
4698 j.m_type = value_t::binary;
4699 j.m_value = typename BasicJsonType::binary_t(b);
4700 j.assert_invariant();
4701 }
4702
4703 template<typename BasicJsonType>
4704 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4705 {
4706 j.m_value.destroy(j.m_type);
4707 j.m_type = value_t::binary;
4708 j.m_value = typename BasicJsonType::binary_t(std::move(b));
4709 j.assert_invariant();
4710 }
4711};
4712
4713template<>
4714struct external_constructor<value_t::number_float>
4715{
4716 template<typename BasicJsonType>
4717 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4718 {
4719 j.m_value.destroy(j.m_type);
4720 j.m_type = value_t::number_float;
4721 j.m_value = val;
4722 j.assert_invariant();
4723 }
4724};
4725
4726template<>
4727struct external_constructor<value_t::number_unsigned>
4728{
4729 template<typename BasicJsonType>
4730 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4731 {
4732 j.m_value.destroy(j.m_type);
4733 j.m_type = value_t::number_unsigned;
4734 j.m_value = val;
4735 j.assert_invariant();
4736 }
4737};
4738
4739template<>
4740struct external_constructor<value_t::number_integer>
4741{
4742 template<typename BasicJsonType>
4743 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4744 {
4745 j.m_value.destroy(j.m_type);
4746 j.m_type = value_t::number_integer;
4747 j.m_value = val;
4748 j.assert_invariant();
4749 }
4750};
4751
4752template<>
4753struct external_constructor<value_t::array>
4754{
4755 template<typename BasicJsonType>
4756 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4757 {
4758 j.m_value.destroy(j.m_type);
4759 j.m_type = value_t::array;
4760 j.m_value = arr;
4761 j.set_parents();
4762 j.assert_invariant();
4763 }
4764
4765 template<typename BasicJsonType>
4766 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4767 {
4768 j.m_value.destroy(j.m_type);
4769 j.m_type = value_t::array;
4770 j.m_value = std::move(arr);
4771 j.set_parents();
4772 j.assert_invariant();
4773 }
4774
4775 template < typename BasicJsonType, typename CompatibleArrayType,
4776 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4777 int > = 0 >
4778 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4779 {
4780 using std::begin;
4781 using std::end;
4782
4783 j.m_value.destroy(j.m_type);
4784 j.m_type = value_t::array;
4785 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4786 j.set_parents();
4787 j.assert_invariant();
4788 }
4789
4790 template<typename BasicJsonType>
4791 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4792 {
4793 j.m_value.destroy(j.m_type);
4794 j.m_type = value_t::array;
4795 j.m_value = value_t::array;
4796 j.m_value.array->reserve(arr.size());
4797 for (const bool x : arr)
4798 {
4799 j.m_value.array->push_back(x);
4800 j.set_parent(j.m_value.array->back());
4801 }
4802 j.assert_invariant();
4803 }
4804
4805 template<typename BasicJsonType, typename T,
4806 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4807 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4808 {
4809 j.m_value.destroy(j.m_type);
4810 j.m_type = value_t::array;
4811 j.m_value = value_t::array;
4812 j.m_value.array->resize(arr.size());
4813 if (arr.size() > 0)
4814 {
4815 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4816 }
4817 j.set_parents();
4818 j.assert_invariant();
4819 }
4820};
4821
4822template<>
4823struct external_constructor<value_t::object>
4824{
4825 template<typename BasicJsonType>
4826 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4827 {
4828 j.m_value.destroy(j.m_type);
4829 j.m_type = value_t::object;
4830 j.m_value = obj;
4831 j.set_parents();
4832 j.assert_invariant();
4833 }
4834
4835 template<typename BasicJsonType>
4836 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4837 {
4838 j.m_value.destroy(j.m_type);
4839 j.m_type = value_t::object;
4840 j.m_value = std::move(obj);
4841 j.set_parents();
4842 j.assert_invariant();
4843 }
4844
4845 template < typename BasicJsonType, typename CompatibleObjectType,
4846 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4847 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4848 {
4849 using std::begin;
4850 using std::end;
4851
4852 j.m_value.destroy(j.m_type);
4853 j.m_type = value_t::object;
4854 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4855 j.set_parents();
4856 j.assert_invariant();
4857 }
4858};
4859
4861// to_json //
4863
4864template<typename BasicJsonType, typename T,
4865 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4866void to_json(BasicJsonType& j, T b) noexcept
4867{
4868 external_constructor<value_t::boolean>::construct(j, b);
4869}
4870
4871template<typename BasicJsonType, typename CompatibleString,
4872 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4873void to_json(BasicJsonType& j, const CompatibleString& s)
4874{
4875 external_constructor<value_t::string>::construct(j, s);
4876}
4877
4878template<typename BasicJsonType>
4879void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4880{
4881 external_constructor<value_t::string>::construct(j, std::move(s));
4882}
4883
4884template<typename BasicJsonType, typename FloatType,
4885 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4886void to_json(BasicJsonType& j, FloatType val) noexcept
4887{
4888 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4889}
4890
4891template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4892 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4893void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4894{
4895 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4896}
4897
4898template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4899 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4900void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4901{
4902 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4903}
4904
4905template<typename BasicJsonType, typename EnumType,
4906 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4907void to_json(BasicJsonType& j, EnumType e) noexcept
4908{
4909 using underlying_type = typename std::underlying_type<EnumType>::type;
4910 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4911}
4912
4913template<typename BasicJsonType>
4914void to_json(BasicJsonType& j, const std::vector<bool>& e)
4915{
4916 external_constructor<value_t::array>::construct(j, e);
4917}
4918
4919template < typename BasicJsonType, typename CompatibleArrayType,
4920 enable_if_t < is_compatible_array_type<BasicJsonType,
4921 CompatibleArrayType>::value&&
4922 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4923 !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4924 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4925 !is_basic_json<CompatibleArrayType>::value,
4926 int > = 0 >
4927void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4928{
4929 external_constructor<value_t::array>::construct(j, arr);
4930}
4931
4932template<typename BasicJsonType>
4933void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4934{
4935 external_constructor<value_t::binary>::construct(j, bin);
4936}
4937
4938template<typename BasicJsonType, typename T,
4939 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4940void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4941{
4942 external_constructor<value_t::array>::construct(j, std::move(arr));
4943}
4944
4945template<typename BasicJsonType>
4946void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4947{
4948 external_constructor<value_t::array>::construct(j, std::move(arr));
4949}
4950
4951template < typename BasicJsonType, typename CompatibleObjectType,
4952 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4953void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4954{
4955 external_constructor<value_t::object>::construct(j, obj);
4956}
4957
4958template<typename BasicJsonType>
4959void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4960{
4961 external_constructor<value_t::object>::construct(j, std::move(obj));
4962}
4963
4964template <
4965 typename BasicJsonType, typename T, std::size_t N,
4966 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4967 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4968 int > = 0 >
4969void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4970{
4971 external_constructor<value_t::array>::construct(j, arr);
4972}
4973
4974template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4975void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4976{
4977 j = { p.first, p.second };
4978}
4979
4980// for https://github.com/nlohmann/json/pull/1134
4981template<typename BasicJsonType, typename T,
4982 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4983void to_json(BasicJsonType& j, const T& b)
4984{
4985 j = { {b.key(), b.value()} };
4986}
4987
4988template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4989void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4990{
4991 j = { std::get<Idx>(t)... };
4992}
4993
4994template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4995void to_json(BasicJsonType& j, const T& t)
4996{
4997 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4998}
4999
5000struct to_json_fn
5001{
5002 template<typename BasicJsonType, typename T>
5003 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5004 -> decltype(to_json(j, std::forward<T>(val)), void())
5005 {
5006 return to_json(j, std::forward<T>(val));
5007 }
5008};
5009} // namespace detail
5010
5014namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5015{
5016constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
5017} // namespace
5018} // namespace nlohmann
5019
5020// #include <nlohmann/detail/meta/identity_tag.hpp>
5021
5022// #include <nlohmann/detail/meta/type_traits.hpp>
5023
5024
5025namespace nlohmann
5026{
5027
5028template<typename ValueType, typename>
5030{
5042 template<typename BasicJsonType, typename TargetType = ValueType>
5043 static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
5044 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5045 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5046 {
5047 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5048 }
5049
5062 template<typename BasicJsonType, typename TargetType = ValueType>
5063 static auto from_json(BasicJsonType && j) noexcept(
5064 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5065 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5066 {
5067 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5068 }
5069
5079 template<typename BasicJsonType, typename TargetType = ValueType>
5080 static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5081 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5082 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5083 {
5084 ::nlohmann::to_json(j, std::forward<TargetType>(val));
5085 }
5086};
5087} // namespace nlohmann
5088
5089// #include <nlohmann/byte_container_with_subtype.hpp>
5090
5091
5092#include <cstdint> // uint8_t, uint64_t
5093#include <tuple> // tie
5094#include <utility> // move
5095
5096namespace nlohmann
5097{
5098
5112template<typename BinaryType>
5113class byte_container_with_subtype : public BinaryType
5114{
5115 public:
5117 using container_type = BinaryType;
5119 using subtype_type = std::uint64_t;
5120
5122 : container_type()
5123 {}
5124
5126 : container_type(b)
5127 {}
5128
5129 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5130 : container_type(std::move(b))
5131 {}
5132
5134 : container_type(b)
5135 , m_subtype(subtype_)
5136 , m_has_subtype(true)
5137 {}
5138
5139 byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5140 : container_type(std::move(b))
5141 , m_subtype(subtype_)
5142 , m_has_subtype(true)
5143 {}
5144
5146 {
5147 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5148 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5149 }
5150
5152 {
5153 return !(rhs == *this);
5154 }
5155
5174 void set_subtype(subtype_type subtype_) noexcept
5175 {
5176 m_subtype = subtype_;
5177 m_has_subtype = true;
5178 }
5179
5202 constexpr subtype_type subtype() const noexcept
5203 {
5204 return m_has_subtype ? m_subtype : subtype_type(-1);
5205 }
5206
5223 constexpr bool has_subtype() const noexcept
5224 {
5225 return m_has_subtype;
5226 }
5227
5247 void clear_subtype() noexcept
5248 {
5249 m_subtype = 0;
5250 m_has_subtype = false;
5251 }
5252
5253 private:
5254 subtype_type m_subtype = 0;
5255 bool m_has_subtype = false;
5256};
5257
5258} // namespace nlohmann
5259
5260// #include <nlohmann/detail/conversions/from_json.hpp>
5261
5262// #include <nlohmann/detail/conversions/to_json.hpp>
5263
5264// #include <nlohmann/detail/exceptions.hpp>
5265
5266// #include <nlohmann/detail/hash.hpp>
5267
5268
5269#include <cstdint> // uint8_t
5270#include <cstddef> // size_t
5271#include <functional> // hash
5272
5273// #include <nlohmann/detail/macro_scope.hpp>
5274
5275// #include <nlohmann/detail/value_t.hpp>
5276
5277
5278namespace nlohmann
5279{
5280namespace detail
5281{
5282
5283// boost::hash_combine
5284inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5285{
5286 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5287 return seed;
5288}
5289
5301template<typename BasicJsonType>
5302std::size_t hash(const BasicJsonType& j)
5303{
5304 using string_t = typename BasicJsonType::string_t;
5305 using number_integer_t = typename BasicJsonType::number_integer_t;
5306 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5307 using number_float_t = typename BasicJsonType::number_float_t;
5308
5309 const auto type = static_cast<std::size_t>(j.type());
5310 switch (j.type())
5311 {
5312 case BasicJsonType::value_t::null:
5313 case BasicJsonType::value_t::discarded:
5314 {
5315 return combine(type, 0);
5316 }
5317
5318 case BasicJsonType::value_t::object:
5319 {
5320 auto seed = combine(type, j.size());
5321 for (const auto& element : j.items())
5322 {
5323 const auto h = std::hash<string_t> {}(element.key());
5324 seed = combine(seed, h);
5325 seed = combine(seed, hash(element.value()));
5326 }
5327 return seed;
5328 }
5329
5330 case BasicJsonType::value_t::array:
5331 {
5332 auto seed = combine(type, j.size());
5333 for (const auto& element : j)
5334 {
5335 seed = combine(seed, hash(element));
5336 }
5337 return seed;
5338 }
5339
5340 case BasicJsonType::value_t::string:
5341 {
5342 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5343 return combine(type, h);
5344 }
5345
5346 case BasicJsonType::value_t::boolean:
5347 {
5348 const auto h = std::hash<bool> {}(j.template get<bool>());
5349 return combine(type, h);
5350 }
5351
5352 case BasicJsonType::value_t::number_integer:
5353 {
5354 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5355 return combine(type, h);
5356 }
5357
5358 case BasicJsonType::value_t::number_unsigned:
5359 {
5360 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5361 return combine(type, h);
5362 }
5363
5364 case BasicJsonType::value_t::number_float:
5365 {
5366 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5367 return combine(type, h);
5368 }
5369
5370 case BasicJsonType::value_t::binary:
5371 {
5372 auto seed = combine(type, j.get_binary().size());
5373 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5374 seed = combine(seed, h);
5375 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5376 for (const auto byte : j.get_binary())
5377 {
5378 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5379 }
5380 return seed;
5381 }
5382
5383 default: // LCOV_EXCL_LINE
5384 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5385 return 0; // LCOV_EXCL_LINE
5386 }
5387}
5388
5389} // namespace detail
5390} // namespace nlohmann
5391
5392// #include <nlohmann/detail/input/binary_reader.hpp>
5393
5394
5395#include <algorithm> // generate_n
5396#include <array> // array
5397#include <cmath> // ldexp
5398#include <cstddef> // size_t
5399#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5400#include <cstdio> // snprintf
5401#include <cstring> // memcpy
5402#include <iterator> // back_inserter
5403#include <limits> // numeric_limits
5404#include <string> // char_traits, string
5405#include <utility> // make_pair, move
5406#include <vector> // vector
5407
5408// #include <nlohmann/detail/exceptions.hpp>
5409
5410// #include <nlohmann/detail/input/input_adapters.hpp>
5411
5412
5413#include <array> // array
5414#include <cstddef> // size_t
5415#include <cstring> // strlen
5416#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5417#include <memory> // shared_ptr, make_shared, addressof
5418#include <numeric> // accumulate
5419#include <string> // string, char_traits
5420#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5421#include <utility> // pair, declval
5422
5423#ifndef JSON_NO_IO
5424 #include <cstdio> // FILE *
5425 #include <istream> // istream
5426#endif // JSON_NO_IO
5427
5428// #include <nlohmann/detail/iterators/iterator_traits.hpp>
5429
5430// #include <nlohmann/detail/macro_scope.hpp>
5431
5432
5433namespace nlohmann
5434{
5435namespace detail
5436{
5438enum class input_format_t { json, cbor, msgpack, ubjson, bson };
5439
5441// input adapters //
5443
5444#ifndef JSON_NO_IO
5449class file_input_adapter
5450{
5451 public:
5452 using char_type = char;
5453
5454 JSON_HEDLEY_NON_NULL(2)
5455 explicit file_input_adapter(std::FILE* f) noexcept
5456 : m_file(f)
5457 {}
5458
5459 // make class move-only
5460 file_input_adapter(const file_input_adapter&) = delete;
5461 file_input_adapter(file_input_adapter&&) noexcept = default;
5462 file_input_adapter& operator=(const file_input_adapter&) = delete;
5463 file_input_adapter& operator=(file_input_adapter&&) = delete;
5464 ~file_input_adapter() = default;
5465
5466 std::char_traits<char>::int_type get_character() noexcept
5467 {
5468 return std::fgetc(m_file);
5469 }
5470
5471 private:
5473 std::FILE* m_file;
5474};
5475
5476
5486class input_stream_adapter
5487{
5488 public:
5489 using char_type = char;
5490
5491 ~input_stream_adapter()
5492 {
5493 // clear stream flags; we use underlying streambuf I/O, do not
5494 // maintain ifstream flags, except eof
5495 if (is != nullptr)
5496 {
5497 is->clear(is->rdstate() & std::ios::eofbit);
5498 }
5499 }
5500
5501 explicit input_stream_adapter(std::istream& i)
5502 : is(&i), sb(i.rdbuf())
5503 {}
5504
5505 // delete because of pointer members
5506 input_stream_adapter(const input_stream_adapter&) = delete;
5507 input_stream_adapter& operator=(input_stream_adapter&) = delete;
5508 input_stream_adapter& operator=(input_stream_adapter&&) = delete;
5509
5510 input_stream_adapter(input_stream_adapter&& rhs) noexcept
5511 : is(rhs.is), sb(rhs.sb)
5512 {
5513 rhs.is = nullptr;
5514 rhs.sb = nullptr;
5515 }
5516
5517 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5518 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5519 // end up as the same value, eg. 0xFFFFFFFF.
5520 std::char_traits<char>::int_type get_character()
5521 {
5522 auto res = sb->sbumpc();
5523 // set eof manually, as we don't use the istream interface.
5524 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5525 {
5526 is->clear(is->rdstate() | std::ios::eofbit);
5527 }
5528 return res;
5529 }
5530
5531 private:
5533 std::istream* is = nullptr;
5534 std::streambuf* sb = nullptr;
5535};
5536#endif // JSON_NO_IO
5537
5538// General-purpose iterator-based adapter. It might not be as fast as
5539// theoretically possible for some containers, but it is extremely versatile.
5540template<typename IteratorType>
5541class iterator_input_adapter
5542{
5543 public:
5544 using char_type = typename std::iterator_traits<IteratorType>::value_type;
5545
5546 iterator_input_adapter(IteratorType first, IteratorType last)
5547 : current(std::move(first)), end(std::move(last))
5548 {}
5549
5550 typename std::char_traits<char_type>::int_type get_character()
5551 {
5552 if (JSON_HEDLEY_LIKELY(current != end))
5553 {
5554 auto result = std::char_traits<char_type>::to_int_type(*current);
5555 std::advance(current, 1);
5556 return result;
5557 }
5558
5559 return std::char_traits<char_type>::eof();
5560 }
5561
5562 private:
5563 IteratorType current;
5564 IteratorType end;
5565
5566 template<typename BaseInputAdapter, size_t T>
5567 friend struct wide_string_input_helper;
5568
5569 bool empty() const
5570 {
5571 return current == end;
5572 }
5573};
5574
5575
5576template<typename BaseInputAdapter, size_t T>
5577struct wide_string_input_helper;
5578
5579template<typename BaseInputAdapter>
5580struct wide_string_input_helper<BaseInputAdapter, 4>
5581{
5582 // UTF-32
5583 static void fill_buffer(BaseInputAdapter& input,
5584 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5585 size_t& utf8_bytes_index,
5586 size_t& utf8_bytes_filled)
5587 {
5588 utf8_bytes_index = 0;
5589
5590 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5591 {
5592 utf8_bytes[0] = std::char_traits<char>::eof();
5593 utf8_bytes_filled = 1;
5594 }
5595 else
5596 {
5597 // get the current character
5598 const auto wc = input.get_character();
5599
5600 // UTF-32 to UTF-8 encoding
5601 if (wc < 0x80)
5602 {
5603 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5604 utf8_bytes_filled = 1;
5605 }
5606 else if (wc <= 0x7FF)
5607 {
5608 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5609 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5610 utf8_bytes_filled = 2;
5611 }
5612 else if (wc <= 0xFFFF)
5613 {
5614 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5615 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5616 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5617 utf8_bytes_filled = 3;
5618 }
5619 else if (wc <= 0x10FFFF)
5620 {
5621 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5622 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5623 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5624 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5625 utf8_bytes_filled = 4;
5626 }
5627 else
5628 {
5629 // unknown character
5630 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5631 utf8_bytes_filled = 1;
5632 }
5633 }
5634 }
5635};
5636
5637template<typename BaseInputAdapter>
5638struct wide_string_input_helper<BaseInputAdapter, 2>
5639{
5640 // UTF-16
5641 static void fill_buffer(BaseInputAdapter& input,
5642 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5643 size_t& utf8_bytes_index,
5644 size_t& utf8_bytes_filled)
5645 {
5646 utf8_bytes_index = 0;
5647
5648 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5649 {
5650 utf8_bytes[0] = std::char_traits<char>::eof();
5651 utf8_bytes_filled = 1;
5652 }
5653 else
5654 {
5655 // get the current character
5656 const auto wc = input.get_character();
5657
5658 // UTF-16 to UTF-8 encoding
5659 if (wc < 0x80)
5660 {
5661 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5662 utf8_bytes_filled = 1;
5663 }
5664 else if (wc <= 0x7FF)
5665 {
5666 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5667 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5668 utf8_bytes_filled = 2;
5669 }
5670 else if (0xD800 > wc || wc >= 0xE000)
5671 {
5672 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5673 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5674 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5675 utf8_bytes_filled = 3;
5676 }
5677 else
5678 {
5679 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5680 {
5681 const auto wc2 = static_cast<unsigned int>(input.get_character());
5682 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5683 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5684 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5685 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5686 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5687 utf8_bytes_filled = 4;
5688 }
5689 else
5690 {
5691 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5692 utf8_bytes_filled = 1;
5693 }
5694 }
5695 }
5696 }
5697};
5698
5699// Wraps another input apdater to convert wide character types into individual bytes.
5700template<typename BaseInputAdapter, typename WideCharType>
5701class wide_string_input_adapter
5702{
5703 public:
5704 using char_type = char;
5705
5706 wide_string_input_adapter(BaseInputAdapter base)
5707 : base_adapter(base) {}
5708
5709 typename std::char_traits<char>::int_type get_character() noexcept
5710 {
5711 // check if buffer needs to be filled
5712 if (utf8_bytes_index == utf8_bytes_filled)
5713 {
5714 fill_buffer<sizeof(WideCharType)>();
5715
5716 JSON_ASSERT(utf8_bytes_filled > 0);
5717 JSON_ASSERT(utf8_bytes_index == 0);
5718 }
5719
5720 // use buffer
5721 JSON_ASSERT(utf8_bytes_filled > 0);
5722 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5723 return utf8_bytes[utf8_bytes_index++];
5724 }
5725
5726 private:
5727 BaseInputAdapter base_adapter;
5728
5729 template<size_t T>
5730 void fill_buffer()
5731 {
5732 wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
5733 }
5734
5736 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5737
5739 std::size_t utf8_bytes_index = 0;
5741 std::size_t utf8_bytes_filled = 0;
5742};
5743
5744
5745template<typename IteratorType, typename Enable = void>
5746struct iterator_input_adapter_factory
5747{
5748 using iterator_type = IteratorType;
5749 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5750 using adapter_type = iterator_input_adapter<iterator_type>;
5751
5752 static adapter_type create(IteratorType first, IteratorType last)
5753 {
5754 return adapter_type(std::move(first), std::move(last));
5755 }
5756};
5757
5758template<typename T>
5759struct is_iterator_of_multibyte
5760{
5761 using value_type = typename std::iterator_traits<T>::value_type;
5762 enum
5763 {
5764 value = sizeof(value_type) > 1
5765 };
5766};
5767
5768template<typename IteratorType>
5769struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5770{
5771 using iterator_type = IteratorType;
5772 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5773 using base_adapter_type = iterator_input_adapter<iterator_type>;
5774 using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
5775
5776 static adapter_type create(IteratorType first, IteratorType last)
5777 {
5778 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5779 }
5780};
5781
5782// General purpose iterator-based input
5783template<typename IteratorType>
5784typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5785{
5786 using factory_type = iterator_input_adapter_factory<IteratorType>;
5787 return factory_type::create(first, last);
5788}
5789
5790// Convenience shorthand from container to iterator
5791// Enables ADL on begin(container) and end(container)
5792// Encloses the using declarations in namespace for not to leak them to outside scope
5793
5794namespace container_input_adapter_factory_impl
5795{
5796
5797using std::begin;
5798using std::end;
5799
5800template<typename ContainerType, typename Enable = void>
5801struct container_input_adapter_factory {};
5802
5803template<typename ContainerType>
5804struct container_input_adapter_factory< ContainerType,
5805 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5806 {
5807 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5808
5809 static adapter_type create(const ContainerType& container)
5810{
5811 return input_adapter(begin(container), end(container));
5812}
5813 };
5814
5815} // namespace container_input_adapter_factory_impl
5816
5817template<typename ContainerType>
5818typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
5819{
5820 return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
5821}
5822
5823#ifndef JSON_NO_IO
5824// Special cases with fast paths
5825inline file_input_adapter input_adapter(std::FILE* file)
5826{
5827 return file_input_adapter(file);
5828}
5829
5830inline input_stream_adapter input_adapter(std::istream& stream)
5831{
5832 return input_stream_adapter(stream);
5833}
5834
5835inline input_stream_adapter input_adapter(std::istream&& stream)
5836{
5837 return input_stream_adapter(stream);
5838}
5839#endif // JSON_NO_IO
5840
5841using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5842
5843// Null-delimited strings, and the like.
5844template < typename CharT,
5845 typename std::enable_if <
5846 std::is_pointer<CharT>::value&&
5847 !std::is_array<CharT>::value&&
5848 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5849 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5850 int >::type = 0 >
5851contiguous_bytes_input_adapter input_adapter(CharT b)
5852{
5853 auto length = std::strlen(reinterpret_cast<const char*>(b));
5854 const auto* ptr = reinterpret_cast<const char*>(b);
5855 return input_adapter(ptr, ptr + length);
5856}
5857
5858template<typename T, std::size_t N>
5859auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5860{
5861 return input_adapter(array, array + N);
5862}
5863
5864// This class only handles inputs of input_buffer_adapter type.
5865// It's required so that expressions like {ptr, len} can be implicitely casted
5866// to the correct adapter.
5867class span_input_adapter
5868{
5869 public:
5870 template < typename CharT,
5871 typename std::enable_if <
5872 std::is_pointer<CharT>::value&&
5873 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5874 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5875 int >::type = 0 >
5876 span_input_adapter(CharT b, std::size_t l)
5877 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5878
5879 template<class IteratorType,
5880 typename std::enable_if<
5881 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5882 int>::type = 0>
5883 span_input_adapter(IteratorType first, IteratorType last)
5884 : ia(input_adapter(first, last)) {}
5885
5886 contiguous_bytes_input_adapter&& get()
5887 {
5888 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5889 }
5890
5891 private:
5892 contiguous_bytes_input_adapter ia;
5893};
5894} // namespace detail
5895} // namespace nlohmann
5896
5897// #include <nlohmann/detail/input/json_sax.hpp>
5898
5899
5900#include <cstddef>
5901#include <string> // string
5902#include <utility> // move
5903#include <vector> // vector
5904
5905// #include <nlohmann/detail/exceptions.hpp>
5906
5907// #include <nlohmann/detail/macro_scope.hpp>
5908
5909
5910namespace nlohmann
5911{
5912
5921template<typename BasicJsonType>
5923{
5924 using number_integer_t = typename BasicJsonType::number_integer_t;
5925 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5926 using number_float_t = typename BasicJsonType::number_float_t;
5927 using string_t = typename BasicJsonType::string_t;
5928 using binary_t = typename BasicJsonType::binary_t;
5929
5934 virtual bool null() = 0;
5935
5941 virtual bool boolean(bool val) = 0;
5942
5948 virtual bool number_integer(number_integer_t val) = 0;
5949
5955 virtual bool number_unsigned(number_unsigned_t val) = 0;
5956
5963 virtual bool number_float(number_float_t val, const string_t& s) = 0;
5964
5971 virtual bool string(string_t& val) = 0;
5972
5979 virtual bool binary(binary_t& val) = 0;
5980
5987 virtual bool start_object(std::size_t elements) = 0;
5988
5995 virtual bool key(string_t& val) = 0;
5996
6001 virtual bool end_object() = 0;
6002
6009 virtual bool start_array(std::size_t elements) = 0;
6010
6015 virtual bool end_array() = 0;
6016
6024 virtual bool parse_error(std::size_t position,
6025 const std::string& last_token,
6026 const detail::exception& ex) = 0;
6027
6028 json_sax() = default;
6029 json_sax(const json_sax&) = default;
6030 json_sax(json_sax&&) noexcept = default;
6031 json_sax& operator=(const json_sax&) = default;
6032 json_sax& operator=(json_sax&&) noexcept = default;
6033 virtual ~json_sax() = default;
6034};
6035
6036
6037namespace detail
6038{
6052template<typename BasicJsonType>
6053class json_sax_dom_parser
6054{
6055 public:
6056 using number_integer_t = typename BasicJsonType::number_integer_t;
6057 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6058 using number_float_t = typename BasicJsonType::number_float_t;
6059 using string_t = typename BasicJsonType::string_t;
6060 using binary_t = typename BasicJsonType::binary_t;
6061
6067 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6068 : root(r), allow_exceptions(allow_exceptions_)
6069 {}
6070
6071 // make class move-only
6072 json_sax_dom_parser(const json_sax_dom_parser&) = delete;
6073 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6074 json_sax_dom_parser& operator=(const json_sax_dom_parser&) = delete;
6075 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6076 ~json_sax_dom_parser() = default;
6077
6078 bool null()
6079 {
6080 handle_value(nullptr);
6081 return true;
6082 }
6083
6084 bool boolean(bool val)
6085 {
6086 handle_value(val);
6087 return true;
6088 }
6089
6091 {
6092 handle_value(val);
6093 return true;
6094 }
6095
6097 {
6098 handle_value(val);
6099 return true;
6100 }
6101
6102 bool number_float(number_float_t val, const string_t& /*unused*/)
6103 {
6104 handle_value(val);
6105 return true;
6106 }
6107
6108 bool string(string_t& val)
6109 {
6110 handle_value(val);
6111 return true;
6112 }
6113
6114 bool binary(binary_t& val)
6115 {
6116 handle_value(std::move(val));
6117 return true;
6118 }
6119
6120 bool start_object(std::size_t len)
6121 {
6122 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6123
6124 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6125 {
6126 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6127 }
6128
6129 return true;
6130 }
6131
6132 bool key(string_t& val)
6133 {
6134 // add null at given key and store the reference for later
6135 object_element = &(ref_stack.back()->m_value.object->operator[](val));
6136 return true;
6137 }
6138
6139 bool end_object()
6140 {
6141 ref_stack.back()->set_parents();
6142 ref_stack.pop_back();
6143 return true;
6144 }
6145
6146 bool start_array(std::size_t len)
6147 {
6148 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6149
6150 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6151 {
6152 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6153 }
6154
6155 return true;
6156 }
6157
6158 bool end_array()
6159 {
6160 ref_stack.back()->set_parents();
6161 ref_stack.pop_back();
6162 return true;
6163 }
6164
6165 template<class Exception>
6166 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6167 const Exception& ex)
6168 {
6169 errored = true;
6170 static_cast<void>(ex);
6171 if (allow_exceptions)
6172 {
6173 JSON_THROW(ex);
6174 }
6175 return false;
6176 }
6177
6178 constexpr bool is_errored() const
6179 {
6180 return errored;
6181 }
6182
6183 private:
6190 template<typename Value>
6191
6192 BasicJsonType* handle_value(Value&& v)
6193 {
6194 if (ref_stack.empty())
6195 {
6196 root = BasicJsonType(std::forward<Value>(v));
6197 return &root;
6198 }
6199
6200 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6201
6202 if (ref_stack.back()->is_array())
6203 {
6204 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6205 return &(ref_stack.back()->m_value.array->back());
6206 }
6207
6208 JSON_ASSERT(ref_stack.back()->is_object());
6209 JSON_ASSERT(object_element);
6210 *object_element = BasicJsonType(std::forward<Value>(v));
6211 return object_element;
6212 }
6213
6215 BasicJsonType& root;
6217 std::vector<BasicJsonType*> ref_stack {};
6219 BasicJsonType* object_element = nullptr;
6221 bool errored = false;
6223 const bool allow_exceptions = true;
6224};
6225
6226template<typename BasicJsonType>
6227class json_sax_dom_callback_parser
6228{
6229 public:
6230 using number_integer_t = typename BasicJsonType::number_integer_t;
6231 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6232 using number_float_t = typename BasicJsonType::number_float_t;
6233 using string_t = typename BasicJsonType::string_t;
6234 using binary_t = typename BasicJsonType::binary_t;
6235 using parser_callback_t = typename BasicJsonType::parser_callback_t;
6236 using parse_event_t = typename BasicJsonType::parse_event_t;
6237
6238 json_sax_dom_callback_parser(BasicJsonType& r,
6239 const parser_callback_t cb,
6240 const bool allow_exceptions_ = true)
6241 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6242 {
6243 keep_stack.push_back(true);
6244 }
6245
6246 // make class move-only
6247 json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = delete;
6248 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6249 json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_parser&) = delete;
6250 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6251 ~json_sax_dom_callback_parser() = default;
6252
6253 bool null()
6254 {
6255 handle_value(nullptr);
6256 return true;
6257 }
6258
6259 bool boolean(bool val)
6260 {
6261 handle_value(val);
6262 return true;
6263 }
6264
6266 {
6267 handle_value(val);
6268 return true;
6269 }
6270
6272 {
6273 handle_value(val);
6274 return true;
6275 }
6276
6277 bool number_float(number_float_t val, const string_t& /*unused*/)
6278 {
6279 handle_value(val);
6280 return true;
6281 }
6282
6283 bool string(string_t& val)
6284 {
6285 handle_value(val);
6286 return true;
6287 }
6288
6289 bool binary(binary_t& val)
6290 {
6291 handle_value(std::move(val));
6292 return true;
6293 }
6294
6295 bool start_object(std::size_t len)
6296 {
6297 // check callback for object start
6298 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6299 keep_stack.push_back(keep);
6300
6301 auto val = handle_value(BasicJsonType::value_t::object, true);
6302 ref_stack.push_back(val.second);
6303
6304 // check object limit
6305 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6306 {
6307 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6308 }
6309
6310 return true;
6311 }
6312
6313 bool key(string_t& val)
6314 {
6315 BasicJsonType k = BasicJsonType(val);
6316
6317 // check callback for key
6318 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6319 key_keep_stack.push_back(keep);
6320
6321 // add discarded value at given key and store the reference for later
6322 if (keep && ref_stack.back())
6323 {
6324 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6325 }
6326
6327 return true;
6328 }
6329
6330 bool end_object()
6331 {
6332 if (ref_stack.back())
6333 {
6334 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6335 {
6336 // discard object
6337 *ref_stack.back() = discarded;
6338 }
6339 else
6340 {
6341 ref_stack.back()->set_parents();
6342 }
6343 }
6344
6345 JSON_ASSERT(!ref_stack.empty());
6346 JSON_ASSERT(!keep_stack.empty());
6347 ref_stack.pop_back();
6348 keep_stack.pop_back();
6349
6350 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6351 {
6352 // remove discarded value
6353 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6354 {
6355 if (it->is_discarded())
6356 {
6357 ref_stack.back()->erase(it);
6358 break;
6359 }
6360 }
6361 }
6362
6363 return true;
6364 }
6365
6366 bool start_array(std::size_t len)
6367 {
6368 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6369 keep_stack.push_back(keep);
6370
6371 auto val = handle_value(BasicJsonType::value_t::array, true);
6372 ref_stack.push_back(val.second);
6373
6374 // check array limit
6375 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6376 {
6377 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6378 }
6379
6380 return true;
6381 }
6382
6383 bool end_array()
6384 {
6385 bool keep = true;
6386
6387 if (ref_stack.back())
6388 {
6389 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6390 if (keep)
6391 {
6392 ref_stack.back()->set_parents();
6393 }
6394 else
6395 {
6396 // discard array
6397 *ref_stack.back() = discarded;
6398 }
6399 }
6400
6401 JSON_ASSERT(!ref_stack.empty());
6402 JSON_ASSERT(!keep_stack.empty());
6403 ref_stack.pop_back();
6404 keep_stack.pop_back();
6405
6406 // remove discarded value
6407 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6408 {
6409 ref_stack.back()->m_value.array->pop_back();
6410 }
6411
6412 return true;
6413 }
6414
6415 template<class Exception>
6416 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6417 const Exception& ex)
6418 {
6419 errored = true;
6420 static_cast<void>(ex);
6421 if (allow_exceptions)
6422 {
6423 JSON_THROW(ex);
6424 }
6425 return false;
6426 }
6427
6428 constexpr bool is_errored() const
6429 {
6430 return errored;
6431 }
6432
6433 private:
6449 template<typename Value>
6450 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6451 {
6452 JSON_ASSERT(!keep_stack.empty());
6453
6454 // do not handle this value if we know it would be added to a discarded
6455 // container
6456 if (!keep_stack.back())
6457 {
6458 return {false, nullptr};
6459 }
6460
6461 // create value
6462 auto value = BasicJsonType(std::forward<Value>(v));
6463
6464 // check callback
6465 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6466
6467 // do not handle this value if we just learnt it shall be discarded
6468 if (!keep)
6469 {
6470 return {false, nullptr};
6471 }
6472
6473 if (ref_stack.empty())
6474 {
6475 root = std::move(value);
6476 return {true, &root};
6477 }
6478
6479 // skip this value if we already decided to skip the parent
6480 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6481 if (!ref_stack.back())
6482 {
6483 return {false, nullptr};
6484 }
6485
6486 // we now only expect arrays and objects
6487 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6488
6489 // array
6490 if (ref_stack.back()->is_array())
6491 {
6492 ref_stack.back()->m_value.array->emplace_back(std::move(value));
6493 return {true, &(ref_stack.back()->m_value.array->back())};
6494 }
6495
6496 // object
6497 JSON_ASSERT(ref_stack.back()->is_object());
6498 // check if we should store an element for the current key
6499 JSON_ASSERT(!key_keep_stack.empty());
6500 const bool store_element = key_keep_stack.back();
6501 key_keep_stack.pop_back();
6502
6503 if (!store_element)
6504 {
6505 return {false, nullptr};
6506 }
6507
6508 JSON_ASSERT(object_element);
6509 *object_element = std::move(value);
6510 return {true, object_element};
6511 }
6512
6514 BasicJsonType& root;
6516 std::vector<BasicJsonType*> ref_stack {};
6518 std::vector<bool> keep_stack {};
6520 std::vector<bool> key_keep_stack {};
6522 BasicJsonType* object_element = nullptr;
6524 bool errored = false;
6526 const parser_callback_t callback = nullptr;
6528 const bool allow_exceptions = true;
6530 BasicJsonType discarded = BasicJsonType::value_t::discarded;
6531};
6532
6533template<typename BasicJsonType>
6534class json_sax_acceptor
6535{
6536 public:
6537 using number_integer_t = typename BasicJsonType::number_integer_t;
6538 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6539 using number_float_t = typename BasicJsonType::number_float_t;
6540 using string_t = typename BasicJsonType::string_t;
6541 using binary_t = typename BasicJsonType::binary_t;
6542
6543 bool null()
6544 {
6545 return true;
6546 }
6547
6548 bool boolean(bool /*unused*/)
6549 {
6550 return true;
6551 }
6552
6553 bool number_integer(number_integer_t /*unused*/)
6554 {
6555 return true;
6556 }
6557
6558 bool number_unsigned(number_unsigned_t /*unused*/)
6559 {
6560 return true;
6561 }
6562
6563 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6564 {
6565 return true;
6566 }
6567
6568 bool string(string_t& /*unused*/)
6569 {
6570 return true;
6571 }
6572
6573 bool binary(binary_t& /*unused*/)
6574 {
6575 return true;
6576 }
6577
6578 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
6579 {
6580 return true;
6581 }
6582
6583 bool key(string_t& /*unused*/)
6584 {
6585 return true;
6586 }
6587
6588 bool end_object()
6589 {
6590 return true;
6591 }
6592
6593 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
6594 {
6595 return true;
6596 }
6597
6598 bool end_array()
6599 {
6600 return true;
6601 }
6602
6603 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6604 {
6605 return false;
6606 }
6607};
6608} // namespace detail
6609
6610} // namespace nlohmann
6611
6612// #include <nlohmann/detail/input/lexer.hpp>
6613
6614
6615#include <array> // array
6616#include <clocale> // localeconv
6617#include <cstddef> // size_t
6618#include <cstdio> // snprintf
6619#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6620#include <initializer_list> // initializer_list
6621#include <string> // char_traits, string
6622#include <utility> // move
6623#include <vector> // vector
6624
6625// #include <nlohmann/detail/input/input_adapters.hpp>
6626
6627// #include <nlohmann/detail/input/position_t.hpp>
6628
6629// #include <nlohmann/detail/macro_scope.hpp>
6630
6631
6632namespace nlohmann
6633{
6634namespace detail
6635{
6637// lexer //
6639
6640template<typename BasicJsonType>
6641class lexer_base
6642{
6643 public:
6645 enum class token_type
6646 {
6647 uninitialized,
6648 literal_true,
6649 literal_false,
6650 literal_null,
6651 value_string,
6652 value_unsigned,
6653 value_integer,
6654 value_float,
6655 begin_array,
6656 begin_object,
6657 end_array,
6658 end_object,
6659 name_separator,
6660 value_separator,
6661 parse_error,
6662 end_of_input,
6663 literal_or_value
6664 };
6665
6667
6668 JSON_HEDLEY_CONST
6669 static const char* token_type_name(const token_type t) noexcept
6670 {
6671 switch (t)
6672 {
6673 case token_type::uninitialized:
6674 return "<uninitialized>";
6675 case token_type::literal_true:
6676 return "true literal";
6677 case token_type::literal_false:
6678 return "false literal";
6679 case token_type::literal_null:
6680 return "null literal";
6681 case token_type::value_string:
6682 return "string literal";
6683 case token_type::value_unsigned:
6684 case token_type::value_integer:
6685 case token_type::value_float:
6686 return "number literal";
6687 case token_type::begin_array:
6688 return "'['";
6689 case token_type::begin_object:
6690 return "'{'";
6691 case token_type::end_array:
6692 return "']'";
6693 case token_type::end_object:
6694 return "'}'";
6695 case token_type::name_separator:
6696 return "':'";
6697 case token_type::value_separator:
6698 return "','";
6699 case token_type::parse_error:
6700 return "<parse error>";
6701 case token_type::end_of_input:
6702 return "end of input";
6703 case token_type::literal_or_value:
6704 return "'[', '{', or a literal";
6705 // LCOV_EXCL_START
6706 default: // catch non-enum values
6707 return "unknown token";
6708 // LCOV_EXCL_STOP
6709 }
6710 }
6711};
6717template<typename BasicJsonType, typename InputAdapterType>
6718class lexer : public lexer_base<BasicJsonType>
6719{
6720 using number_integer_t = typename BasicJsonType::number_integer_t;
6721 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6722 using number_float_t = typename BasicJsonType::number_float_t;
6723 using string_t = typename BasicJsonType::string_t;
6724 using char_type = typename InputAdapterType::char_type;
6725 using char_int_type = typename std::char_traits<char_type>::int_type;
6726
6727 public:
6728 using token_type = typename lexer_base<BasicJsonType>::token_type;
6729
6730 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6731 : ia(std::move(adapter))
6732 , ignore_comments(ignore_comments_)
6733 , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6734 {}
6735
6736 // delete because of pointer members
6737 lexer(const lexer&) = delete;
6738 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6739 lexer& operator=(lexer&) = delete;
6740 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6741 ~lexer() = default;
6742
6743 private:
6745 // locales
6747
6749 JSON_HEDLEY_PURE
6750 static char get_decimal_point() noexcept
6751 {
6752 const auto* loc = localeconv();
6753 JSON_ASSERT(loc != nullptr);
6754 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6755 }
6756
6758 // scan functions
6760
6776 int get_codepoint()
6777 {
6778 // this function only makes sense after reading `\u`
6779 JSON_ASSERT(current == 'u');
6780 int codepoint = 0;
6781
6782 const auto factors = { 12u, 8u, 4u, 0u };
6783 for (const auto factor : factors)
6784 {
6785 get();
6786
6787 if (current >= '0' && current <= '9')
6788 {
6789 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6790 }
6791 else if (current >= 'A' && current <= 'F')
6792 {
6793 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6794 }
6795 else if (current >= 'a' && current <= 'f')
6796 {
6797 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6798 }
6799 else
6800 {
6801 return -1;
6802 }
6803 }
6804
6805 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6806 return codepoint;
6807 }
6808
6824 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6825 {
6826 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6827 add(current);
6828
6829 for (auto range = ranges.begin(); range != ranges.end(); ++range)
6830 {
6831 get();
6832 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6833 {
6834 add(current);
6835 }
6836 else
6837 {
6838 error_message = "invalid string: ill-formed UTF-8 byte";
6839 return false;
6840 }
6841 }
6842
6843 return true;
6844 }
6845
6861 token_type scan_string()
6862 {
6863 // reset token_buffer (ignore opening quote)
6864 reset();
6865
6866 // we entered the function by reading an open quote
6867 JSON_ASSERT(current == '\"');
6868
6869 while (true)
6870 {
6871 // get next character
6872 switch (get())
6873 {
6874 // end of file while parsing string
6875 case std::char_traits<char_type>::eof():
6876 {
6877 error_message = "invalid string: missing closing quote";
6878 return token_type::parse_error;
6879 }
6880
6881 // closing quote
6882 case '\"':
6883 {
6884 return token_type::value_string;
6885 }
6886
6887 // escapes
6888 case '\\':
6889 {
6890 switch (get())
6891 {
6892 // quotation mark
6893 case '\"':
6894 add('\"');
6895 break;
6896 // reverse solidus
6897 case '\\':
6898 add('\\');
6899 break;
6900 // solidus
6901 case '/':
6902 add('/');
6903 break;
6904 // backspace
6905 case 'b':
6906 add('\b');
6907 break;
6908 // form feed
6909 case 'f':
6910 add('\f');
6911 break;
6912 // line feed
6913 case 'n':
6914 add('\n');
6915 break;
6916 // carriage return
6917 case 'r':
6918 add('\r');
6919 break;
6920 // tab
6921 case 't':
6922 add('\t');
6923 break;
6924
6925 // unicode escapes
6926 case 'u':
6927 {
6928 const int codepoint1 = get_codepoint();
6929 int codepoint = codepoint1; // start with codepoint1
6930
6931 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6932 {
6933 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6934 return token_type::parse_error;
6935 }
6936
6937 // check if code point is a high surrogate
6938 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6939 {
6940 // expect next \uxxxx entry
6941 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6942 {
6943 const int codepoint2 = get_codepoint();
6944
6945 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6946 {
6947 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6948 return token_type::parse_error;
6949 }
6950
6951 // check if codepoint2 is a low surrogate
6952 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6953 {
6954 // overwrite codepoint
6955 codepoint = static_cast<int>(
6956 // high surrogate occupies the most significant 22 bits
6957 (static_cast<unsigned int>(codepoint1) << 10u)
6958 // low surrogate occupies the least significant 15 bits
6959 + static_cast<unsigned int>(codepoint2)
6960 // there is still the 0xD800, 0xDC00 and 0x10000 noise
6961 // in the result so we have to subtract with:
6962 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6963 - 0x35FDC00u);
6964 }
6965 else
6966 {
6967 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6968 return token_type::parse_error;
6969 }
6970 }
6971 else
6972 {
6973 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6974 return token_type::parse_error;
6975 }
6976 }
6977 else
6978 {
6979 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6980 {
6981 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6982 return token_type::parse_error;
6983 }
6984 }
6985
6986 // result of the above calculation yields a proper codepoint
6987 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6988
6989 // translate codepoint into bytes
6990 if (codepoint < 0x80)
6991 {
6992 // 1-byte characters: 0xxxxxxx (ASCII)
6993 add(static_cast<char_int_type>(codepoint));
6994 }
6995 else if (codepoint <= 0x7FF)
6996 {
6997 // 2-byte characters: 110xxxxx 10xxxxxx
6998 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6999 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7000 }
7001 else if (codepoint <= 0xFFFF)
7002 {
7003 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7004 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7005 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7006 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7007 }
7008 else
7009 {
7010 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7011 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7012 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7013 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7014 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7015 }
7016
7017 break;
7018 }
7019
7020 // other characters after escape
7021 default:
7022 error_message = "invalid string: forbidden character after backslash";
7023 return token_type::parse_error;
7024 }
7025
7026 break;
7027 }
7028
7029 // invalid control characters
7030 case 0x00:
7031 {
7032 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7033 return token_type::parse_error;
7034 }
7035
7036 case 0x01:
7037 {
7038 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7039 return token_type::parse_error;
7040 }
7041
7042 case 0x02:
7043 {
7044 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7045 return token_type::parse_error;
7046 }
7047
7048 case 0x03:
7049 {
7050 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7051 return token_type::parse_error;
7052 }
7053
7054 case 0x04:
7055 {
7056 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7057 return token_type::parse_error;
7058 }
7059
7060 case 0x05:
7061 {
7062 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7063 return token_type::parse_error;
7064 }
7065
7066 case 0x06:
7067 {
7068 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7069 return token_type::parse_error;
7070 }
7071
7072 case 0x07:
7073 {
7074 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7075 return token_type::parse_error;
7076 }
7077
7078 case 0x08:
7079 {
7080 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7081 return token_type::parse_error;
7082 }
7083
7084 case 0x09:
7085 {
7086 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7087 return token_type::parse_error;
7088 }
7089
7090 case 0x0A:
7091 {
7092 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7093 return token_type::parse_error;
7094 }
7095
7096 case 0x0B:
7097 {
7098 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7099 return token_type::parse_error;
7100 }
7101
7102 case 0x0C:
7103 {
7104 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7105 return token_type::parse_error;
7106 }
7107
7108 case 0x0D:
7109 {
7110 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7111 return token_type::parse_error;
7112 }
7113
7114 case 0x0E:
7115 {
7116 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7117 return token_type::parse_error;
7118 }
7119
7120 case 0x0F:
7121 {
7122 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7123 return token_type::parse_error;
7124 }
7125
7126 case 0x10:
7127 {
7128 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7129 return token_type::parse_error;
7130 }
7131
7132 case 0x11:
7133 {
7134 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7135 return token_type::parse_error;
7136 }
7137
7138 case 0x12:
7139 {
7140 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7141 return token_type::parse_error;
7142 }
7143
7144 case 0x13:
7145 {
7146 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7147 return token_type::parse_error;
7148 }
7149
7150 case 0x14:
7151 {
7152 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7153 return token_type::parse_error;
7154 }
7155
7156 case 0x15:
7157 {
7158 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7159 return token_type::parse_error;
7160 }
7161
7162 case 0x16:
7163 {
7164 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7165 return token_type::parse_error;
7166 }
7167
7168 case 0x17:
7169 {
7170 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7171 return token_type::parse_error;
7172 }
7173
7174 case 0x18:
7175 {
7176 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7177 return token_type::parse_error;
7178 }
7179
7180 case 0x19:
7181 {
7182 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7183 return token_type::parse_error;
7184 }
7185
7186 case 0x1A:
7187 {
7188 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7189 return token_type::parse_error;
7190 }
7191
7192 case 0x1B:
7193 {
7194 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7195 return token_type::parse_error;
7196 }
7197
7198 case 0x1C:
7199 {
7200 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7201 return token_type::parse_error;
7202 }
7203
7204 case 0x1D:
7205 {
7206 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7207 return token_type::parse_error;
7208 }
7209
7210 case 0x1E:
7211 {
7212 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7213 return token_type::parse_error;
7214 }
7215
7216 case 0x1F:
7217 {
7218 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7219 return token_type::parse_error;
7220 }
7221
7222 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7223 case 0x20:
7224 case 0x21:
7225 case 0x23:
7226 case 0x24:
7227 case 0x25:
7228 case 0x26:
7229 case 0x27:
7230 case 0x28:
7231 case 0x29:
7232 case 0x2A:
7233 case 0x2B:
7234 case 0x2C:
7235 case 0x2D:
7236 case 0x2E:
7237 case 0x2F:
7238 case 0x30:
7239 case 0x31:
7240 case 0x32:
7241 case 0x33:
7242 case 0x34:
7243 case 0x35:
7244 case 0x36:
7245 case 0x37:
7246 case 0x38:
7247 case 0x39:
7248 case 0x3A:
7249 case 0x3B:
7250 case 0x3C:
7251 case 0x3D:
7252 case 0x3E:
7253 case 0x3F:
7254 case 0x40:
7255 case 0x41:
7256 case 0x42:
7257 case 0x43:
7258 case 0x44:
7259 case 0x45:
7260 case 0x46:
7261 case 0x47:
7262 case 0x48:
7263 case 0x49:
7264 case 0x4A:
7265 case 0x4B:
7266 case 0x4C:
7267 case 0x4D:
7268 case 0x4E:
7269 case 0x4F:
7270 case 0x50:
7271 case 0x51:
7272 case 0x52:
7273 case 0x53:
7274 case 0x54:
7275 case 0x55:
7276 case 0x56:
7277 case 0x57:
7278 case 0x58:
7279 case 0x59:
7280 case 0x5A:
7281 case 0x5B:
7282 case 0x5D:
7283 case 0x5E:
7284 case 0x5F:
7285 case 0x60:
7286 case 0x61:
7287 case 0x62:
7288 case 0x63:
7289 case 0x64:
7290 case 0x65:
7291 case 0x66:
7292 case 0x67:
7293 case 0x68:
7294 case 0x69:
7295 case 0x6A:
7296 case 0x6B:
7297 case 0x6C:
7298 case 0x6D:
7299 case 0x6E:
7300 case 0x6F:
7301 case 0x70:
7302 case 0x71:
7303 case 0x72:
7304 case 0x73:
7305 case 0x74:
7306 case 0x75:
7307 case 0x76:
7308 case 0x77:
7309 case 0x78:
7310 case 0x79:
7311 case 0x7A:
7312 case 0x7B:
7313 case 0x7C:
7314 case 0x7D:
7315 case 0x7E:
7316 case 0x7F:
7317 {
7318 add(current);
7319 break;
7320 }
7321
7322 // U+0080..U+07FF: bytes C2..DF 80..BF
7323 case 0xC2:
7324 case 0xC3:
7325 case 0xC4:
7326 case 0xC5:
7327 case 0xC6:
7328 case 0xC7:
7329 case 0xC8:
7330 case 0xC9:
7331 case 0xCA:
7332 case 0xCB:
7333 case 0xCC:
7334 case 0xCD:
7335 case 0xCE:
7336 case 0xCF:
7337 case 0xD0:
7338 case 0xD1:
7339 case 0xD2:
7340 case 0xD3:
7341 case 0xD4:
7342 case 0xD5:
7343 case 0xD6:
7344 case 0xD7:
7345 case 0xD8:
7346 case 0xD9:
7347 case 0xDA:
7348 case 0xDB:
7349 case 0xDC:
7350 case 0xDD:
7351 case 0xDE:
7352 case 0xDF:
7353 {
7354 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7355 {
7356 return token_type::parse_error;
7357 }
7358 break;
7359 }
7360
7361 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7362 case 0xE0:
7363 {
7364 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7365 {
7366 return token_type::parse_error;
7367 }
7368 break;
7369 }
7370
7371 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7372 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7373 case 0xE1:
7374 case 0xE2:
7375 case 0xE3:
7376 case 0xE4:
7377 case 0xE5:
7378 case 0xE6:
7379 case 0xE7:
7380 case 0xE8:
7381 case 0xE9:
7382 case 0xEA:
7383 case 0xEB:
7384 case 0xEC:
7385 case 0xEE:
7386 case 0xEF:
7387 {
7388 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7389 {
7390 return token_type::parse_error;
7391 }
7392 break;
7393 }
7394
7395 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7396 case 0xED:
7397 {
7398 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7399 {
7400 return token_type::parse_error;
7401 }
7402 break;
7403 }
7404
7405 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7406 case 0xF0:
7407 {
7408 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7409 {
7410 return token_type::parse_error;
7411 }
7412 break;
7413 }
7414
7415 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7416 case 0xF1:
7417 case 0xF2:
7418 case 0xF3:
7419 {
7420 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7421 {
7422 return token_type::parse_error;
7423 }
7424 break;
7425 }
7426
7427 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7428 case 0xF4:
7429 {
7430 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7431 {
7432 return token_type::parse_error;
7433 }
7434 break;
7435 }
7436
7437 // remaining bytes (80..C1 and F5..FF) are ill-formed
7438 default:
7439 {
7440 error_message = "invalid string: ill-formed UTF-8 byte";
7441 return token_type::parse_error;
7442 }
7443 }
7444 }
7445 }
7446
7451 bool scan_comment()
7452 {
7453 switch (get())
7454 {
7455 // single-line comments skip input until a newline or EOF is read
7456 case '/':
7457 {
7458 while (true)
7459 {
7460 switch (get())
7461 {
7462 case '\n':
7463 case '\r':
7464 case std::char_traits<char_type>::eof():
7465 case '\0':
7466 return true;
7467
7468 default:
7469 break;
7470 }
7471 }
7472 }
7473
7474 // multi-line comments skip input until */ is read
7475 case '*':
7476 {
7477 while (true)
7478 {
7479 switch (get())
7480 {
7481 case std::char_traits<char_type>::eof():
7482 case '\0':
7483 {
7484 error_message = "invalid comment; missing closing '*/'";
7485 return false;
7486 }
7487
7488 case '*':
7489 {
7490 switch (get())
7491 {
7492 case '/':
7493 return true;
7494
7495 default:
7496 {
7497 unget();
7498 continue;
7499 }
7500 }
7501 }
7502
7503 default:
7504 continue;
7505 }
7506 }
7507 }
7508
7509 // unexpected character after reading '/'
7510 default:
7511 {
7512 error_message = "invalid comment; expecting '/' or '*' after '/'";
7513 return false;
7514 }
7515 }
7516 }
7517
7518 JSON_HEDLEY_NON_NULL(2)
7519 static void strtof(float& f, const char* str, char** endptr) noexcept
7520 {
7521 f = std::strtof(str, endptr);
7522 }
7523
7524 JSON_HEDLEY_NON_NULL(2)
7525 static void strtof(double& f, const char* str, char** endptr) noexcept
7526 {
7527 f = std::strtod(str, endptr);
7528 }
7529
7530 JSON_HEDLEY_NON_NULL(2)
7531 static void strtof(long double& f, const char* str, char** endptr) noexcept
7532 {
7533 f = std::strtold(str, endptr);
7534 }
7535
7576 token_type scan_number() // lgtm [cpp/use-of-goto]
7577 {
7578 // reset token_buffer to store the number's bytes
7579 reset();
7580
7581 // the type of the parsed number; initially set to unsigned; will be
7582 // changed if minus sign, decimal point or exponent is read
7583 token_type number_type = token_type::value_unsigned;
7584
7585 // state (init): we just found out we need to scan a number
7586 switch (current)
7587 {
7588 case '-':
7589 {
7590 add(current);
7591 goto scan_number_minus;
7592 }
7593
7594 case '0':
7595 {
7596 add(current);
7597 goto scan_number_zero;
7598 }
7599
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_any1;
7612 }
7613
7614 // all other characters are rejected outside scan_number()
7615 default: // LCOV_EXCL_LINE
7616 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7617 }
7618
7619scan_number_minus:
7620 // state: we just parsed a leading minus sign
7621 number_type = token_type::value_integer;
7622 switch (get())
7623 {
7624 case '0':
7625 {
7626 add(current);
7627 goto scan_number_zero;
7628 }
7629
7630 case '1':
7631 case '2':
7632 case '3':
7633 case '4':
7634 case '5':
7635 case '6':
7636 case '7':
7637 case '8':
7638 case '9':
7639 {
7640 add(current);
7641 goto scan_number_any1;
7642 }
7643
7644 default:
7645 {
7646 error_message = "invalid number; expected digit after '-'";
7647 return token_type::parse_error;
7648 }
7649 }
7650
7651scan_number_zero:
7652 // state: we just parse a zero (maybe with a leading minus sign)
7653 switch (get())
7654 {
7655 case '.':
7656 {
7657 add(decimal_point_char);
7658 goto scan_number_decimal1;
7659 }
7660
7661 case 'e':
7662 case 'E':
7663 {
7664 add(current);
7665 goto scan_number_exponent;
7666 }
7667
7668 default:
7669 goto scan_number_done;
7670 }
7671
7672scan_number_any1:
7673 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7674 switch (get())
7675 {
7676 case '0':
7677 case '1':
7678 case '2':
7679 case '3':
7680 case '4':
7681 case '5':
7682 case '6':
7683 case '7':
7684 case '8':
7685 case '9':
7686 {
7687 add(current);
7688 goto scan_number_any1;
7689 }
7690
7691 case '.':
7692 {
7693 add(decimal_point_char);
7694 goto scan_number_decimal1;
7695 }
7696
7697 case 'e':
7698 case 'E':
7699 {
7700 add(current);
7701 goto scan_number_exponent;
7702 }
7703
7704 default:
7705 goto scan_number_done;
7706 }
7707
7708scan_number_decimal1:
7709 // state: we just parsed a decimal point
7710 number_type = token_type::value_float;
7711 switch (get())
7712 {
7713 case '0':
7714 case '1':
7715 case '2':
7716 case '3':
7717 case '4':
7718 case '5':
7719 case '6':
7720 case '7':
7721 case '8':
7722 case '9':
7723 {
7724 add(current);
7725 goto scan_number_decimal2;
7726 }
7727
7728 default:
7729 {
7730 error_message = "invalid number; expected digit after '.'";
7731 return token_type::parse_error;
7732 }
7733 }
7734
7735scan_number_decimal2:
7736 // we just parsed at least one number after a decimal point
7737 switch (get())
7738 {
7739 case '0':
7740 case '1':
7741 case '2':
7742 case '3':
7743 case '4':
7744 case '5':
7745 case '6':
7746 case '7':
7747 case '8':
7748 case '9':
7749 {
7750 add(current);
7751 goto scan_number_decimal2;
7752 }
7753
7754 case 'e':
7755 case 'E':
7756 {
7757 add(current);
7758 goto scan_number_exponent;
7759 }
7760
7761 default:
7762 goto scan_number_done;
7763 }
7764
7765scan_number_exponent:
7766 // we just parsed an exponent
7767 number_type = token_type::value_float;
7768 switch (get())
7769 {
7770 case '+':
7771 case '-':
7772 {
7773 add(current);
7774 goto scan_number_sign;
7775 }
7776
7777 case '0':
7778 case '1':
7779 case '2':
7780 case '3':
7781 case '4':
7782 case '5':
7783 case '6':
7784 case '7':
7785 case '8':
7786 case '9':
7787 {
7788 add(current);
7789 goto scan_number_any2;
7790 }
7791
7792 default:
7793 {
7794 error_message =
7795 "invalid number; expected '+', '-', or digit after exponent";
7796 return token_type::parse_error;
7797 }
7798 }
7799
7800scan_number_sign:
7801 // we just parsed an exponent sign
7802 switch (get())
7803 {
7804 case '0':
7805 case '1':
7806 case '2':
7807 case '3':
7808 case '4':
7809 case '5':
7810 case '6':
7811 case '7':
7812 case '8':
7813 case '9':
7814 {
7815 add(current);
7816 goto scan_number_any2;
7817 }
7818
7819 default:
7820 {
7821 error_message = "invalid number; expected digit after exponent sign";
7822 return token_type::parse_error;
7823 }
7824 }
7825
7826scan_number_any2:
7827 // we just parsed a number after the exponent or exponent sign
7828 switch (get())
7829 {
7830 case '0':
7831 case '1':
7832 case '2':
7833 case '3':
7834 case '4':
7835 case '5':
7836 case '6':
7837 case '7':
7838 case '8':
7839 case '9':
7840 {
7841 add(current);
7842 goto scan_number_any2;
7843 }
7844
7845 default:
7846 goto scan_number_done;
7847 }
7848
7849scan_number_done:
7850 // unget the character after the number (we only read it to know that
7851 // we are done scanning a number)
7852 unget();
7853
7854 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7855 errno = 0;
7856
7857 // try to parse integers first and fall back to floats
7858 if (number_type == token_type::value_unsigned)
7859 {
7860 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7861
7862 // we checked the number format before
7863 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7864
7865 if (errno == 0)
7866 {
7867 value_unsigned = static_cast<number_unsigned_t>(x);
7868 if (value_unsigned == x)
7869 {
7870 return token_type::value_unsigned;
7871 }
7872 }
7873 }
7874 else if (number_type == token_type::value_integer)
7875 {
7876 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7877
7878 // we checked the number format before
7879 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7880
7881 if (errno == 0)
7882 {
7883 value_integer = static_cast<number_integer_t>(x);
7884 if (value_integer == x)
7885 {
7886 return token_type::value_integer;
7887 }
7888 }
7889 }
7890
7891 // this code is reached if we parse a floating-point number or if an
7892 // integer conversion above failed
7893 strtof(value_float, token_buffer.data(), &endptr);
7894
7895 // we checked the number format before
7896 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7897
7898 return token_type::value_float;
7899 }
7900
7906 JSON_HEDLEY_NON_NULL(2)
7907 token_type scan_literal(const char_type* literal_text, const std::size_t length,
7908 token_type return_type)
7909 {
7910 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7911 for (std::size_t i = 1; i < length; ++i)
7912 {
7913 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7914 {
7915 error_message = "invalid literal";
7916 return token_type::parse_error;
7917 }
7918 }
7919 return return_type;
7920 }
7921
7923 // input management
7925
7927 void reset() noexcept
7928 {
7929 token_buffer.clear();
7930 token_string.clear();
7931 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7932 }
7933
7934 /*
7935 @brief get next character from the input
7936
7937 This function provides the interface to the used input adapter. It does
7938 not throw in case the input reached EOF, but returns a
7939 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7940 for use in error messages.
7941
7942 @return character read from the input
7943 */
7944 char_int_type get()
7945 {
7946 ++position.chars_read_total;
7947 ++position.chars_read_current_line;
7948
7949 if (next_unget)
7950 {
7951 // just reset the next_unget variable and work with current
7952 next_unget = false;
7953 }
7954 else
7955 {
7956 current = ia.get_character();
7957 }
7958
7959 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7960 {
7961 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7962 }
7963
7964 if (current == '\n')
7965 {
7966 ++position.lines_read;
7967 position.chars_read_current_line = 0;
7968 }
7969
7970 return current;
7971 }
7972
7981 void unget()
7982 {
7983 next_unget = true;
7984
7985 --position.chars_read_total;
7986
7987 // in case we "unget" a newline, we have to also decrement the lines_read
7988 if (position.chars_read_current_line == 0)
7989 {
7990 if (position.lines_read > 0)
7991 {
7992 --position.lines_read;
7993 }
7994 }
7995 else
7996 {
7997 --position.chars_read_current_line;
7998 }
7999
8000 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8001 {
8002 JSON_ASSERT(!token_string.empty());
8003 token_string.pop_back();
8004 }
8005 }
8006
8008 void add(char_int_type c)
8009 {
8010 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8011 }
8012
8013 public:
8015 // value getters
8017
8019 constexpr number_integer_t get_number_integer() const noexcept
8020 {
8021 return value_integer;
8022 }
8023
8025 constexpr number_unsigned_t get_number_unsigned() const noexcept
8026 {
8027 return value_unsigned;
8028 }
8029
8031 constexpr number_float_t get_number_float() const noexcept
8032 {
8033 return value_float;
8034 }
8035
8037 string_t& get_string()
8038 {
8039 return token_buffer;
8040 }
8041
8043 // diagnostics
8045
8047 constexpr position_t get_position() const noexcept
8048 {
8049 return position;
8050 }
8051
8055 std::string get_token_string() const
8056 {
8057 // escape control characters
8058 std::string result;
8059 for (const auto c : token_string)
8060 {
8061 if (static_cast<unsigned char>(c) <= '\x1F')
8062 {
8063 // escape control characters
8064 std::array<char, 9> cs{{}};
8065 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8066 result += cs.data();
8067 }
8068 else
8069 {
8070 // add character as is
8071 result.push_back(static_cast<std::string::value_type>(c));
8072 }
8073 }
8074
8075 return result;
8076 }
8077
8079
8080 constexpr const char* get_error_message() const noexcept
8081 {
8082 return error_message;
8083 }
8084
8086 // actual scanner
8088
8093 bool skip_bom()
8094 {
8095 if (get() == 0xEF)
8096 {
8097 // check if we completely parse the BOM
8098 return get() == 0xBB && get() == 0xBF;
8099 }
8100
8101 // the first character is not the beginning of the BOM; unget it to
8102 // process is later
8103 unget();
8104 return true;
8105 }
8106
8107 void skip_whitespace()
8108 {
8109 do
8110 {
8111 get();
8112 }
8113 while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8114 }
8115
8116 token_type scan()
8117 {
8118 // initially, skip the BOM
8119 if (position.chars_read_total == 0 && !skip_bom())
8120 {
8121 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8122 return token_type::parse_error;
8123 }
8124
8125 // read next character and ignore whitespace
8126 skip_whitespace();
8127
8128 // ignore comments
8129 while (ignore_comments && current == '/')
8130 {
8131 if (!scan_comment())
8132 {
8133 return token_type::parse_error;
8134 }
8135
8136 // skip following whitespace
8137 skip_whitespace();
8138 }
8139
8140 switch (current)
8141 {
8142 // structural characters
8143 case '[':
8144 return token_type::begin_array;
8145 case ']':
8146 return token_type::end_array;
8147 case '{':
8148 return token_type::begin_object;
8149 case '}':
8150 return token_type::end_object;
8151 case ':':
8152 return token_type::name_separator;
8153 case ',':
8154 return token_type::value_separator;
8155
8156 // literals
8157 case 't':
8158 {
8159 std::array<char_type, 4> true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}};
8160 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8161 }
8162 case 'f':
8163 {
8164 std::array<char_type, 5> false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}};
8165 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8166 }
8167 case 'n':
8168 {
8169 std::array<char_type, 4> null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}};
8170 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8171 }
8172
8173 // string
8174 case '\"':
8175 return scan_string();
8176
8177 // number
8178 case '-':
8179 case '0':
8180 case '1':
8181 case '2':
8182 case '3':
8183 case '4':
8184 case '5':
8185 case '6':
8186 case '7':
8187 case '8':
8188 case '9':
8189 return scan_number();
8190
8191 // end of input (the null byte is needed when parsing from
8192 // string literals)
8193 case '\0':
8194 case std::char_traits<char_type>::eof():
8195 return token_type::end_of_input;
8196
8197 // error
8198 default:
8199 error_message = "invalid literal";
8200 return token_type::parse_error;
8201 }
8202 }
8203
8204 private:
8206 InputAdapterType ia;
8207
8209 const bool ignore_comments = false;
8210
8212 char_int_type current = std::char_traits<char_type>::eof();
8213
8215 bool next_unget = false;
8216
8218 position_t position {};
8219
8221 std::vector<char_type> token_string {};
8222
8224 string_t token_buffer {};
8225
8227 const char* error_message = "";
8228
8229 // number values
8230 number_integer_t value_integer = 0;
8231 number_unsigned_t value_unsigned = 0;
8232 number_float_t value_float = 0;
8233
8235 const char_int_type decimal_point_char = '.';
8236};
8237} // namespace detail
8238} // namespace nlohmann
8239
8240// #include <nlohmann/detail/macro_scope.hpp>
8241
8242// #include <nlohmann/detail/meta/is_sax.hpp>
8243
8244
8245#include <cstdint> // size_t
8246#include <utility> // declval
8247#include <string> // string
8248
8249// #include <nlohmann/detail/meta/detected.hpp>
8250
8251// #include <nlohmann/detail/meta/type_traits.hpp>
8252
8253
8254namespace nlohmann
8255{
8256namespace detail
8257{
8258template<typename T>
8259using null_function_t = decltype(std::declval<T&>().null());
8260
8261template<typename T>
8262using boolean_function_t =
8263 decltype(std::declval<T&>().boolean(std::declval<bool>()));
8264
8265template<typename T, typename Integer>
8266using number_integer_function_t =
8267 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8268
8269template<typename T, typename Unsigned>
8270using number_unsigned_function_t =
8271 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8272
8273template<typename T, typename Float, typename String>
8274using number_float_function_t = decltype(std::declval<T&>().number_float(
8275 std::declval<Float>(), std::declval<const String&>()));
8276
8277template<typename T, typename String>
8278using string_function_t =
8279 decltype(std::declval<T&>().string(std::declval<String&>()));
8280
8281template<typename T, typename Binary>
8282using binary_function_t =
8283 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8284
8285template<typename T>
8286using start_object_function_t =
8287 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8288
8289template<typename T, typename String>
8290using key_function_t =
8291 decltype(std::declval<T&>().key(std::declval<String&>()));
8292
8293template<typename T>
8294using end_object_function_t = decltype(std::declval<T&>().end_object());
8295
8296template<typename T>
8297using start_array_function_t =
8298 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8299
8300template<typename T>
8301using end_array_function_t = decltype(std::declval<T&>().end_array());
8302
8303template<typename T, typename Exception>
8304using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8305 std::declval<std::size_t>(), std::declval<const std::string&>(),
8306 std::declval<const Exception&>()));
8307
8308template<typename SAX, typename BasicJsonType>
8309struct is_sax
8310{
8311 private:
8312 static_assert(is_basic_json<BasicJsonType>::value,
8313 "BasicJsonType must be of type basic_json<...>");
8314
8315 using number_integer_t = typename BasicJsonType::number_integer_t;
8316 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8317 using number_float_t = typename BasicJsonType::number_float_t;
8318 using string_t = typename BasicJsonType::string_t;
8319 using binary_t = typename BasicJsonType::binary_t;
8320 using exception_t = typename BasicJsonType::exception;
8321
8322 public:
8323 static constexpr bool value =
8324 is_detected_exact<bool, null_function_t, SAX>::value &&
8325 is_detected_exact<bool, boolean_function_t, SAX>::value &&
8326 is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
8327 is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
8328 is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
8329 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
8330 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
8331 is_detected_exact<bool, start_object_function_t, SAX>::value &&
8332 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
8333 is_detected_exact<bool, end_object_function_t, SAX>::value &&
8334 is_detected_exact<bool, start_array_function_t, SAX>::value &&
8335 is_detected_exact<bool, end_array_function_t, SAX>::value &&
8336 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
8337};
8338
8339template<typename SAX, typename BasicJsonType>
8340struct is_sax_static_asserts
8341{
8342 private:
8343 static_assert(is_basic_json<BasicJsonType>::value,
8344 "BasicJsonType must be of type basic_json<...>");
8345
8346 using number_integer_t = typename BasicJsonType::number_integer_t;
8347 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8348 using number_float_t = typename BasicJsonType::number_float_t;
8349 using string_t = typename BasicJsonType::string_t;
8350 using binary_t = typename BasicJsonType::binary_t;
8351 using exception_t = typename BasicJsonType::exception;
8352
8353 public:
8354 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
8355 "Missing/invalid function: bool null()");
8356 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8357 "Missing/invalid function: bool boolean(bool)");
8358 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8359 "Missing/invalid function: bool boolean(bool)");
8360 static_assert(
8361 is_detected_exact<bool, number_integer_function_t, SAX,
8362 number_integer_t>::value,
8363 "Missing/invalid function: bool number_integer(number_integer_t)");
8364 static_assert(
8365 is_detected_exact<bool, number_unsigned_function_t, SAX,
8366 number_unsigned_t>::value,
8367 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8368 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8369 number_float_t, string_t>::value,
8370 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8371 static_assert(
8372 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
8373 "Missing/invalid function: bool string(string_t&)");
8374 static_assert(
8375 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
8376 "Missing/invalid function: bool binary(binary_t&)");
8377 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
8378 "Missing/invalid function: bool start_object(std::size_t)");
8379 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
8380 "Missing/invalid function: bool key(string_t&)");
8381 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
8382 "Missing/invalid function: bool end_object()");
8383 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
8384 "Missing/invalid function: bool start_array(std::size_t)");
8385 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
8386 "Missing/invalid function: bool end_array()");
8387 static_assert(
8388 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
8389 "Missing/invalid function: bool parse_error(std::size_t, const "
8390 "std::string&, const exception&)");
8391};
8392} // namespace detail
8393} // namespace nlohmann
8394
8395// #include <nlohmann/detail/meta/type_traits.hpp>
8396
8397// #include <nlohmann/detail/value_t.hpp>
8398
8399
8400namespace nlohmann
8401{
8402namespace detail
8403{
8404
8406enum class cbor_tag_handler_t
8407{
8408 error,
8409 ignore,
8410 store
8411};
8412
8420static inline bool little_endianess(int num = 1) noexcept
8421{
8422 return *reinterpret_cast<char*>(&num) == 1;
8423}
8424
8425
8427// binary reader //
8429
8433template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8434class binary_reader
8435{
8436 using number_integer_t = typename BasicJsonType::number_integer_t;
8437 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8438 using number_float_t = typename BasicJsonType::number_float_t;
8439 using string_t = typename BasicJsonType::string_t;
8440 using binary_t = typename BasicJsonType::binary_t;
8441 using json_sax_t = SAX;
8442 using char_type = typename InputAdapterType::char_type;
8443 using char_int_type = typename std::char_traits<char_type>::int_type;
8444
8445 public:
8451 explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
8452 {
8453 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
8454 }
8455
8456 // make class move-only
8457 binary_reader(const binary_reader&) = delete;
8458 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8459 binary_reader& operator=(const binary_reader&) = delete;
8460 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8461 ~binary_reader() = default;
8462
8471 JSON_HEDLEY_NON_NULL(3)
8472 bool sax_parse(const input_format_t format,
8473 json_sax_t* sax_,
8474 const bool strict = true,
8475 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8476 {
8477 sax = sax_;
8478 bool result = false;
8479
8480 switch (format)
8481 {
8482 case input_format_t::bson:
8483 result = parse_bson_internal();
8484 break;
8485
8486 case input_format_t::cbor:
8487 result = parse_cbor_internal(true, tag_handler);
8488 break;
8489
8490 case input_format_t::msgpack:
8491 result = parse_msgpack_internal();
8492 break;
8493
8494 case input_format_t::ubjson:
8495 result = parse_ubjson_internal();
8496 break;
8497
8498 case input_format_t::json: // LCOV_EXCL_LINE
8499 default: // LCOV_EXCL_LINE
8500 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8501 }
8502
8503 // strict mode: next byte must be EOF
8504 if (result && strict)
8505 {
8506 if (format == input_format_t::ubjson)
8507 {
8508 get_ignore_noop();
8509 }
8510 else
8511 {
8512 get();
8513 }
8514
8515 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8516 {
8517 return sax->parse_error(chars_read, get_token_string(),
8518 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
8519 }
8520 }
8521
8522 return result;
8523 }
8524
8525 private:
8527 // BSON //
8529
8534 bool parse_bson_internal()
8535 {
8536 std::int32_t document_size{};
8537 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8538
8539 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
8540 {
8541 return false;
8542 }
8543
8544 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8545 {
8546 return false;
8547 }
8548
8549 return sax->end_object();
8550 }
8551
8559 bool get_bson_cstr(string_t& result)
8560 {
8561 auto out = std::back_inserter(result);
8562 while (true)
8563 {
8564 get();
8565 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
8566 {
8567 return false;
8568 }
8569 if (current == 0x00)
8570 {
8571 return true;
8572 }
8573 *out++ = static_cast<typename string_t::value_type>(current);
8574 }
8575 }
8576
8588 template<typename NumberType>
8589 bool get_bson_string(const NumberType len, string_t& result)
8590 {
8591 if (JSON_HEDLEY_UNLIKELY(len < 1))
8592 {
8593 auto last_token = get_token_string();
8594 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()));
8595 }
8596
8597 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8598 }
8599
8609 template<typename NumberType>
8610 bool get_bson_binary(const NumberType len, binary_t& result)
8611 {
8612 if (JSON_HEDLEY_UNLIKELY(len < 0))
8613 {
8614 auto last_token = get_token_string();
8615 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()));
8616 }
8617
8618 // All BSON binary values have a subtype
8619 std::uint8_t subtype{};
8620 get_number<std::uint8_t>(input_format_t::bson, subtype);
8621 result.set_subtype(subtype);
8622
8623 return get_binary(input_format_t::bson, len, result);
8624 }
8625
8636 bool parse_bson_element_internal(const char_int_type element_type,
8637 const std::size_t element_type_parse_position)
8638 {
8639 switch (element_type)
8640 {
8641 case 0x01: // double
8642 {
8643 double number{};
8644 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8645 }
8646
8647 case 0x02: // string
8648 {
8649 std::int32_t len{};
8650 string_t value;
8651 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8652 }
8653
8654 case 0x03: // object
8655 {
8656 return parse_bson_internal();
8657 }
8658
8659 case 0x04: // array
8660 {
8661 return parse_bson_array();
8662 }
8663
8664 case 0x05: // binary
8665 {
8666 std::int32_t len{};
8667 binary_t value;
8668 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8669 }
8670
8671 case 0x08: // boolean
8672 {
8673 return sax->boolean(get() != 0);
8674 }
8675
8676 case 0x0A: // null
8677 {
8678 return sax->null();
8679 }
8680
8681 case 0x10: // int32
8682 {
8683 std::int32_t value{};
8684 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8685 }
8686
8687 case 0x12: // int64
8688 {
8689 std::int64_t value{};
8690 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8691 }
8692
8693 default: // anything else not supported (yet)
8694 {
8695 std::array<char, 3> cr{{}};
8696 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8697 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()));
8698 }
8699 }
8700 }
8701
8714 bool parse_bson_element_list(const bool is_array)
8715 {
8716 string_t key;
8717
8718 while (auto element_type = get())
8719 {
8720 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8721 {
8722 return false;
8723 }
8724
8725 const std::size_t element_type_parse_position = chars_read;
8726 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8727 {
8728 return false;
8729 }
8730
8731 if (!is_array && !sax->key(key))
8732 {
8733 return false;
8734 }
8735
8736 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8737 {
8738 return false;
8739 }
8740
8741 // get_bson_cstr only appends
8742 key.clear();
8743 }
8744
8745 return true;
8746 }
8747
8752 bool parse_bson_array()
8753 {
8754 std::int32_t document_size{};
8755 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8756
8757 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8758 {
8759 return false;
8760 }
8761
8762 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8763 {
8764 return false;
8765 }
8766
8767 return sax->end_array();
8768 }
8769
8771 // CBOR //
8773
8782 bool parse_cbor_internal(const bool get_char,
8783 const cbor_tag_handler_t tag_handler)
8784 {
8785 switch (get_char ? get() : current)
8786 {
8787 // EOF
8788 case std::char_traits<char_type>::eof():
8789 return unexpect_eof(input_format_t::cbor, "value");
8790
8791 // Integer 0x00..0x17 (0..23)
8792 case 0x00:
8793 case 0x01:
8794 case 0x02:
8795 case 0x03:
8796 case 0x04:
8797 case 0x05:
8798 case 0x06:
8799 case 0x07:
8800 case 0x08:
8801 case 0x09:
8802 case 0x0A:
8803 case 0x0B:
8804 case 0x0C:
8805 case 0x0D:
8806 case 0x0E:
8807 case 0x0F:
8808 case 0x10:
8809 case 0x11:
8810 case 0x12:
8811 case 0x13:
8812 case 0x14:
8813 case 0x15:
8814 case 0x16:
8815 case 0x17:
8816 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8817
8818 case 0x18: // Unsigned integer (one-byte uint8_t follows)
8819 {
8820 std::uint8_t number{};
8821 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8822 }
8823
8824 case 0x19: // Unsigned integer (two-byte uint16_t follows)
8825 {
8826 std::uint16_t number{};
8827 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8828 }
8829
8830 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8831 {
8832 std::uint32_t number{};
8833 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8834 }
8835
8836 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8837 {
8838 std::uint64_t number{};
8839 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8840 }
8841
8842 // Negative integer -1-0x00..-1-0x17 (-1..-24)
8843 case 0x20:
8844 case 0x21:
8845 case 0x22:
8846 case 0x23:
8847 case 0x24:
8848 case 0x25:
8849 case 0x26:
8850 case 0x27:
8851 case 0x28:
8852 case 0x29:
8853 case 0x2A:
8854 case 0x2B:
8855 case 0x2C:
8856 case 0x2D:
8857 case 0x2E:
8858 case 0x2F:
8859 case 0x30:
8860 case 0x31:
8861 case 0x32:
8862 case 0x33:
8863 case 0x34:
8864 case 0x35:
8865 case 0x36:
8866 case 0x37:
8867 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8868
8869 case 0x38: // Negative integer (one-byte uint8_t follows)
8870 {
8871 std::uint8_t number{};
8872 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8873 }
8874
8875 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8876 {
8877 std::uint16_t number{};
8878 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8879 }
8880
8881 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8882 {
8883 std::uint32_t number{};
8884 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8885 }
8886
8887 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8888 {
8889 std::uint64_t number{};
8890 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8891 - static_cast<number_integer_t>(number));
8892 }
8893
8894 // Binary data (0x00..0x17 bytes follow)
8895 case 0x40:
8896 case 0x41:
8897 case 0x42:
8898 case 0x43:
8899 case 0x44:
8900 case 0x45:
8901 case 0x46:
8902 case 0x47:
8903 case 0x48:
8904 case 0x49:
8905 case 0x4A:
8906 case 0x4B:
8907 case 0x4C:
8908 case 0x4D:
8909 case 0x4E:
8910 case 0x4F:
8911 case 0x50:
8912 case 0x51:
8913 case 0x52:
8914 case 0x53:
8915 case 0x54:
8916 case 0x55:
8917 case 0x56:
8918 case 0x57:
8919 case 0x58: // Binary data (one-byte uint8_t for n follows)
8920 case 0x59: // Binary data (two-byte uint16_t for n follow)
8921 case 0x5A: // Binary data (four-byte uint32_t for n follow)
8922 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8923 case 0x5F: // Binary data (indefinite length)
8924 {
8925 binary_t b;
8926 return get_cbor_binary(b) && sax->binary(b);
8927 }
8928
8929 // UTF-8 string (0x00..0x17 bytes follow)
8930 case 0x60:
8931 case 0x61:
8932 case 0x62:
8933 case 0x63:
8934 case 0x64:
8935 case 0x65:
8936 case 0x66:
8937 case 0x67:
8938 case 0x68:
8939 case 0x69:
8940 case 0x6A:
8941 case 0x6B:
8942 case 0x6C:
8943 case 0x6D:
8944 case 0x6E:
8945 case 0x6F:
8946 case 0x70:
8947 case 0x71:
8948 case 0x72:
8949 case 0x73:
8950 case 0x74:
8951 case 0x75:
8952 case 0x76:
8953 case 0x77:
8954 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8955 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8956 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8957 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8958 case 0x7F: // UTF-8 string (indefinite length)
8959 {
8960 string_t s;
8961 return get_cbor_string(s) && sax->string(s);
8962 }
8963
8964 // array (0x00..0x17 data items follow)
8965 case 0x80:
8966 case 0x81:
8967 case 0x82:
8968 case 0x83:
8969 case 0x84:
8970 case 0x85:
8971 case 0x86:
8972 case 0x87:
8973 case 0x88:
8974 case 0x89:
8975 case 0x8A:
8976 case 0x8B:
8977 case 0x8C:
8978 case 0x8D:
8979 case 0x8E:
8980 case 0x8F:
8981 case 0x90:
8982 case 0x91:
8983 case 0x92:
8984 case 0x93:
8985 case 0x94:
8986 case 0x95:
8987 case 0x96:
8988 case 0x97:
8989 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8990
8991 case 0x98: // array (one-byte uint8_t for n follows)
8992 {
8993 std::uint8_t len{};
8994 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8995 }
8996
8997 case 0x99: // array (two-byte uint16_t for n follow)
8998 {
8999 std::uint16_t len{};
9000 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9001 }
9002
9003 case 0x9A: // array (four-byte uint32_t for n follow)
9004 {
9005 std::uint32_t len{};
9006 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9007 }
9008
9009 case 0x9B: // array (eight-byte uint64_t for n follow)
9010 {
9011 std::uint64_t len{};
9012 return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9013 }
9014
9015 case 0x9F: // array (indefinite length)
9016 return get_cbor_array(std::size_t(-1), tag_handler);
9017
9018 // map (0x00..0x17 pairs of data items follow)
9019 case 0xA0:
9020 case 0xA1:
9021 case 0xA2:
9022 case 0xA3:
9023 case 0xA4:
9024 case 0xA5:
9025 case 0xA6:
9026 case 0xA7:
9027 case 0xA8:
9028 case 0xA9:
9029 case 0xAA:
9030 case 0xAB:
9031 case 0xAC:
9032 case 0xAD:
9033 case 0xAE:
9034 case 0xAF:
9035 case 0xB0:
9036 case 0xB1:
9037 case 0xB2:
9038 case 0xB3:
9039 case 0xB4:
9040 case 0xB5:
9041 case 0xB6:
9042 case 0xB7:
9043 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9044
9045 case 0xB8: // map (one-byte uint8_t for n follows)
9046 {
9047 std::uint8_t len{};
9048 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9049 }
9050
9051 case 0xB9: // map (two-byte uint16_t for n follow)
9052 {
9053 std::uint16_t len{};
9054 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9055 }
9056
9057 case 0xBA: // map (four-byte uint32_t for n follow)
9058 {
9059 std::uint32_t len{};
9060 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9061 }
9062
9063 case 0xBB: // map (eight-byte uint64_t for n follow)
9064 {
9065 std::uint64_t len{};
9066 return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9067 }
9068
9069 case 0xBF: // map (indefinite length)
9070 return get_cbor_object(std::size_t(-1), tag_handler);
9071
9072 case 0xC6: // tagged item
9073 case 0xC7:
9074 case 0xC8:
9075 case 0xC9:
9076 case 0xCA:
9077 case 0xCB:
9078 case 0xCC:
9079 case 0xCD:
9080 case 0xCE:
9081 case 0xCF:
9082 case 0xD0:
9083 case 0xD1:
9084 case 0xD2:
9085 case 0xD3:
9086 case 0xD4:
9087 case 0xD8: // tagged item (1 bytes follow)
9088 case 0xD9: // tagged item (2 bytes follow)
9089 case 0xDA: // tagged item (4 bytes follow)
9090 case 0xDB: // tagged item (8 bytes follow)
9091 {
9092 switch (tag_handler)
9093 {
9094 case cbor_tag_handler_t::error:
9095 {
9096 auto last_token = get_token_string();
9097 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()));
9098 }
9099
9100 case cbor_tag_handler_t::ignore:
9101 {
9102 // ignore binary subtype
9103 switch (current)
9104 {
9105 case 0xD8:
9106 {
9107 std::uint8_t subtype_to_ignore{};
9108 get_number(input_format_t::cbor, subtype_to_ignore);
9109 break;
9110 }
9111 case 0xD9:
9112 {
9113 std::uint16_t subtype_to_ignore{};
9114 get_number(input_format_t::cbor, subtype_to_ignore);
9115 break;
9116 }
9117 case 0xDA:
9118 {
9119 std::uint32_t subtype_to_ignore{};
9120 get_number(input_format_t::cbor, subtype_to_ignore);
9121 break;
9122 }
9123 case 0xDB:
9124 {
9125 std::uint64_t subtype_to_ignore{};
9126 get_number(input_format_t::cbor, subtype_to_ignore);
9127 break;
9128 }
9129 default:
9130 break;
9131 }
9132 return parse_cbor_internal(true, tag_handler);
9133 }
9134
9135 case cbor_tag_handler_t::store:
9136 {
9137 binary_t b;
9138 // use binary subtype and store in binary container
9139 switch (current)
9140 {
9141 case 0xD8:
9142 {
9143 std::uint8_t subtype{};
9144 get_number(input_format_t::cbor, subtype);
9145 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9146 break;
9147 }
9148 case 0xD9:
9149 {
9150 std::uint16_t subtype{};
9151 get_number(input_format_t::cbor, subtype);
9152 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9153 break;
9154 }
9155 case 0xDA:
9156 {
9157 std::uint32_t subtype{};
9158 get_number(input_format_t::cbor, subtype);
9159 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9160 break;
9161 }
9162 case 0xDB:
9163 {
9164 std::uint64_t subtype{};
9165 get_number(input_format_t::cbor, subtype);
9166 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9167 break;
9168 }
9169 default:
9170 return parse_cbor_internal(true, tag_handler);
9171 }
9172 get();
9173 return get_cbor_binary(b) && sax->binary(b);
9174 }
9175
9176 default: // LCOV_EXCL_LINE
9177 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9178 return false; // LCOV_EXCL_LINE
9179 }
9180 }
9181
9182 case 0xF4: // false
9183 return sax->boolean(false);
9184
9185 case 0xF5: // true
9186 return sax->boolean(true);
9187
9188 case 0xF6: // null
9189 return sax->null();
9190
9191 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9192 {
9193 const auto byte1_raw = get();
9194 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9195 {
9196 return false;
9197 }
9198 const auto byte2_raw = get();
9199 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9200 {
9201 return false;
9202 }
9203
9204 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9205 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9206
9207 // code from RFC 7049, Appendix D, Figure 3:
9208 // As half-precision floating-point numbers were only added
9209 // to IEEE 754 in 2008, today's programming platforms often
9210 // still only have limited support for them. It is very
9211 // easy to include at least decoding support for them even
9212 // without such support. An example of a small decoder for
9213 // half-precision floating-point numbers in the C language
9214 // is shown in Fig. 3.
9215 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9216 const double val = [&half]
9217 {
9218 const int exp = (half >> 10u) & 0x1Fu;
9219 const unsigned int mant = half & 0x3FFu;
9220 JSON_ASSERT(0 <= exp&& exp <= 32);
9221 JSON_ASSERT(mant <= 1024);
9222 switch (exp)
9223 {
9224 case 0:
9225 return std::ldexp(mant, -24);
9226 case 31:
9227 return (mant == 0)
9228 ? std::numeric_limits<double>::infinity()
9229 : std::numeric_limits<double>::quiet_NaN();
9230 default:
9231 return std::ldexp(mant + 1024, exp - 25);
9232 }
9233 }();
9234 return sax->number_float((half & 0x8000u) != 0
9235 ? static_cast<number_float_t>(-val)
9236 : static_cast<number_float_t>(val), "");
9237 }
9238
9239 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9240 {
9241 float number{};
9242 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9243 }
9244
9245 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9246 {
9247 double number{};
9248 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9249 }
9250
9251 default: // anything else (0xFF is handled inside the other types)
9252 {
9253 auto last_token = get_token_string();
9254 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()));
9255 }
9256 }
9257 }
9258
9270 bool get_cbor_string(string_t& result)
9271 {
9272 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9273 {
9274 return false;
9275 }
9276
9277 switch (current)
9278 {
9279 // UTF-8 string (0x00..0x17 bytes follow)
9280 case 0x60:
9281 case 0x61:
9282 case 0x62:
9283 case 0x63:
9284 case 0x64:
9285 case 0x65:
9286 case 0x66:
9287 case 0x67:
9288 case 0x68:
9289 case 0x69:
9290 case 0x6A:
9291 case 0x6B:
9292 case 0x6C:
9293 case 0x6D:
9294 case 0x6E:
9295 case 0x6F:
9296 case 0x70:
9297 case 0x71:
9298 case 0x72:
9299 case 0x73:
9300 case 0x74:
9301 case 0x75:
9302 case 0x76:
9303 case 0x77:
9304 {
9305 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9306 }
9307
9308 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9309 {
9310 std::uint8_t len{};
9311 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9312 }
9313
9314 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9315 {
9316 std::uint16_t len{};
9317 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9318 }
9319
9320 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9321 {
9322 std::uint32_t len{};
9323 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9324 }
9325
9326 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9327 {
9328 std::uint64_t len{};
9329 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9330 }
9331
9332 case 0x7F: // UTF-8 string (indefinite length)
9333 {
9334 while (get() != 0xFF)
9335 {
9336 string_t chunk;
9337 if (!get_cbor_string(chunk))
9338 {
9339 return false;
9340 }
9341 result.append(chunk);
9342 }
9343 return true;
9344 }
9345
9346 default:
9347 {
9348 auto last_token = get_token_string();
9349 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()));
9350 }
9351 }
9352 }
9353
9365 bool get_cbor_binary(binary_t& result)
9366 {
9367 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
9368 {
9369 return false;
9370 }
9371
9372 switch (current)
9373 {
9374 // Binary data (0x00..0x17 bytes follow)
9375 case 0x40:
9376 case 0x41:
9377 case 0x42:
9378 case 0x43:
9379 case 0x44:
9380 case 0x45:
9381 case 0x46:
9382 case 0x47:
9383 case 0x48:
9384 case 0x49:
9385 case 0x4A:
9386 case 0x4B:
9387 case 0x4C:
9388 case 0x4D:
9389 case 0x4E:
9390 case 0x4F:
9391 case 0x50:
9392 case 0x51:
9393 case 0x52:
9394 case 0x53:
9395 case 0x54:
9396 case 0x55:
9397 case 0x56:
9398 case 0x57:
9399 {
9400 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9401 }
9402
9403 case 0x58: // Binary data (one-byte uint8_t for n follows)
9404 {
9405 std::uint8_t len{};
9406 return get_number(input_format_t::cbor, len) &&
9407 get_binary(input_format_t::cbor, len, result);
9408 }
9409
9410 case 0x59: // Binary data (two-byte uint16_t for n follow)
9411 {
9412 std::uint16_t len{};
9413 return get_number(input_format_t::cbor, len) &&
9414 get_binary(input_format_t::cbor, len, result);
9415 }
9416
9417 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9418 {
9419 std::uint32_t len{};
9420 return get_number(input_format_t::cbor, len) &&
9421 get_binary(input_format_t::cbor, len, result);
9422 }
9423
9424 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9425 {
9426 std::uint64_t len{};
9427 return get_number(input_format_t::cbor, len) &&
9428 get_binary(input_format_t::cbor, len, result);
9429 }
9430
9431 case 0x5F: // Binary data (indefinite length)
9432 {
9433 while (get() != 0xFF)
9434 {
9435 binary_t chunk;
9436 if (!get_cbor_binary(chunk))
9437 {
9438 return false;
9439 }
9440 result.insert(result.end(), chunk.begin(), chunk.end());
9441 }
9442 return true;
9443 }
9444
9445 default:
9446 {
9447 auto last_token = get_token_string();
9448 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()));
9449 }
9450 }
9451 }
9452
9459 bool get_cbor_array(const std::size_t len,
9460 const cbor_tag_handler_t tag_handler)
9461 {
9462 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9463 {
9464 return false;
9465 }
9466
9467 if (len != std::size_t(-1))
9468 {
9469 for (std::size_t i = 0; i < len; ++i)
9470 {
9471 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9472 {
9473 return false;
9474 }
9475 }
9476 }
9477 else
9478 {
9479 while (get() != 0xFF)
9480 {
9481 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9482 {
9483 return false;
9484 }
9485 }
9486 }
9487
9488 return sax->end_array();
9489 }
9490
9497 bool get_cbor_object(const std::size_t len,
9498 const cbor_tag_handler_t tag_handler)
9499 {
9500 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9501 {
9502 return false;
9503 }
9504
9505 if (len != 0)
9506 {
9507 string_t key;
9508 if (len != std::size_t(-1))
9509 {
9510 for (std::size_t i = 0; i < len; ++i)
9511 {
9512 get();
9513 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9514 {
9515 return false;
9516 }
9517
9518 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9519 {
9520 return false;
9521 }
9522 key.clear();
9523 }
9524 }
9525 else
9526 {
9527 while (get() != 0xFF)
9528 {
9529 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9530 {
9531 return false;
9532 }
9533
9534 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9535 {
9536 return false;
9537 }
9538 key.clear();
9539 }
9540 }
9541 }
9542
9543 return sax->end_object();
9544 }
9545
9547 // MsgPack //
9549
9553 bool parse_msgpack_internal()
9554 {
9555 switch (get())
9556 {
9557 // EOF
9558 case std::char_traits<char_type>::eof():
9559 return unexpect_eof(input_format_t::msgpack, "value");
9560
9561 // positive fixint
9562 case 0x00:
9563 case 0x01:
9564 case 0x02:
9565 case 0x03:
9566 case 0x04:
9567 case 0x05:
9568 case 0x06:
9569 case 0x07:
9570 case 0x08:
9571 case 0x09:
9572 case 0x0A:
9573 case 0x0B:
9574 case 0x0C:
9575 case 0x0D:
9576 case 0x0E:
9577 case 0x0F:
9578 case 0x10:
9579 case 0x11:
9580 case 0x12:
9581 case 0x13:
9582 case 0x14:
9583 case 0x15:
9584 case 0x16:
9585 case 0x17:
9586 case 0x18:
9587 case 0x19:
9588 case 0x1A:
9589 case 0x1B:
9590 case 0x1C:
9591 case 0x1D:
9592 case 0x1E:
9593 case 0x1F:
9594 case 0x20:
9595 case 0x21:
9596 case 0x22:
9597 case 0x23:
9598 case 0x24:
9599 case 0x25:
9600 case 0x26:
9601 case 0x27:
9602 case 0x28:
9603 case 0x29:
9604 case 0x2A:
9605 case 0x2B:
9606 case 0x2C:
9607 case 0x2D:
9608 case 0x2E:
9609 case 0x2F:
9610 case 0x30:
9611 case 0x31:
9612 case 0x32:
9613 case 0x33:
9614 case 0x34:
9615 case 0x35:
9616 case 0x36:
9617 case 0x37:
9618 case 0x38:
9619 case 0x39:
9620 case 0x3A:
9621 case 0x3B:
9622 case 0x3C:
9623 case 0x3D:
9624 case 0x3E:
9625 case 0x3F:
9626 case 0x40:
9627 case 0x41:
9628 case 0x42:
9629 case 0x43:
9630 case 0x44:
9631 case 0x45:
9632 case 0x46:
9633 case 0x47:
9634 case 0x48:
9635 case 0x49:
9636 case 0x4A:
9637 case 0x4B:
9638 case 0x4C:
9639 case 0x4D:
9640 case 0x4E:
9641 case 0x4F:
9642 case 0x50:
9643 case 0x51:
9644 case 0x52:
9645 case 0x53:
9646 case 0x54:
9647 case 0x55:
9648 case 0x56:
9649 case 0x57:
9650 case 0x58:
9651 case 0x59:
9652 case 0x5A:
9653 case 0x5B:
9654 case 0x5C:
9655 case 0x5D:
9656 case 0x5E:
9657 case 0x5F:
9658 case 0x60:
9659 case 0x61:
9660 case 0x62:
9661 case 0x63:
9662 case 0x64:
9663 case 0x65:
9664 case 0x66:
9665 case 0x67:
9666 case 0x68:
9667 case 0x69:
9668 case 0x6A:
9669 case 0x6B:
9670 case 0x6C:
9671 case 0x6D:
9672 case 0x6E:
9673 case 0x6F:
9674 case 0x70:
9675 case 0x71:
9676 case 0x72:
9677 case 0x73:
9678 case 0x74:
9679 case 0x75:
9680 case 0x76:
9681 case 0x77:
9682 case 0x78:
9683 case 0x79:
9684 case 0x7A:
9685 case 0x7B:
9686 case 0x7C:
9687 case 0x7D:
9688 case 0x7E:
9689 case 0x7F:
9690 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9691
9692 // fixmap
9693 case 0x80:
9694 case 0x81:
9695 case 0x82:
9696 case 0x83:
9697 case 0x84:
9698 case 0x85:
9699 case 0x86:
9700 case 0x87:
9701 case 0x88:
9702 case 0x89:
9703 case 0x8A:
9704 case 0x8B:
9705 case 0x8C:
9706 case 0x8D:
9707 case 0x8E:
9708 case 0x8F:
9709 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9710
9711 // fixarray
9712 case 0x90:
9713 case 0x91:
9714 case 0x92:
9715 case 0x93:
9716 case 0x94:
9717 case 0x95:
9718 case 0x96:
9719 case 0x97:
9720 case 0x98:
9721 case 0x99:
9722 case 0x9A:
9723 case 0x9B:
9724 case 0x9C:
9725 case 0x9D:
9726 case 0x9E:
9727 case 0x9F:
9728 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9729
9730 // fixstr
9731 case 0xA0:
9732 case 0xA1:
9733 case 0xA2:
9734 case 0xA3:
9735 case 0xA4:
9736 case 0xA5:
9737 case 0xA6:
9738 case 0xA7:
9739 case 0xA8:
9740 case 0xA9:
9741 case 0xAA:
9742 case 0xAB:
9743 case 0xAC:
9744 case 0xAD:
9745 case 0xAE:
9746 case 0xAF:
9747 case 0xB0:
9748 case 0xB1:
9749 case 0xB2:
9750 case 0xB3:
9751 case 0xB4:
9752 case 0xB5:
9753 case 0xB6:
9754 case 0xB7:
9755 case 0xB8:
9756 case 0xB9:
9757 case 0xBA:
9758 case 0xBB:
9759 case 0xBC:
9760 case 0xBD:
9761 case 0xBE:
9762 case 0xBF:
9763 case 0xD9: // str 8
9764 case 0xDA: // str 16
9765 case 0xDB: // str 32
9766 {
9767 string_t s;
9768 return get_msgpack_string(s) && sax->string(s);
9769 }
9770
9771 case 0xC0: // nil
9772 return sax->null();
9773
9774 case 0xC2: // false
9775 return sax->boolean(false);
9776
9777 case 0xC3: // true
9778 return sax->boolean(true);
9779
9780 case 0xC4: // bin 8
9781 case 0xC5: // bin 16
9782 case 0xC6: // bin 32
9783 case 0xC7: // ext 8
9784 case 0xC8: // ext 16
9785 case 0xC9: // ext 32
9786 case 0xD4: // fixext 1
9787 case 0xD5: // fixext 2
9788 case 0xD6: // fixext 4
9789 case 0xD7: // fixext 8
9790 case 0xD8: // fixext 16
9791 {
9792 binary_t b;
9793 return get_msgpack_binary(b) && sax->binary(b);
9794 }
9795
9796 case 0xCA: // float 32
9797 {
9798 float number{};
9799 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9800 }
9801
9802 case 0xCB: // float 64
9803 {
9804 double number{};
9805 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9806 }
9807
9808 case 0xCC: // uint 8
9809 {
9810 std::uint8_t number{};
9811 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9812 }
9813
9814 case 0xCD: // uint 16
9815 {
9816 std::uint16_t number{};
9817 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9818 }
9819
9820 case 0xCE: // uint 32
9821 {
9822 std::uint32_t number{};
9823 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9824 }
9825
9826 case 0xCF: // uint 64
9827 {
9828 std::uint64_t number{};
9829 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9830 }
9831
9832 case 0xD0: // int 8
9833 {
9834 std::int8_t number{};
9835 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9836 }
9837
9838 case 0xD1: // int 16
9839 {
9840 std::int16_t number{};
9841 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9842 }
9843
9844 case 0xD2: // int 32
9845 {
9846 std::int32_t number{};
9847 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9848 }
9849
9850 case 0xD3: // int 64
9851 {
9852 std::int64_t number{};
9853 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9854 }
9855
9856 case 0xDC: // array 16
9857 {
9858 std::uint16_t len{};
9859 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9860 }
9861
9862 case 0xDD: // array 32
9863 {
9864 std::uint32_t len{};
9865 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9866 }
9867
9868 case 0xDE: // map 16
9869 {
9870 std::uint16_t len{};
9871 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9872 }
9873
9874 case 0xDF: // map 32
9875 {
9876 std::uint32_t len{};
9877 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9878 }
9879
9880 // negative fixint
9881 case 0xE0:
9882 case 0xE1:
9883 case 0xE2:
9884 case 0xE3:
9885 case 0xE4:
9886 case 0xE5:
9887 case 0xE6:
9888 case 0xE7:
9889 case 0xE8:
9890 case 0xE9:
9891 case 0xEA:
9892 case 0xEB:
9893 case 0xEC:
9894 case 0xED:
9895 case 0xEE:
9896 case 0xEF:
9897 case 0xF0:
9898 case 0xF1:
9899 case 0xF2:
9900 case 0xF3:
9901 case 0xF4:
9902 case 0xF5:
9903 case 0xF6:
9904 case 0xF7:
9905 case 0xF8:
9906 case 0xF9:
9907 case 0xFA:
9908 case 0xFB:
9909 case 0xFC:
9910 case 0xFD:
9911 case 0xFE:
9912 case 0xFF:
9913 return sax->number_integer(static_cast<std::int8_t>(current));
9914
9915 default: // anything else
9916 {
9917 auto last_token = get_token_string();
9918 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()));
9919 }
9920 }
9921 }
9922
9933 bool get_msgpack_string(string_t& result)
9934 {
9935 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9936 {
9937 return false;
9938 }
9939
9940 switch (current)
9941 {
9942 // fixstr
9943 case 0xA0:
9944 case 0xA1:
9945 case 0xA2:
9946 case 0xA3:
9947 case 0xA4:
9948 case 0xA5:
9949 case 0xA6:
9950 case 0xA7:
9951 case 0xA8:
9952 case 0xA9:
9953 case 0xAA:
9954 case 0xAB:
9955 case 0xAC:
9956 case 0xAD:
9957 case 0xAE:
9958 case 0xAF:
9959 case 0xB0:
9960 case 0xB1:
9961 case 0xB2:
9962 case 0xB3:
9963 case 0xB4:
9964 case 0xB5:
9965 case 0xB6:
9966 case 0xB7:
9967 case 0xB8:
9968 case 0xB9:
9969 case 0xBA:
9970 case 0xBB:
9971 case 0xBC:
9972 case 0xBD:
9973 case 0xBE:
9974 case 0xBF:
9975 {
9976 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9977 }
9978
9979 case 0xD9: // str 8
9980 {
9981 std::uint8_t len{};
9982 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9983 }
9984
9985 case 0xDA: // str 16
9986 {
9987 std::uint16_t len{};
9988 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9989 }
9990
9991 case 0xDB: // str 32
9992 {
9993 std::uint32_t len{};
9994 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
9995 }
9996
9997 default:
9998 {
9999 auto last_token = get_token_string();
10000 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()));
10001 }
10002 }
10003 }
10004
10015 bool get_msgpack_binary(binary_t& result)
10016 {
10017 // helper function to set the subtype
10018 auto assign_and_return_true = [&result](std::int8_t subtype)
10019 {
10020 result.set_subtype(static_cast<std::uint8_t>(subtype));
10021 return true;
10022 };
10023
10024 switch (current)
10025 {
10026 case 0xC4: // bin 8
10027 {
10028 std::uint8_t len{};
10029 return get_number(input_format_t::msgpack, len) &&
10030 get_binary(input_format_t::msgpack, len, result);
10031 }
10032
10033 case 0xC5: // bin 16
10034 {
10035 std::uint16_t len{};
10036 return get_number(input_format_t::msgpack, len) &&
10037 get_binary(input_format_t::msgpack, len, result);
10038 }
10039
10040 case 0xC6: // bin 32
10041 {
10042 std::uint32_t len{};
10043 return get_number(input_format_t::msgpack, len) &&
10044 get_binary(input_format_t::msgpack, len, result);
10045 }
10046
10047 case 0xC7: // ext 8
10048 {
10049 std::uint8_t len{};
10050 std::int8_t subtype{};
10051 return get_number(input_format_t::msgpack, len) &&
10052 get_number(input_format_t::msgpack, subtype) &&
10053 get_binary(input_format_t::msgpack, len, result) &&
10054 assign_and_return_true(subtype);
10055 }
10056
10057 case 0xC8: // ext 16
10058 {
10059 std::uint16_t len{};
10060 std::int8_t subtype{};
10061 return get_number(input_format_t::msgpack, len) &&
10062 get_number(input_format_t::msgpack, subtype) &&
10063 get_binary(input_format_t::msgpack, len, result) &&
10064 assign_and_return_true(subtype);
10065 }
10066
10067 case 0xC9: // ext 32
10068 {
10069 std::uint32_t len{};
10070 std::int8_t subtype{};
10071 return get_number(input_format_t::msgpack, len) &&
10072 get_number(input_format_t::msgpack, subtype) &&
10073 get_binary(input_format_t::msgpack, len, result) &&
10074 assign_and_return_true(subtype);
10075 }
10076
10077 case 0xD4: // fixext 1
10078 {
10079 std::int8_t subtype{};
10080 return get_number(input_format_t::msgpack, subtype) &&
10081 get_binary(input_format_t::msgpack, 1, result) &&
10082 assign_and_return_true(subtype);
10083 }
10084
10085 case 0xD5: // fixext 2
10086 {
10087 std::int8_t subtype{};
10088 return get_number(input_format_t::msgpack, subtype) &&
10089 get_binary(input_format_t::msgpack, 2, result) &&
10090 assign_and_return_true(subtype);
10091 }
10092
10093 case 0xD6: // fixext 4
10094 {
10095 std::int8_t subtype{};
10096 return get_number(input_format_t::msgpack, subtype) &&
10097 get_binary(input_format_t::msgpack, 4, result) &&
10098 assign_and_return_true(subtype);
10099 }
10100
10101 case 0xD7: // fixext 8
10102 {
10103 std::int8_t subtype{};
10104 return get_number(input_format_t::msgpack, subtype) &&
10105 get_binary(input_format_t::msgpack, 8, result) &&
10106 assign_and_return_true(subtype);
10107 }
10108
10109 case 0xD8: // fixext 16
10110 {
10111 std::int8_t subtype{};
10112 return get_number(input_format_t::msgpack, subtype) &&
10113 get_binary(input_format_t::msgpack, 16, result) &&
10114 assign_and_return_true(subtype);
10115 }
10116
10117 default: // LCOV_EXCL_LINE
10118 return false; // LCOV_EXCL_LINE
10119 }
10120 }
10121
10126 bool get_msgpack_array(const std::size_t len)
10127 {
10128 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10129 {
10130 return false;
10131 }
10132
10133 for (std::size_t i = 0; i < len; ++i)
10134 {
10135 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10136 {
10137 return false;
10138 }
10139 }
10140
10141 return sax->end_array();
10142 }
10143
10148 bool get_msgpack_object(const std::size_t len)
10149 {
10150 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10151 {
10152 return false;
10153 }
10154
10155 string_t key;
10156 for (std::size_t i = 0; i < len; ++i)
10157 {
10158 get();
10159 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10160 {
10161 return false;
10162 }
10163
10164 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10165 {
10166 return false;
10167 }
10168 key.clear();
10169 }
10170
10171 return sax->end_object();
10172 }
10173
10175 // UBJSON //
10177
10185 bool parse_ubjson_internal(const bool get_char = true)
10186 {
10187 return get_ubjson_value(get_char ? get_ignore_noop() : current);
10188 }
10189
10204 bool get_ubjson_string(string_t& result, const bool get_char = true)
10205 {
10206 if (get_char)
10207 {
10208 get(); // TODO(niels): may we ignore N here?
10209 }
10210
10211 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10212 {
10213 return false;
10214 }
10215
10216 switch (current)
10217 {
10218 case 'U':
10219 {
10220 std::uint8_t len{};
10221 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10222 }
10223
10224 case 'i':
10225 {
10226 std::int8_t len{};
10227 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10228 }
10229
10230 case 'I':
10231 {
10232 std::int16_t len{};
10233 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10234 }
10235
10236 case 'l':
10237 {
10238 std::int32_t len{};
10239 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10240 }
10241
10242 case 'L':
10243 {
10244 std::int64_t len{};
10245 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10246 }
10247
10248 default:
10249 auto last_token = get_token_string();
10250 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()));
10251 }
10252 }
10253
10258 bool get_ubjson_size_value(std::size_t& result)
10259 {
10260 switch (get_ignore_noop())
10261 {
10262 case 'U':
10263 {
10264 std::uint8_t number{};
10265 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10266 {
10267 return false;
10268 }
10269 result = static_cast<std::size_t>(number);
10270 return true;
10271 }
10272
10273 case 'i':
10274 {
10275 std::int8_t number{};
10276 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10277 {
10278 return false;
10279 }
10280 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10281 return true;
10282 }
10283
10284 case 'I':
10285 {
10286 std::int16_t number{};
10287 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10288 {
10289 return false;
10290 }
10291 result = static_cast<std::size_t>(number);
10292 return true;
10293 }
10294
10295 case 'l':
10296 {
10297 std::int32_t number{};
10298 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10299 {
10300 return false;
10301 }
10302 result = static_cast<std::size_t>(number);
10303 return true;
10304 }
10305
10306 case 'L':
10307 {
10308 std::int64_t number{};
10309 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10310 {
10311 return false;
10312 }
10313 result = static_cast<std::size_t>(number);
10314 return true;
10315 }
10316
10317 default:
10318 {
10319 auto last_token = get_token_string();
10320 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()));
10321 }
10322 }
10323 }
10324
10335 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
10336 {
10337 result.first = string_t::npos; // size
10338 result.second = 0; // type
10339
10340 get_ignore_noop();
10341
10342 if (current == '$')
10343 {
10344 result.second = get(); // must not ignore 'N', because 'N' maybe the type
10345 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
10346 {
10347 return false;
10348 }
10349
10350 get_ignore_noop();
10351 if (JSON_HEDLEY_UNLIKELY(current != '#'))
10352 {
10353 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10354 {
10355 return false;
10356 }
10357 auto last_token = get_token_string();
10358 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()));
10359 }
10360
10361 return get_ubjson_size_value(result.first);
10362 }
10363
10364 if (current == '#')
10365 {
10366 return get_ubjson_size_value(result.first);
10367 }
10368
10369 return true;
10370 }
10371
10376 bool get_ubjson_value(const char_int_type prefix)
10377 {
10378 switch (prefix)
10379 {
10380 case std::char_traits<char_type>::eof(): // EOF
10381 return unexpect_eof(input_format_t::ubjson, "value");
10382
10383 case 'T': // true
10384 return sax->boolean(true);
10385 case 'F': // false
10386 return sax->boolean(false);
10387
10388 case 'Z': // null
10389 return sax->null();
10390
10391 case 'U':
10392 {
10393 std::uint8_t number{};
10394 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
10395 }
10396
10397 case 'i':
10398 {
10399 std::int8_t number{};
10400 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10401 }
10402
10403 case 'I':
10404 {
10405 std::int16_t number{};
10406 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10407 }
10408
10409 case 'l':
10410 {
10411 std::int32_t number{};
10412 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10413 }
10414
10415 case 'L':
10416 {
10417 std::int64_t number{};
10418 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10419 }
10420
10421 case 'd':
10422 {
10423 float number{};
10424 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10425 }
10426
10427 case 'D':
10428 {
10429 double number{};
10430 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10431 }
10432
10433 case 'H':
10434 {
10435 return get_ubjson_high_precision_number();
10436 }
10437
10438 case 'C': // char
10439 {
10440 get();
10441 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
10442 {
10443 return false;
10444 }
10445 if (JSON_HEDLEY_UNLIKELY(current > 127))
10446 {
10447 auto last_token = get_token_string();
10448 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()));
10449 }
10450 string_t s(1, static_cast<typename string_t::value_type>(current));
10451 return sax->string(s);
10452 }
10453
10454 case 'S': // string
10455 {
10456 string_t s;
10457 return get_ubjson_string(s) && sax->string(s);
10458 }
10459
10460 case '[': // array
10461 return get_ubjson_array();
10462
10463 case '{': // object
10464 return get_ubjson_object();
10465
10466 default: // anything else
10467 {
10468 auto last_token = get_token_string();
10469 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()));
10470 }
10471 }
10472 }
10473
10477 bool get_ubjson_array()
10478 {
10479 std::pair<std::size_t, char_int_type> size_and_type;
10480 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10481 {
10482 return false;
10483 }
10484
10485 if (size_and_type.first != string_t::npos)
10486 {
10487 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
10488 {
10489 return false;
10490 }
10491
10492 if (size_and_type.second != 0)
10493 {
10494 if (size_and_type.second != 'N')
10495 {
10496 for (std::size_t i = 0; i < size_and_type.first; ++i)
10497 {
10498 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10499 {
10500 return false;
10501 }
10502 }
10503 }
10504 }
10505 else
10506 {
10507 for (std::size_t i = 0; i < size_and_type.first; ++i)
10508 {
10509 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10510 {
10511 return false;
10512 }
10513 }
10514 }
10515 }
10516 else
10517 {
10518 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10519 {
10520 return false;
10521 }
10522
10523 while (current != ']')
10524 {
10525 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
10526 {
10527 return false;
10528 }
10529 get_ignore_noop();
10530 }
10531 }
10532
10533 return sax->end_array();
10534 }
10535
10539 bool get_ubjson_object()
10540 {
10541 std::pair<std::size_t, char_int_type> size_and_type;
10542 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10543 {
10544 return false;
10545 }
10546
10547 string_t key;
10548 if (size_and_type.first != string_t::npos)
10549 {
10550 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
10551 {
10552 return false;
10553 }
10554
10555 if (size_and_type.second != 0)
10556 {
10557 for (std::size_t i = 0; i < size_and_type.first; ++i)
10558 {
10559 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10560 {
10561 return false;
10562 }
10563 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10564 {
10565 return false;
10566 }
10567 key.clear();
10568 }
10569 }
10570 else
10571 {
10572 for (std::size_t i = 0; i < size_and_type.first; ++i)
10573 {
10574 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10575 {
10576 return false;
10577 }
10578 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10579 {
10580 return false;
10581 }
10582 key.clear();
10583 }
10584 }
10585 }
10586 else
10587 {
10588 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10589 {
10590 return false;
10591 }
10592
10593 while (current != '}')
10594 {
10595 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
10596 {
10597 return false;
10598 }
10599 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10600 {
10601 return false;
10602 }
10603 get_ignore_noop();
10604 key.clear();
10605 }
10606 }
10607
10608 return sax->end_object();
10609 }
10610
10611 // Note, no reader for UBJSON binary types is implemented because they do
10612 // not exist
10613
10614 bool get_ubjson_high_precision_number()
10615 {
10616 // get size of following number string
10617 std::size_t size{};
10618 auto res = get_ubjson_size_value(size);
10619 if (JSON_HEDLEY_UNLIKELY(!res))
10620 {
10621 return res;
10622 }
10623
10624 // get number string
10625 std::vector<char> number_vector;
10626 for (std::size_t i = 0; i < size; ++i)
10627 {
10628 get();
10629 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
10630 {
10631 return false;
10632 }
10633 number_vector.push_back(static_cast<char>(current));
10634 }
10635
10636 // parse number string
10637 using ia_type = decltype(detail::input_adapter(number_vector));
10638 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
10639 const auto result_number = number_lexer.scan();
10640 const auto number_string = number_lexer.get_token_string();
10641 const auto result_remainder = number_lexer.scan();
10642
10643 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
10644
10645 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
10646 {
10647 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()));
10648 }
10649
10650 switch (result_number)
10651 {
10652 case token_type::value_integer:
10653 return sax->number_integer(number_lexer.get_number_integer());
10654 case token_type::value_unsigned:
10655 return sax->number_unsigned(number_lexer.get_number_unsigned());
10656 case token_type::value_float:
10657 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
10658 case token_type::uninitialized:
10659 case token_type::literal_true:
10660 case token_type::literal_false:
10661 case token_type::literal_null:
10662 case token_type::value_string:
10663 case token_type::begin_array:
10664 case token_type::begin_object:
10665 case token_type::end_array:
10666 case token_type::end_object:
10667 case token_type::name_separator:
10668 case token_type::value_separator:
10669 case token_type::parse_error:
10670 case token_type::end_of_input:
10671 case token_type::literal_or_value:
10672 default:
10673 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()));
10674 }
10675 }
10676
10678 // Utility functions //
10680
10690 char_int_type get()
10691 {
10692 ++chars_read;
10693 return current = ia.get_character();
10694 }
10695
10699 char_int_type get_ignore_noop()
10700 {
10701 do
10702 {
10703 get();
10704 }
10705 while (current == 'N');
10706
10707 return current;
10708 }
10709
10710 /*
10711 @brief read a number from the input
10712
10713 @tparam NumberType the type of the number
10714 @param[in] format the current format (for diagnostics)
10715 @param[out] result number of type @a NumberType
10716
10717 @return whether conversion completed
10718
10719 @note This function needs to respect the system's endianess, because
10720 bytes in CBOR, MessagePack, and UBJSON are stored in network order
10721 (big endian) and therefore need reordering on little endian systems.
10722 */
10723 template<typename NumberType, bool InputIsLittleEndian = false>
10724 bool get_number(const input_format_t format, NumberType& result)
10725 {
10726 // step 1: read input into array with system's byte order
10727 std::array<std::uint8_t, sizeof(NumberType)> vec{};
10728 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
10729 {
10730 get();
10731 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10732 {
10733 return false;
10734 }
10735
10736 // reverse byte order prior to conversion if necessary
10737 if (is_little_endian != InputIsLittleEndian)
10738 {
10739 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10740 }
10741 else
10742 {
10743 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10744 }
10745 }
10746
10747 // step 2: convert array into number of type T and return
10748 std::memcpy(&result, vec.data(), sizeof(NumberType));
10749 return true;
10750 }
10751
10766 template<typename NumberType>
10767 bool get_string(const input_format_t format,
10768 const NumberType len,
10769 string_t& result)
10770 {
10771 bool success = true;
10772 for (NumberType i = 0; i < len; i++)
10773 {
10774 get();
10775 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10776 {
10777 success = false;
10778 break;
10779 }
10780 result.push_back(static_cast<typename string_t::value_type>(current));
10781 }
10782 return success;
10783 }
10784
10799 template<typename NumberType>
10800 bool get_binary(const input_format_t format,
10801 const NumberType len,
10802 binary_t& result)
10803 {
10804 bool success = true;
10805 for (NumberType i = 0; i < len; i++)
10806 {
10807 get();
10808 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10809 {
10810 success = false;
10811 break;
10812 }
10813 result.push_back(static_cast<std::uint8_t>(current));
10814 }
10815 return success;
10816 }
10817
10823 JSON_HEDLEY_NON_NULL(3)
10824 bool unexpect_eof(const input_format_t format, const char* context) const
10825 {
10826 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10827 {
10828 return sax->parse_error(chars_read, "<end of file>",
10829 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
10830 }
10831 return true;
10832 }
10833
10837 std::string get_token_string() const
10838 {
10839 std::array<char, 3> cr{{}};
10840 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10841 return std::string{cr.data()};
10842 }
10843
10850 std::string exception_message(const input_format_t format,
10851 const std::string& detail,
10852 const std::string& context) const
10853 {
10854 std::string error_msg = "syntax error while parsing ";
10855
10856 switch (format)
10857 {
10858 case input_format_t::cbor:
10859 error_msg += "CBOR";
10860 break;
10861
10862 case input_format_t::msgpack:
10863 error_msg += "MessagePack";
10864 break;
10865
10866 case input_format_t::ubjson:
10867 error_msg += "UBJSON";
10868 break;
10869
10870 case input_format_t::bson:
10871 error_msg += "BSON";
10872 break;
10873
10874 case input_format_t::json: // LCOV_EXCL_LINE
10875 default: // LCOV_EXCL_LINE
10876 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10877 }
10878
10879 return error_msg + " " + context + ": " + detail;
10880 }
10881
10882 private:
10884 InputAdapterType ia;
10885
10887 char_int_type current = std::char_traits<char_type>::eof();
10888
10890 std::size_t chars_read = 0;
10891
10893 const bool is_little_endian = little_endianess();
10894
10896 json_sax_t* sax = nullptr;
10897};
10898} // namespace detail
10899} // namespace nlohmann
10900
10901// #include <nlohmann/detail/input/input_adapters.hpp>
10902
10903// #include <nlohmann/detail/input/lexer.hpp>
10904
10905// #include <nlohmann/detail/input/parser.hpp>
10906
10907
10908#include <cmath> // isfinite
10909#include <cstdint> // uint8_t
10910#include <functional> // function
10911#include <string> // string
10912#include <utility> // move
10913#include <vector> // vector
10914
10915// #include <nlohmann/detail/exceptions.hpp>
10916
10917// #include <nlohmann/detail/input/input_adapters.hpp>
10918
10919// #include <nlohmann/detail/input/json_sax.hpp>
10920
10921// #include <nlohmann/detail/input/lexer.hpp>
10922
10923// #include <nlohmann/detail/macro_scope.hpp>
10924
10925// #include <nlohmann/detail/meta/is_sax.hpp>
10926
10927// #include <nlohmann/detail/value_t.hpp>
10928
10929
10930namespace nlohmann
10931{
10932namespace detail
10933{
10935// parser //
10937
10938enum class parse_event_t : std::uint8_t
10939{
10941 object_start,
10943 object_end,
10945 array_start,
10947 array_end,
10949 key,
10951 value
10952};
10953
10954template<typename BasicJsonType>
10955using parser_callback_t =
10956 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
10957
10963template<typename BasicJsonType, typename InputAdapterType>
10964class parser
10965{
10966 using number_integer_t = typename BasicJsonType::number_integer_t;
10967 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10968 using number_float_t = typename BasicJsonType::number_float_t;
10969 using string_t = typename BasicJsonType::string_t;
10970 using lexer_t = lexer<BasicJsonType, InputAdapterType>;
10971 using token_type = typename lexer_t::token_type;
10972
10973 public:
10975 explicit parser(InputAdapterType&& adapter,
10976 const parser_callback_t<BasicJsonType> cb = nullptr,
10977 const bool allow_exceptions_ = true,
10978 const bool skip_comments = false)
10979 : callback(cb)
10980 , m_lexer(std::move(adapter), skip_comments)
10981 , allow_exceptions(allow_exceptions_)
10982 {
10983 // read first token
10984 get_token();
10985 }
10986
10997 void parse(const bool strict, BasicJsonType& result)
10998 {
10999 if (callback)
11000 {
11001 json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
11002 sax_parse_internal(&sdp);
11003
11004 // in strict mode, input must be completely read
11005 if (strict && (get_token() != token_type::end_of_input))
11006 {
11007 sdp.parse_error(m_lexer.get_position(),
11008 m_lexer.get_token_string(),
11009 parse_error::create(101, m_lexer.get_position(),
11010 exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11011 }
11012
11013 // in case of an error, return discarded value
11014 if (sdp.is_errored())
11015 {
11016 result = value_t::discarded;
11017 return;
11018 }
11019
11020 // set top-level value to null if it was discarded by the callback
11021 // function
11022 if (result.is_discarded())
11023 {
11024 result = nullptr;
11025 }
11026 }
11027 else
11028 {
11029 json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
11030 sax_parse_internal(&sdp);
11031
11032 // in strict mode, input must be completely read
11033 if (strict && (get_token() != token_type::end_of_input))
11034 {
11035 sdp.parse_error(m_lexer.get_position(),
11036 m_lexer.get_token_string(),
11037 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11038 }
11039
11040 // in case of an error, return discarded value
11041 if (sdp.is_errored())
11042 {
11043 result = value_t::discarded;
11044 return;
11045 }
11046 }
11047
11048 result.assert_invariant();
11049 }
11050
11057 bool accept(const bool strict = true)
11058 {
11059 json_sax_acceptor<BasicJsonType> sax_acceptor;
11060 return sax_parse(&sax_acceptor, strict);
11061 }
11062
11063 template<typename SAX>
11064 JSON_HEDLEY_NON_NULL(2)
11065 bool sax_parse(SAX* sax, const bool strict = true)
11066 {
11067 (void)detail::is_sax_static_asserts<SAX, BasicJsonType> {};
11068 const bool result = sax_parse_internal(sax);
11069
11070 // strict mode: next byte must be EOF
11071 if (result && strict && (get_token() != token_type::end_of_input))
11072 {
11073 return sax->parse_error(m_lexer.get_position(),
11074 m_lexer.get_token_string(),
11075 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11076 }
11077
11078 return result;
11079 }
11080
11081 private:
11082 template<typename SAX>
11083 JSON_HEDLEY_NON_NULL(2)
11084 bool sax_parse_internal(SAX* sax)
11085 {
11086 // stack to remember the hierarchy of structured values we are parsing
11087 // true = array; false = object
11088 std::vector<bool> states;
11089 // value to avoid a goto (see comment where set to true)
11090 bool skip_to_state_evaluation = false;
11091
11092 while (true)
11093 {
11094 if (!skip_to_state_evaluation)
11095 {
11096 // invariant: get_token() was called before each iteration
11097 switch (last_token)
11098 {
11099 case token_type::begin_object:
11100 {
11101 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
11102 {
11103 return false;
11104 }
11105
11106 // closing } -> we are done
11107 if (get_token() == token_type::end_object)
11108 {
11109 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11110 {
11111 return false;
11112 }
11113 break;
11114 }
11115
11116 // parse key
11117 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11118 {
11119 return sax->parse_error(m_lexer.get_position(),
11120 m_lexer.get_token_string(),
11121 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11122 }
11123 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11124 {
11125 return false;
11126 }
11127
11128 // parse separator (:)
11129 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11130 {
11131 return sax->parse_error(m_lexer.get_position(),
11132 m_lexer.get_token_string(),
11133 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11134 }
11135
11136 // remember we are now inside an object
11137 states.push_back(false);
11138
11139 // parse values
11140 get_token();
11141 continue;
11142 }
11143
11144 case token_type::begin_array:
11145 {
11146 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
11147 {
11148 return false;
11149 }
11150
11151 // closing ] -> we are done
11152 if (get_token() == token_type::end_array)
11153 {
11154 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11155 {
11156 return false;
11157 }
11158 break;
11159 }
11160
11161 // remember we are now inside an array
11162 states.push_back(true);
11163
11164 // parse values (no need to call get_token)
11165 continue;
11166 }
11167
11168 case token_type::value_float:
11169 {
11170 const auto res = m_lexer.get_number_float();
11171
11172 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11173 {
11174 return sax->parse_error(m_lexer.get_position(),
11175 m_lexer.get_token_string(),
11176 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
11177 }
11178
11179 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11180 {
11181 return false;
11182 }
11183
11184 break;
11185 }
11186
11187 case token_type::literal_false:
11188 {
11189 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11190 {
11191 return false;
11192 }
11193 break;
11194 }
11195
11196 case token_type::literal_null:
11197 {
11198 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11199 {
11200 return false;
11201 }
11202 break;
11203 }
11204
11205 case token_type::literal_true:
11206 {
11207 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11208 {
11209 return false;
11210 }
11211 break;
11212 }
11213
11214 case token_type::value_integer:
11215 {
11216 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11217 {
11218 return false;
11219 }
11220 break;
11221 }
11222
11223 case token_type::value_string:
11224 {
11225 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11226 {
11227 return false;
11228 }
11229 break;
11230 }
11231
11232 case token_type::value_unsigned:
11233 {
11234 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11235 {
11236 return false;
11237 }
11238 break;
11239 }
11240
11241 case token_type::parse_error:
11242 {
11243 // using "uninitialized" to avoid "expected" message
11244 return sax->parse_error(m_lexer.get_position(),
11245 m_lexer.get_token_string(),
11246 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
11247 }
11248
11249 case token_type::uninitialized:
11250 case token_type::end_array:
11251 case token_type::end_object:
11252 case token_type::name_separator:
11253 case token_type::value_separator:
11254 case token_type::end_of_input:
11255 case token_type::literal_or_value:
11256 default: // the last token was unexpected
11257 {
11258 return sax->parse_error(m_lexer.get_position(),
11259 m_lexer.get_token_string(),
11260 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
11261 }
11262 }
11263 }
11264 else
11265 {
11266 skip_to_state_evaluation = false;
11267 }
11268
11269 // we reached this line after we successfully parsed a value
11270 if (states.empty())
11271 {
11272 // empty stack: we reached the end of the hierarchy: done
11273 return true;
11274 }
11275
11276 if (states.back()) // array
11277 {
11278 // comma -> next value
11279 if (get_token() == token_type::value_separator)
11280 {
11281 // parse a new value
11282 get_token();
11283 continue;
11284 }
11285
11286 // closing ]
11287 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11288 {
11289 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11290 {
11291 return false;
11292 }
11293
11294 // We are done with this array. Before we can parse a
11295 // new value, we need to evaluate the new state first.
11296 // By setting skip_to_state_evaluation to false, we
11297 // are effectively jumping to the beginning of this if.
11298 JSON_ASSERT(!states.empty());
11299 states.pop_back();
11300 skip_to_state_evaluation = true;
11301 continue;
11302 }
11303
11304 return sax->parse_error(m_lexer.get_position(),
11305 m_lexer.get_token_string(),
11306 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11307 }
11308
11309 // states.back() is false -> object
11310
11311 // comma -> next value
11312 if (get_token() == token_type::value_separator)
11313 {
11314 // parse key
11315 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11316 {
11317 return sax->parse_error(m_lexer.get_position(),
11318 m_lexer.get_token_string(),
11319 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11320 }
11321
11322 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11323 {
11324 return false;
11325 }
11326
11327 // parse separator (:)
11328 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11329 {
11330 return sax->parse_error(m_lexer.get_position(),
11331 m_lexer.get_token_string(),
11332 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11333 }
11334
11335 // parse values
11336 get_token();
11337 continue;
11338 }
11339
11340 // closing }
11341 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11342 {
11343 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11344 {
11345 return false;
11346 }
11347
11348 // We are done with this object. Before we can parse a
11349 // new value, we need to evaluate the new state first.
11350 // By setting skip_to_state_evaluation to false, we
11351 // are effectively jumping to the beginning of this if.
11352 JSON_ASSERT(!states.empty());
11353 states.pop_back();
11354 skip_to_state_evaluation = true;
11355 continue;
11356 }
11357
11358 return sax->parse_error(m_lexer.get_position(),
11359 m_lexer.get_token_string(),
11360 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11361 }
11362 }
11363
11365 token_type get_token()
11366 {
11367 return last_token = m_lexer.scan();
11368 }
11369
11370 std::string exception_message(const token_type expected, const std::string& context)
11371 {
11372 std::string error_msg = "syntax error ";
11373
11374 if (!context.empty())
11375 {
11376 error_msg += "while parsing " + context + " ";
11377 }
11378
11379 error_msg += "- ";
11380
11381 if (last_token == token_type::parse_error)
11382 {
11383 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
11384 m_lexer.get_token_string() + "'";
11385 }
11386 else
11387 {
11388 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
11389 }
11390
11391 if (expected != token_type::uninitialized)
11392 {
11393 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
11394 }
11395
11396 return error_msg;
11397 }
11398
11399 private:
11401 const parser_callback_t<BasicJsonType> callback = nullptr;
11403 token_type last_token = token_type::uninitialized;
11405 lexer_t m_lexer;
11407 const bool allow_exceptions = true;
11408};
11409
11410} // namespace detail
11411} // namespace nlohmann
11412
11413// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11414
11415
11416// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11417
11418
11419#include <cstddef> // ptrdiff_t
11420#include <limits> // numeric_limits
11421
11422// #include <nlohmann/detail/macro_scope.hpp>
11423
11424
11425namespace nlohmann
11426{
11427namespace detail
11428{
11429/*
11430@brief an iterator for primitive JSON types
11431
11432This class models an iterator for primitive JSON types (boolean, number,
11433string). It's only purpose is to allow the iterator/const_iterator classes
11434to "iterate" over primitive values. Internally, the iterator is modeled by
11435a `difference_type` variable. Value begin_value (`0`) models the begin,
11436end_value (`1`) models past the end.
11437*/
11438class primitive_iterator_t
11439{
11440 private:
11441 using difference_type = std::ptrdiff_t;
11442 static constexpr difference_type begin_value = 0;
11443 static constexpr difference_type end_value = begin_value + 1;
11444
11445 JSON_PRIVATE_UNLESS_TESTED:
11447 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11448
11449 public:
11450 constexpr difference_type get_value() const noexcept
11451 {
11452 return m_it;
11453 }
11454
11456 void set_begin() noexcept
11457 {
11458 m_it = begin_value;
11459 }
11460
11462 void set_end() noexcept
11463 {
11464 m_it = end_value;
11465 }
11466
11468 constexpr bool is_begin() const noexcept
11469 {
11470 return m_it == begin_value;
11471 }
11472
11474 constexpr bool is_end() const noexcept
11475 {
11476 return m_it == end_value;
11477 }
11478
11479 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11480 {
11481 return lhs.m_it == rhs.m_it;
11482 }
11483
11484 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11485 {
11486 return lhs.m_it < rhs.m_it;
11487 }
11488
11489 primitive_iterator_t operator+(difference_type n) noexcept
11490 {
11491 auto result = *this;
11492 result += n;
11493 return result;
11494 }
11495
11496 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11497 {
11498 return lhs.m_it - rhs.m_it;
11499 }
11500
11501 primitive_iterator_t& operator++() noexcept
11502 {
11503 ++m_it;
11504 return *this;
11505 }
11506
11507 primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
11508 {
11509 auto result = *this;
11510 ++m_it;
11511 return result;
11512 }
11513
11514 primitive_iterator_t& operator--() noexcept
11515 {
11516 --m_it;
11517 return *this;
11518 }
11519
11520 primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
11521 {
11522 auto result = *this;
11523 --m_it;
11524 return result;
11525 }
11526
11527 primitive_iterator_t& operator+=(difference_type n) noexcept
11528 {
11529 m_it += n;
11530 return *this;
11531 }
11532
11533 primitive_iterator_t& operator-=(difference_type n) noexcept
11534 {
11535 m_it -= n;
11536 return *this;
11537 }
11538};
11539} // namespace detail
11540} // namespace nlohmann
11541
11542
11543namespace nlohmann
11544{
11545namespace detail
11546{
11553template<typename BasicJsonType> struct internal_iterator
11554{
11556 typename BasicJsonType::object_t::iterator object_iterator {};
11558 typename BasicJsonType::array_t::iterator array_iterator {};
11560 primitive_iterator_t primitive_iterator {};
11561};
11562} // namespace detail
11563} // namespace nlohmann
11564
11565// #include <nlohmann/detail/iterators/iter_impl.hpp>
11566
11567
11568#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
11569#include <type_traits> // conditional, is_const, remove_const
11570
11571// #include <nlohmann/detail/exceptions.hpp>
11572
11573// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11574
11575// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11576
11577// #include <nlohmann/detail/macro_scope.hpp>
11578
11579// #include <nlohmann/detail/meta/cpp_future.hpp>
11580
11581// #include <nlohmann/detail/meta/type_traits.hpp>
11582
11583// #include <nlohmann/detail/value_t.hpp>
11584
11585
11586namespace nlohmann
11587{
11588namespace detail
11589{
11590// forward declare, to be able to friend it later on
11591template<typename IteratorType> class iteration_proxy;
11592template<typename IteratorType> class iteration_proxy_value;
11593
11610template<typename BasicJsonType>
11611class iter_impl
11612{
11614 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
11616 friend other_iter_impl;
11617 friend BasicJsonType;
11618 friend iteration_proxy<iter_impl>;
11619 friend iteration_proxy_value<iter_impl>;
11620
11621 using object_t = typename BasicJsonType::object_t;
11622 using array_t = typename BasicJsonType::array_t;
11623 // make sure BasicJsonType is basic_json or const basic_json
11624 static_assert(is_basic_json<typename std::remove_const<BasicJsonType>::type>::value,
11625 "iter_impl only accepts (const) basic_json");
11626
11627 public:
11628
11634 using iterator_category = std::bidirectional_iterator_tag;
11635
11637 using value_type = typename BasicJsonType::value_type;
11639 using difference_type = typename BasicJsonType::difference_type;
11641 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
11642 typename BasicJsonType::const_pointer,
11643 typename BasicJsonType::pointer>::type;
11645 using reference =
11646 typename std::conditional<std::is_const<BasicJsonType>::value,
11647 typename BasicJsonType::const_reference,
11648 typename BasicJsonType::reference>::type;
11649
11650 iter_impl() = default;
11651 ~iter_impl() = default;
11652 iter_impl(iter_impl&&) noexcept = default;
11653 iter_impl& operator=(iter_impl&&) noexcept = default;
11654
11661 explicit iter_impl(pointer object) noexcept : m_object(object)
11662 {
11663 JSON_ASSERT(m_object != nullptr);
11664
11665 switch (m_object->m_type)
11666 {
11667 case value_t::object:
11668 {
11669 m_it.object_iterator = typename object_t::iterator();
11670 break;
11671 }
11672
11673 case value_t::array:
11674 {
11675 m_it.array_iterator = typename array_t::iterator();
11676 break;
11677 }
11678
11679 case value_t::null:
11680 case value_t::string:
11681 case value_t::boolean:
11682 case value_t::number_integer:
11683 case value_t::number_unsigned:
11684 case value_t::number_float:
11685 case value_t::binary:
11686 case value_t::discarded:
11687 default:
11688 {
11689 m_it.primitive_iterator = primitive_iterator_t();
11690 break;
11691 }
11692 }
11693 }
11694
11711 iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
11712 : m_object(other.m_object), m_it(other.m_it)
11713 {}
11714
11721 iter_impl& operator=(const iter_impl<const BasicJsonType>& other) noexcept
11722 {
11723 if (&other != this)
11724 {
11725 m_object = other.m_object;
11726 m_it = other.m_it;
11727 }
11728 return *this;
11729 }
11730
11736 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
11737 : m_object(other.m_object), m_it(other.m_it)
11738 {}
11739
11746 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
11747 {
11748 m_object = other.m_object;
11749 m_it = other.m_it;
11750 return *this;
11751 }
11752
11753 JSON_PRIVATE_UNLESS_TESTED:
11758 void set_begin() noexcept
11759 {
11760 JSON_ASSERT(m_object != nullptr);
11761
11762 switch (m_object->m_type)
11763 {
11764 case value_t::object:
11765 {
11766 m_it.object_iterator = m_object->m_value.object->begin();
11767 break;
11768 }
11769
11770 case value_t::array:
11771 {
11772 m_it.array_iterator = m_object->m_value.array->begin();
11773 break;
11774 }
11775
11776 case value_t::null:
11777 {
11778 // set to end so begin()==end() is true: null is empty
11779 m_it.primitive_iterator.set_end();
11780 break;
11781 }
11782
11783 case value_t::string:
11784 case value_t::boolean:
11785 case value_t::number_integer:
11786 case value_t::number_unsigned:
11787 case value_t::number_float:
11788 case value_t::binary:
11789 case value_t::discarded:
11790 default:
11791 {
11792 m_it.primitive_iterator.set_begin();
11793 break;
11794 }
11795 }
11796 }
11797
11802 void set_end() noexcept
11803 {
11804 JSON_ASSERT(m_object != nullptr);
11805
11806 switch (m_object->m_type)
11807 {
11808 case value_t::object:
11809 {
11810 m_it.object_iterator = m_object->m_value.object->end();
11811 break;
11812 }
11813
11814 case value_t::array:
11815 {
11816 m_it.array_iterator = m_object->m_value.array->end();
11817 break;
11818 }
11819
11820 case value_t::null:
11821 case value_t::string:
11822 case value_t::boolean:
11823 case value_t::number_integer:
11824 case value_t::number_unsigned:
11825 case value_t::number_float:
11826 case value_t::binary:
11827 case value_t::discarded:
11828 default:
11829 {
11830 m_it.primitive_iterator.set_end();
11831 break;
11832 }
11833 }
11834 }
11835
11836 public:
11841 reference operator*() const
11842 {
11843 JSON_ASSERT(m_object != nullptr);
11844
11845 switch (m_object->m_type)
11846 {
11847 case value_t::object:
11848 {
11849 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11850 return m_it.object_iterator->second;
11851 }
11852
11853 case value_t::array:
11854 {
11855 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11856 return *m_it.array_iterator;
11857 }
11858
11859 case value_t::null:
11860 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11861
11862 case value_t::string:
11863 case value_t::boolean:
11864 case value_t::number_integer:
11865 case value_t::number_unsigned:
11866 case value_t::number_float:
11867 case value_t::binary:
11868 case value_t::discarded:
11869 default:
11870 {
11871 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11872 {
11873 return *m_object;
11874 }
11875
11876 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11877 }
11878 }
11879 }
11880
11885 pointer operator->() const
11886 {
11887 JSON_ASSERT(m_object != nullptr);
11888
11889 switch (m_object->m_type)
11890 {
11891 case value_t::object:
11892 {
11893 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11894 return &(m_it.object_iterator->second);
11895 }
11896
11897 case value_t::array:
11898 {
11899 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11900 return &*m_it.array_iterator;
11901 }
11902
11903 case value_t::null:
11904 case value_t::string:
11905 case value_t::boolean:
11906 case value_t::number_integer:
11907 case value_t::number_unsigned:
11908 case value_t::number_float:
11909 case value_t::binary:
11910 case value_t::discarded:
11911 default:
11912 {
11913 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11914 {
11915 return m_object;
11916 }
11917
11918 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11919 }
11920 }
11921 }
11922
11927 iter_impl const operator++(int) // NOLINT(readability-const-return-type)
11928 {
11929 auto result = *this;
11930 ++(*this);
11931 return result;
11932 }
11933
11938 iter_impl& operator++()
11939 {
11940 JSON_ASSERT(m_object != nullptr);
11941
11942 switch (m_object->m_type)
11943 {
11944 case value_t::object:
11945 {
11946 std::advance(m_it.object_iterator, 1);
11947 break;
11948 }
11949
11950 case value_t::array:
11951 {
11952 std::advance(m_it.array_iterator, 1);
11953 break;
11954 }
11955
11956 case value_t::null:
11957 case value_t::string:
11958 case value_t::boolean:
11959 case value_t::number_integer:
11960 case value_t::number_unsigned:
11961 case value_t::number_float:
11962 case value_t::binary:
11963 case value_t::discarded:
11964 default:
11965 {
11966 ++m_it.primitive_iterator;
11967 break;
11968 }
11969 }
11970
11971 return *this;
11972 }
11973
11978 iter_impl const operator--(int) // NOLINT(readability-const-return-type)
11979 {
11980 auto result = *this;
11981 --(*this);
11982 return result;
11983 }
11984
11989 iter_impl& operator--()
11990 {
11991 JSON_ASSERT(m_object != nullptr);
11992
11993 switch (m_object->m_type)
11994 {
11995 case value_t::object:
11996 {
11997 std::advance(m_it.object_iterator, -1);
11998 break;
11999 }
12000
12001 case value_t::array:
12002 {
12003 std::advance(m_it.array_iterator, -1);
12004 break;
12005 }
12006
12007 case value_t::null:
12008 case value_t::string:
12009 case value_t::boolean:
12010 case value_t::number_integer:
12011 case value_t::number_unsigned:
12012 case value_t::number_float:
12013 case value_t::binary:
12014 case value_t::discarded:
12015 default:
12016 {
12017 --m_it.primitive_iterator;
12018 break;
12019 }
12020 }
12021
12022 return *this;
12023 }
12024
12029 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 >
12030 bool operator==(const IterImpl& other) const
12031 {
12032 // if objects are not the same, the comparison is undefined
12033 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12034 {
12035 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12036 }
12037
12038 JSON_ASSERT(m_object != nullptr);
12039
12040 switch (m_object->m_type)
12041 {
12042 case value_t::object:
12043 return (m_it.object_iterator == other.m_it.object_iterator);
12044
12045 case value_t::array:
12046 return (m_it.array_iterator == other.m_it.array_iterator);
12047
12048 case value_t::null:
12049 case value_t::string:
12050 case value_t::boolean:
12051 case value_t::number_integer:
12052 case value_t::number_unsigned:
12053 case value_t::number_float:
12054 case value_t::binary:
12055 case value_t::discarded:
12056 default:
12057 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
12058 }
12059 }
12060
12065 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 >
12066 bool operator!=(const IterImpl& other) const
12067 {
12068 return !operator==(other);
12069 }
12070
12075 bool operator<(const iter_impl& other) const
12076 {
12077 // if objects are not the same, the comparison is undefined
12078 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12079 {
12080 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12081 }
12082
12083 JSON_ASSERT(m_object != nullptr);
12084
12085 switch (m_object->m_type)
12086 {
12087 case value_t::object:
12088 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
12089
12090 case value_t::array:
12091 return (m_it.array_iterator < other.m_it.array_iterator);
12092
12093 case value_t::null:
12094 case value_t::string:
12095 case value_t::boolean:
12096 case value_t::number_integer:
12097 case value_t::number_unsigned:
12098 case value_t::number_float:
12099 case value_t::binary:
12100 case value_t::discarded:
12101 default:
12102 return (m_it.primitive_iterator < other.m_it.primitive_iterator);
12103 }
12104 }
12105
12110 bool operator<=(const iter_impl& other) const
12111 {
12112 return !other.operator < (*this);
12113 }
12114
12119 bool operator>(const iter_impl& other) const
12120 {
12121 return !operator<=(other);
12122 }
12123
12128 bool operator>=(const iter_impl& other) const
12129 {
12130 return !operator<(other);
12131 }
12132
12137 iter_impl& operator+=(difference_type i)
12138 {
12139 JSON_ASSERT(m_object != nullptr);
12140
12141 switch (m_object->m_type)
12142 {
12143 case value_t::object:
12144 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12145
12146 case value_t::array:
12147 {
12148 std::advance(m_it.array_iterator, i);
12149 break;
12150 }
12151
12152 case value_t::null:
12153 case value_t::string:
12154 case value_t::boolean:
12155 case value_t::number_integer:
12156 case value_t::number_unsigned:
12157 case value_t::number_float:
12158 case value_t::binary:
12159 case value_t::discarded:
12160 default:
12161 {
12162 m_it.primitive_iterator += i;
12163 break;
12164 }
12165 }
12166
12167 return *this;
12168 }
12169
12174 iter_impl& operator-=(difference_type i)
12175 {
12176 return operator+=(-i);
12177 }
12178
12183 iter_impl operator+(difference_type i) const
12184 {
12185 auto result = *this;
12186 result += i;
12187 return result;
12188 }
12189
12194 friend iter_impl operator+(difference_type i, const iter_impl& it)
12195 {
12196 auto result = it;
12197 result += i;
12198 return result;
12199 }
12200
12205 iter_impl operator-(difference_type i) const
12206 {
12207 auto result = *this;
12208 result -= i;
12209 return result;
12210 }
12211
12216 difference_type operator-(const iter_impl& other) const
12217 {
12218 JSON_ASSERT(m_object != nullptr);
12219
12220 switch (m_object->m_type)
12221 {
12222 case value_t::object:
12223 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12224
12225 case value_t::array:
12226 return m_it.array_iterator - other.m_it.array_iterator;
12227
12228 case value_t::null:
12229 case value_t::string:
12230 case value_t::boolean:
12231 case value_t::number_integer:
12232 case value_t::number_unsigned:
12233 case value_t::number_float:
12234 case value_t::binary:
12235 case value_t::discarded:
12236 default:
12237 return m_it.primitive_iterator - other.m_it.primitive_iterator;
12238 }
12239 }
12240
12245 reference operator[](difference_type n) const
12246 {
12247 JSON_ASSERT(m_object != nullptr);
12248
12249 switch (m_object->m_type)
12250 {
12251 case value_t::object:
12252 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
12253
12254 case value_t::array:
12255 return *std::next(m_it.array_iterator, n);
12256
12257 case value_t::null:
12258 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12259
12260 case value_t::string:
12261 case value_t::boolean:
12262 case value_t::number_integer:
12263 case value_t::number_unsigned:
12264 case value_t::number_float:
12265 case value_t::binary:
12266 case value_t::discarded:
12267 default:
12268 {
12269 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
12270 {
12271 return *m_object;
12272 }
12273
12274 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12275 }
12276 }
12277 }
12278
12283 const typename object_t::key_type& key() const
12284 {
12285 JSON_ASSERT(m_object != nullptr);
12286
12287 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
12288 {
12289 return m_it.object_iterator->first;
12290 }
12291
12292 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
12293 }
12294
12299 reference value() const
12300 {
12301 return operator*();
12302 }
12303
12304 JSON_PRIVATE_UNLESS_TESTED:
12306 pointer m_object = nullptr;
12308 internal_iterator<typename std::remove_const<BasicJsonType>::type> m_it {};
12309};
12310} // namespace detail
12311} // namespace nlohmann
12312
12313// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12314
12315// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12316
12317
12318#include <cstddef> // ptrdiff_t
12319#include <iterator> // reverse_iterator
12320#include <utility> // declval
12321
12322namespace nlohmann
12323{
12324namespace detail
12325{
12327// reverse_iterator //
12329
12348template<typename Base>
12349class json_reverse_iterator : public std::reverse_iterator<Base>
12350{
12351 public:
12352 using difference_type = std::ptrdiff_t;
12354 using base_iterator = std::reverse_iterator<Base>;
12356 using reference = typename Base::reference;
12357
12359 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
12360 : base_iterator(it) {}
12361
12363 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12364
12366 json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
12367 {
12368 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12369 }
12370
12372 json_reverse_iterator& operator++()
12373 {
12374 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12375 }
12376
12378 json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
12379 {
12380 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12381 }
12382
12384 json_reverse_iterator& operator--()
12385 {
12386 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12387 }
12388
12390 json_reverse_iterator& operator+=(difference_type i)
12391 {
12392 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12393 }
12394
12396 json_reverse_iterator operator+(difference_type i) const
12397 {
12398 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12399 }
12400
12402 json_reverse_iterator operator-(difference_type i) const
12403 {
12404 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12405 }
12406
12408 difference_type operator-(const json_reverse_iterator& other) const
12409 {
12410 return base_iterator(*this) - base_iterator(other);
12411 }
12412
12414 reference operator[](difference_type n) const
12415 {
12416 return *(this->operator+(n));
12417 }
12418
12420 auto key() const -> decltype(std::declval<Base>().key())
12421 {
12422 auto it = --this->base();
12423 return it.key();
12424 }
12425
12427 reference value() const
12428 {
12429 auto it = --this->base();
12430 return it.operator * ();
12431 }
12432};
12433} // namespace detail
12434} // namespace nlohmann
12435
12436// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12437
12438// #include <nlohmann/detail/json_pointer.hpp>
12439
12440
12441#include <algorithm> // all_of
12442#include <cctype> // isdigit
12443#include <limits> // max
12444#include <numeric> // accumulate
12445#include <string> // string
12446#include <utility> // move
12447#include <vector> // vector
12448
12449// #include <nlohmann/detail/exceptions.hpp>
12450
12451// #include <nlohmann/detail/macro_scope.hpp>
12452
12453// #include <nlohmann/detail/string_escape.hpp>
12454
12455// #include <nlohmann/detail/value_t.hpp>
12456
12457
12458namespace nlohmann
12459{
12460template<typename BasicJsonType>
12462{
12463 // allow basic_json to access private members
12464 NLOHMANN_BASIC_JSON_TPL_DECLARATION
12465 friend class basic_json;
12466
12467 public:
12489 explicit json_pointer(const std::string& s = "")
12490 : reference_tokens(split(s))
12491 {}
12492
12507 std::string to_string() const
12508 {
12509 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12510 std::string{},
12511 [](const std::string & a, const std::string & b)
12512 {
12513 return a + "/" + detail::escape(b);
12514 });
12515 }
12516
12518 operator std::string() const
12519 {
12520 return to_string();
12521 }
12522
12540 {
12541 reference_tokens.insert(reference_tokens.end(),
12542 ptr.reference_tokens.begin(),
12543 ptr.reference_tokens.end());
12544 return *this;
12545 }
12546
12563 json_pointer& operator/=(std::string token)
12564 {
12565 push_back(std::move(token));
12566 return *this;
12567 }
12568
12585 json_pointer& operator/=(std::size_t array_idx)
12586 {
12587 return *this /= std::to_string(array_idx);
12588 }
12589
12606 const json_pointer& rhs)
12607 {
12608 return json_pointer(lhs) /= rhs;
12609 }
12610
12626 friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param)
12627 {
12628 return json_pointer(ptr) /= std::move(token);
12629 }
12630
12646 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
12647 {
12648 return json_pointer(ptr) /= array_idx;
12649 }
12650
12665 {
12666 if (empty())
12667 {
12668 return *this;
12669 }
12670
12671 json_pointer res = *this;
12672 res.pop_back();
12673 return res;
12674 }
12675
12690 {
12691 if (JSON_HEDLEY_UNLIKELY(empty()))
12692 {
12693 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12694 }
12695
12696 reference_tokens.pop_back();
12697 }
12698
12713 const std::string& back() const
12714 {
12715 if (JSON_HEDLEY_UNLIKELY(empty()))
12716 {
12717 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12718 }
12719
12720 return reference_tokens.back();
12721 }
12722
12735 void push_back(const std::string& token)
12736 {
12737 reference_tokens.push_back(token);
12738 }
12739
12741 void push_back(std::string&& token)
12742 {
12743 reference_tokens.push_back(std::move(token));
12744 }
12745
12760 bool empty() const noexcept
12761 {
12762 return reference_tokens.empty();
12763 }
12764
12765 private:
12776 static typename BasicJsonType::size_type array_index(const std::string& s)
12777 {
12778 using size_type = typename BasicJsonType::size_type;
12779
12780 // error condition (cf. RFC 6901, Sect. 4)
12781 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
12782 {
12783 JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
12784 }
12785
12786 // error condition (cf. RFC 6901, Sect. 4)
12787 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
12788 {
12789 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
12790 }
12791
12792 std::size_t processed_chars = 0;
12793 unsigned long long res = 0; // NOLINT(runtime/int)
12794 JSON_TRY
12795 {
12796 res = std::stoull(s, &processed_chars);
12797 }
12798 JSON_CATCH(std::out_of_range&)
12799 {
12800 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12801 }
12802
12803 // check if the string was completely read
12804 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
12805 {
12806 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12807 }
12808
12809 // only triggered on special platforms (like 32bit), see also
12810 // https://github.com/nlohmann/json/pull/2203
12811 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
12812 {
12813 JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
12814 }
12815
12816 return static_cast<size_type>(res);
12817 }
12818
12819 JSON_PRIVATE_UNLESS_TESTED:
12820 json_pointer top() const
12821 {
12822 if (JSON_HEDLEY_UNLIKELY(empty()))
12823 {
12824 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12825 }
12826
12827 json_pointer result = *this;
12828 result.reference_tokens = {reference_tokens[0]};
12829 return result;
12830 }
12831
12832 private:
12841 BasicJsonType& get_and_create(BasicJsonType& j) const
12842 {
12843 auto* result = &j;
12844
12845 // in case no reference tokens exist, return a reference to the JSON value
12846 // j which will be overwritten by a primitive value
12847 for (const auto& reference_token : reference_tokens)
12848 {
12849 switch (result->type())
12850 {
12851 case detail::value_t::null:
12852 {
12853 if (reference_token == "0")
12854 {
12855 // start a new array if reference token is 0
12856 result = &result->operator[](0);
12857 }
12858 else
12859 {
12860 // start a new object otherwise
12861 result = &result->operator[](reference_token);
12862 }
12863 break;
12864 }
12865
12866 case detail::value_t::object:
12867 {
12868 // create an entry in the object
12869 result = &result->operator[](reference_token);
12870 break;
12871 }
12872
12873 case detail::value_t::array:
12874 {
12875 // create an entry in the array
12876 result = &result->operator[](array_index(reference_token));
12877 break;
12878 }
12879
12880 /*
12881 The following code is only reached if there exists a reference
12882 token _and_ the current value is primitive. In this case, we have
12883 an error situation, because primitive values may only occur as
12884 single value; that is, with an empty list of reference tokens.
12885 */
12886 case detail::value_t::string:
12887 case detail::value_t::boolean:
12888 case detail::value_t::number_integer:
12889 case detail::value_t::number_unsigned:
12890 case detail::value_t::number_float:
12891 case detail::value_t::binary:
12892 case detail::value_t::discarded:
12893 default:
12894 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
12895 }
12896 }
12897
12898 return *result;
12899 }
12900
12920 BasicJsonType& get_unchecked(BasicJsonType* ptr) const
12921 {
12922 for (const auto& reference_token : reference_tokens)
12923 {
12924 // convert null values to arrays or objects before continuing
12925 if (ptr->is_null())
12926 {
12927 // check if reference token is a number
12928 const bool nums =
12929 std::all_of(reference_token.begin(), reference_token.end(),
12930 [](const unsigned char x)
12931 {
12932 return std::isdigit(x);
12933 });
12934
12935 // change value to array for numbers or "-" or to object otherwise
12936 *ptr = (nums || reference_token == "-")
12937 ? detail::value_t::array
12938 : detail::value_t::object;
12939 }
12940
12941 switch (ptr->type())
12942 {
12943 case detail::value_t::object:
12944 {
12945 // use unchecked object access
12946 ptr = &ptr->operator[](reference_token);
12947 break;
12948 }
12949
12950 case detail::value_t::array:
12951 {
12952 if (reference_token == "-")
12953 {
12954 // explicitly treat "-" as index beyond the end
12955 ptr = &ptr->operator[](ptr->m_value.array->size());
12956 }
12957 else
12958 {
12959 // convert array index to number; unchecked access
12960 ptr = &ptr->operator[](array_index(reference_token));
12961 }
12962 break;
12963 }
12964
12965 case detail::value_t::null:
12966 case detail::value_t::string:
12967 case detail::value_t::boolean:
12968 case detail::value_t::number_integer:
12969 case detail::value_t::number_unsigned:
12970 case detail::value_t::number_float:
12971 case detail::value_t::binary:
12972 case detail::value_t::discarded:
12973 default:
12974 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12975 }
12976 }
12977
12978 return *ptr;
12979 }
12980
12987 BasicJsonType& get_checked(BasicJsonType* ptr) const
12988 {
12989 for (const auto& reference_token : reference_tokens)
12990 {
12991 switch (ptr->type())
12992 {
12993 case detail::value_t::object:
12994 {
12995 // note: at performs range check
12996 ptr = &ptr->at(reference_token);
12997 break;
12998 }
12999
13000 case detail::value_t::array:
13001 {
13002 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13003 {
13004 // "-" always fails the range check
13005 JSON_THROW(detail::out_of_range::create(402,
13006 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13007 ") is out of range", *ptr));
13008 }
13009
13010 // note: at performs range check
13011 ptr = &ptr->at(array_index(reference_token));
13012 break;
13013 }
13014
13015 case detail::value_t::null:
13016 case detail::value_t::string:
13017 case detail::value_t::boolean:
13018 case detail::value_t::number_integer:
13019 case detail::value_t::number_unsigned:
13020 case detail::value_t::number_float:
13021 case detail::value_t::binary:
13022 case detail::value_t::discarded:
13023 default:
13024 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13025 }
13026 }
13027
13028 return *ptr;
13029 }
13030
13044 const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
13045 {
13046 for (const auto& reference_token : reference_tokens)
13047 {
13048 switch (ptr->type())
13049 {
13050 case detail::value_t::object:
13051 {
13052 // use unchecked object access
13053 ptr = &ptr->operator[](reference_token);
13054 break;
13055 }
13056
13057 case detail::value_t::array:
13058 {
13059 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13060 {
13061 // "-" cannot be used for const access
13062 JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
13063 }
13064
13065 // use unchecked array access
13066 ptr = &ptr->operator[](array_index(reference_token));
13067 break;
13068 }
13069
13070 case detail::value_t::null:
13071 case detail::value_t::string:
13072 case detail::value_t::boolean:
13073 case detail::value_t::number_integer:
13074 case detail::value_t::number_unsigned:
13075 case detail::value_t::number_float:
13076 case detail::value_t::binary:
13077 case detail::value_t::discarded:
13078 default:
13079 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13080 }
13081 }
13082
13083 return *ptr;
13084 }
13085
13092 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
13093 {
13094 for (const auto& reference_token : reference_tokens)
13095 {
13096 switch (ptr->type())
13097 {
13098 case detail::value_t::object:
13099 {
13100 // note: at performs range check
13101 ptr = &ptr->at(reference_token);
13102 break;
13103 }
13104
13105 case detail::value_t::array:
13106 {
13107 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13108 {
13109 // "-" always fails the range check
13110 JSON_THROW(detail::out_of_range::create(402,
13111 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13112 ") is out of range", *ptr));
13113 }
13114
13115 // note: at performs range check
13116 ptr = &ptr->at(array_index(reference_token));
13117 break;
13118 }
13119
13120 case detail::value_t::null:
13121 case detail::value_t::string:
13122 case detail::value_t::boolean:
13123 case detail::value_t::number_integer:
13124 case detail::value_t::number_unsigned:
13125 case detail::value_t::number_float:
13126 case detail::value_t::binary:
13127 case detail::value_t::discarded:
13128 default:
13129 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13130 }
13131 }
13132
13133 return *ptr;
13134 }
13135
13140 bool contains(const BasicJsonType* ptr) const
13141 {
13142 for (const auto& reference_token : reference_tokens)
13143 {
13144 switch (ptr->type())
13145 {
13146 case detail::value_t::object:
13147 {
13148 if (!ptr->contains(reference_token))
13149 {
13150 // we did not find the key in the object
13151 return false;
13152 }
13153
13154 ptr = &ptr->operator[](reference_token);
13155 break;
13156 }
13157
13158 case detail::value_t::array:
13159 {
13160 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13161 {
13162 // "-" always fails the range check
13163 return false;
13164 }
13165 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13166 {
13167 // invalid char
13168 return false;
13169 }
13170 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
13171 {
13172 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13173 {
13174 // first char should be between '1' and '9'
13175 return false;
13176 }
13177 for (std::size_t i = 1; i < reference_token.size(); i++)
13178 {
13179 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13180 {
13181 // other char should be between '0' and '9'
13182 return false;
13183 }
13184 }
13185 }
13186
13187 const auto idx = array_index(reference_token);
13188 if (idx >= ptr->size())
13189 {
13190 // index out of range
13191 return false;
13192 }
13193
13194 ptr = &ptr->operator[](idx);
13195 break;
13196 }
13197
13198 case detail::value_t::null:
13199 case detail::value_t::string:
13200 case detail::value_t::boolean:
13201 case detail::value_t::number_integer:
13202 case detail::value_t::number_unsigned:
13203 case detail::value_t::number_float:
13204 case detail::value_t::binary:
13205 case detail::value_t::discarded:
13206 default:
13207 {
13208 // we do not expect primitive values if there is still a
13209 // reference token to process
13210 return false;
13211 }
13212 }
13213 }
13214
13215 // no reference token left means we found a primitive value
13216 return true;
13217 }
13218
13228 static std::vector<std::string> split(const std::string& reference_string)
13229 {
13230 std::vector<std::string> result;
13231
13232 // special case: empty reference string -> no reference tokens
13233 if (reference_string.empty())
13234 {
13235 return result;
13236 }
13237
13238 // check if nonempty reference string begins with slash
13239 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
13240 {
13241 JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
13242 }
13243
13244 // extract the reference tokens:
13245 // - slash: position of the last read slash (or end of string)
13246 // - start: position after the previous slash
13247 for (
13248 // search for the first slash after the first character
13249 std::size_t slash = reference_string.find_first_of('/', 1),
13250 // set the beginning of the first reference token
13251 start = 1;
13252 // we can stop if start == 0 (if slash == std::string::npos)
13253 start != 0;
13254 // set the beginning of the next reference token
13255 // (will eventually be 0 if slash == std::string::npos)
13256 start = (slash == std::string::npos) ? 0 : slash + 1,
13257 // find next slash
13258 slash = reference_string.find_first_of('/', start))
13259 {
13260 // use the text between the beginning of the reference token
13261 // (start) and the last slash (slash).
13262 auto reference_token = reference_string.substr(start, slash - start);
13263
13264 // check reference tokens are properly escaped
13265 for (std::size_t pos = reference_token.find_first_of('~');
13266 pos != std::string::npos;
13267 pos = reference_token.find_first_of('~', pos + 1))
13268 {
13269 JSON_ASSERT(reference_token[pos] == '~');
13270
13271 // ~ must be followed by 0 or 1
13272 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
13273 (reference_token[pos + 1] != '0' &&
13274 reference_token[pos + 1] != '1')))
13275 {
13276 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
13277 }
13278 }
13279
13280 // finally, store the reference token
13281 detail::unescape(reference_token);
13282 result.push_back(reference_token);
13283 }
13284
13285 return result;
13286 }
13287
13288 private:
13296 static void flatten(const std::string& reference_string,
13297 const BasicJsonType& value,
13298 BasicJsonType& result)
13299 {
13300 switch (value.type())
13301 {
13302 case detail::value_t::array:
13303 {
13304 if (value.m_value.array->empty())
13305 {
13306 // flatten empty array as null
13307 result[reference_string] = nullptr;
13308 }
13309 else
13310 {
13311 // iterate array and use index as reference string
13312 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13313 {
13314 flatten(reference_string + "/" + std::to_string(i),
13315 value.m_value.array->operator[](i), result);
13316 }
13317 }
13318 break;
13319 }
13320
13321 case detail::value_t::object:
13322 {
13323 if (value.m_value.object->empty())
13324 {
13325 // flatten empty object as null
13326 result[reference_string] = nullptr;
13327 }
13328 else
13329 {
13330 // iterate object and use keys as reference string
13331 for (const auto& element : *value.m_value.object)
13332 {
13333 flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
13334 }
13335 }
13336 break;
13337 }
13338
13339 case detail::value_t::null:
13340 case detail::value_t::string:
13341 case detail::value_t::boolean:
13342 case detail::value_t::number_integer:
13343 case detail::value_t::number_unsigned:
13344 case detail::value_t::number_float:
13345 case detail::value_t::binary:
13346 case detail::value_t::discarded:
13347 default:
13348 {
13349 // add primitive value with its reference string
13350 result[reference_string] = value;
13351 break;
13352 }
13353 }
13354 }
13355
13366 static BasicJsonType
13367 unflatten(const BasicJsonType& value)
13368 {
13369 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
13370 {
13371 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
13372 }
13373
13374 BasicJsonType result;
13375
13376 // iterate the JSON object values
13377 for (const auto& element : *value.m_value.object)
13378 {
13379 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
13380 {
13381 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
13382 }
13383
13384 // assign value to reference pointed to by JSON pointer; Note that if
13385 // the JSON pointer is "" (i.e., points to the whole value), function
13386 // get_and_create returns a reference to result itself. An assignment
13387 // will then create a primitive value.
13388 json_pointer(element.first).get_and_create(result) = element.second;
13389 }
13390
13391 return result;
13392 }
13393
13405 friend bool operator==(json_pointer const& lhs,
13406 json_pointer const& rhs) noexcept
13407 {
13408 return lhs.reference_tokens == rhs.reference_tokens;
13409 }
13410
13422 friend bool operator!=(json_pointer const& lhs,
13423 json_pointer const& rhs) noexcept
13424 {
13425 return !(lhs == rhs);
13426 }
13427
13429 std::vector<std::string> reference_tokens;
13430};
13431} // namespace nlohmann
13432
13433// #include <nlohmann/detail/json_ref.hpp>
13434
13435
13436#include <initializer_list>
13437#include <utility>
13438
13439// #include <nlohmann/detail/meta/type_traits.hpp>
13440
13441
13442namespace nlohmann
13443{
13444namespace detail
13445{
13446template<typename BasicJsonType>
13447class json_ref
13448{
13449 public:
13450 using value_type = BasicJsonType;
13451
13452 json_ref(value_type&& value)
13453 : owned_value(std::move(value))
13454 {}
13455
13456 json_ref(const value_type& value)
13457 : value_ref(&value)
13458 {}
13459
13460 json_ref(std::initializer_list<json_ref> init)
13461 : owned_value(init)
13462 {}
13463
13464 template <
13465 class... Args,
13466 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13467 json_ref(Args && ... args)
13468 : owned_value(std::forward<Args>(args)...)
13469 {}
13470
13471 // class should be movable only
13472 json_ref(json_ref&&) noexcept = default;
13473 json_ref(const json_ref&) = delete;
13474 json_ref& operator=(const json_ref&) = delete;
13475 json_ref& operator=(json_ref&&) = delete;
13476 ~json_ref() = default;
13477
13478 value_type moved_or_copied() const
13479 {
13480 if (value_ref == nullptr)
13481 {
13482 return std::move(owned_value);
13483 }
13484 return *value_ref;
13485 }
13486
13487 value_type const& operator*() const
13488 {
13489 return value_ref ? *value_ref : owned_value;
13490 }
13491
13492 value_type const* operator->() const
13493 {
13494 return &** this;
13495 }
13496
13497 private:
13498 mutable value_type owned_value = nullptr;
13499 value_type const* value_ref = nullptr;
13500};
13501} // namespace detail
13502} // namespace nlohmann
13503
13504// #include <nlohmann/detail/macro_scope.hpp>
13505
13506// #include <nlohmann/detail/string_escape.hpp>
13507
13508// #include <nlohmann/detail/meta/cpp_future.hpp>
13509
13510// #include <nlohmann/detail/meta/type_traits.hpp>
13511
13512// #include <nlohmann/detail/output/binary_writer.hpp>
13513
13514
13515#include <algorithm> // reverse
13516#include <array> // array
13517#include <cmath> // isnan, isinf
13518#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13519#include <cstring> // memcpy
13520#include <limits> // numeric_limits
13521#include <string> // string
13522#include <utility> // move
13523
13524// #include <nlohmann/detail/input/binary_reader.hpp>
13525
13526// #include <nlohmann/detail/macro_scope.hpp>
13527
13528// #include <nlohmann/detail/output/output_adapters.hpp>
13529
13530
13531#include <algorithm> // copy
13532#include <cstddef> // size_t
13533#include <iterator> // back_inserter
13534#include <memory> // shared_ptr, make_shared
13535#include <string> // basic_string
13536#include <vector> // vector
13537
13538#ifndef JSON_NO_IO
13539 #include <ios> // streamsize
13540 #include <ostream> // basic_ostream
13541#endif // JSON_NO_IO
13542
13543// #include <nlohmann/detail/macro_scope.hpp>
13544
13545
13546namespace nlohmann
13547{
13548namespace detail
13549{
13551template<typename CharType> struct output_adapter_protocol
13552{
13553 virtual void write_character(CharType c) = 0;
13554 virtual void write_characters(const CharType* s, std::size_t length) = 0;
13555 virtual ~output_adapter_protocol() = default;
13556
13557 output_adapter_protocol() = default;
13558 output_adapter_protocol(const output_adapter_protocol&) = default;
13559 output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
13560 output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
13561 output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
13562};
13563
13565template<typename CharType>
13566using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13567
13569template<typename CharType, typename AllocatorType = std::allocator<CharType>>
13570class output_vector_adapter : public output_adapter_protocol<CharType>
13571{
13572 public:
13573 explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
13574 : v(vec)
13575 {}
13576
13577 void write_character(CharType c) override
13578 {
13579 v.push_back(c);
13580 }
13581
13582 JSON_HEDLEY_NON_NULL(2)
13583 void write_characters(const CharType* s, std::size_t length) override
13584 {
13585 std::copy(s, s + length, std::back_inserter(v));
13586 }
13587
13588 private:
13589 std::vector<CharType, AllocatorType>& v;
13590};
13591
13592#ifndef JSON_NO_IO
13594template<typename CharType>
13595class output_stream_adapter : public output_adapter_protocol<CharType>
13596{
13597 public:
13598 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13599 : stream(s)
13600 {}
13601
13602 void write_character(CharType c) override
13603 {
13604 stream.put(c);
13605 }
13606
13607 JSON_HEDLEY_NON_NULL(2)
13608 void write_characters(const CharType* s, std::size_t length) override
13609 {
13610 stream.write(s, static_cast<std::streamsize>(length));
13611 }
13612
13613 private:
13614 std::basic_ostream<CharType>& stream;
13615};
13616#endif // JSON_NO_IO
13617
13619template<typename CharType, typename StringType = std::basic_string<CharType>>
13620class output_string_adapter : public output_adapter_protocol<CharType>
13621{
13622 public:
13623 explicit output_string_adapter(StringType& s) noexcept
13624 : str(s)
13625 {}
13626
13627 void write_character(CharType c) override
13628 {
13629 str.push_back(c);
13630 }
13631
13632 JSON_HEDLEY_NON_NULL(2)
13633 void write_characters(const CharType* s, std::size_t length) override
13634 {
13635 str.append(s, length);
13636 }
13637
13638 private:
13639 StringType& str;
13640};
13641
13642template<typename CharType, typename StringType = std::basic_string<CharType>>
13643class output_adapter
13644{
13645 public:
13646 template<typename AllocatorType = std::allocator<CharType>>
13647 output_adapter(std::vector<CharType, AllocatorType>& vec)
13648 : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
13649
13650#ifndef JSON_NO_IO
13651 output_adapter(std::basic_ostream<CharType>& s)
13652 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
13653#endif // JSON_NO_IO
13654
13655 output_adapter(StringType& s)
13656 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
13657
13658 operator output_adapter_t<CharType>()
13659 {
13660 return oa;
13661 }
13662
13663 private:
13664 output_adapter_t<CharType> oa = nullptr;
13665};
13666} // namespace detail
13667} // namespace nlohmann
13668
13669
13670namespace nlohmann
13671{
13672namespace detail
13673{
13675// binary writer //
13677
13681template<typename BasicJsonType, typename CharType>
13682class binary_writer
13683{
13684 using string_t = typename BasicJsonType::string_t;
13685 using binary_t = typename BasicJsonType::binary_t;
13686 using number_float_t = typename BasicJsonType::number_float_t;
13687
13688 public:
13694 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
13695 {
13696 JSON_ASSERT(oa);
13697 }
13698
13703 void write_bson(const BasicJsonType& j)
13704 {
13705 switch (j.type())
13706 {
13707 case value_t::object:
13708 {
13709 write_bson_object(*j.m_value.object);
13710 break;
13711 }
13712
13713 case value_t::null:
13714 case value_t::array:
13715 case value_t::string:
13716 case value_t::boolean:
13717 case value_t::number_integer:
13718 case value_t::number_unsigned:
13719 case value_t::number_float:
13720 case value_t::binary:
13721 case value_t::discarded:
13722 default:
13723 {
13724 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));
13725 }
13726 }
13727 }
13728
13732 void write_cbor(const BasicJsonType& j)
13733 {
13734 switch (j.type())
13735 {
13736 case value_t::null:
13737 {
13738 oa->write_character(to_char_type(0xF6));
13739 break;
13740 }
13741
13742 case value_t::boolean:
13743 {
13744 oa->write_character(j.m_value.boolean
13745 ? to_char_type(0xF5)
13746 : to_char_type(0xF4));
13747 break;
13748 }
13749
13750 case value_t::number_integer:
13751 {
13752 if (j.m_value.number_integer >= 0)
13753 {
13754 // CBOR does not differentiate between positive signed
13755 // integers and unsigned integers. Therefore, we used the
13756 // code from the value_t::number_unsigned case here.
13757 if (j.m_value.number_integer <= 0x17)
13758 {
13759 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13760 }
13761 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13762 {
13763 oa->write_character(to_char_type(0x18));
13764 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13765 }
13766 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
13767 {
13768 oa->write_character(to_char_type(0x19));
13769 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13770 }
13771 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
13772 {
13773 oa->write_character(to_char_type(0x1A));
13774 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13775 }
13776 else
13777 {
13778 oa->write_character(to_char_type(0x1B));
13779 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13780 }
13781 }
13782 else
13783 {
13784 // The conversions below encode the sign in the first
13785 // byte, and the value is converted to a positive number.
13786 const auto positive_number = -1 - j.m_value.number_integer;
13787 if (j.m_value.number_integer >= -24)
13788 {
13789 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
13790 }
13791 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
13792 {
13793 oa->write_character(to_char_type(0x38));
13794 write_number(static_cast<std::uint8_t>(positive_number));
13795 }
13796 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
13797 {
13798 oa->write_character(to_char_type(0x39));
13799 write_number(static_cast<std::uint16_t>(positive_number));
13800 }
13801 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
13802 {
13803 oa->write_character(to_char_type(0x3A));
13804 write_number(static_cast<std::uint32_t>(positive_number));
13805 }
13806 else
13807 {
13808 oa->write_character(to_char_type(0x3B));
13809 write_number(static_cast<std::uint64_t>(positive_number));
13810 }
13811 }
13812 break;
13813 }
13814
13815 case value_t::number_unsigned:
13816 {
13817 if (j.m_value.number_unsigned <= 0x17)
13818 {
13819 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13820 }
13821 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13822 {
13823 oa->write_character(to_char_type(0x18));
13824 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13825 }
13826 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13827 {
13828 oa->write_character(to_char_type(0x19));
13829 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
13830 }
13831 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13832 {
13833 oa->write_character(to_char_type(0x1A));
13834 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
13835 }
13836 else
13837 {
13838 oa->write_character(to_char_type(0x1B));
13839 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
13840 }
13841 break;
13842 }
13843
13844 case value_t::number_float:
13845 {
13846 if (std::isnan(j.m_value.number_float))
13847 {
13848 // NaN is 0xf97e00 in CBOR
13849 oa->write_character(to_char_type(0xF9));
13850 oa->write_character(to_char_type(0x7E));
13851 oa->write_character(to_char_type(0x00));
13852 }
13853 else if (std::isinf(j.m_value.number_float))
13854 {
13855 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
13856 oa->write_character(to_char_type(0xf9));
13857 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
13858 oa->write_character(to_char_type(0x00));
13859 }
13860 else
13861 {
13862 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
13863 }
13864 break;
13865 }
13866
13867 case value_t::string:
13868 {
13869 // step 1: write control byte and the string length
13870 const auto N = j.m_value.string->size();
13871 if (N <= 0x17)
13872 {
13873 write_number(static_cast<std::uint8_t>(0x60 + N));
13874 }
13875 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13876 {
13877 oa->write_character(to_char_type(0x78));
13878 write_number(static_cast<std::uint8_t>(N));
13879 }
13880 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13881 {
13882 oa->write_character(to_char_type(0x79));
13883 write_number(static_cast<std::uint16_t>(N));
13884 }
13885 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13886 {
13887 oa->write_character(to_char_type(0x7A));
13888 write_number(static_cast<std::uint32_t>(N));
13889 }
13890 // LCOV_EXCL_START
13891 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13892 {
13893 oa->write_character(to_char_type(0x7B));
13894 write_number(static_cast<std::uint64_t>(N));
13895 }
13896 // LCOV_EXCL_STOP
13897
13898 // step 2: write the string
13899 oa->write_characters(
13900 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13901 j.m_value.string->size());
13902 break;
13903 }
13904
13905 case value_t::array:
13906 {
13907 // step 1: write control byte and the array size
13908 const auto N = j.m_value.array->size();
13909 if (N <= 0x17)
13910 {
13911 write_number(static_cast<std::uint8_t>(0x80 + N));
13912 }
13913 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13914 {
13915 oa->write_character(to_char_type(0x98));
13916 write_number(static_cast<std::uint8_t>(N));
13917 }
13918 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13919 {
13920 oa->write_character(to_char_type(0x99));
13921 write_number(static_cast<std::uint16_t>(N));
13922 }
13923 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13924 {
13925 oa->write_character(to_char_type(0x9A));
13926 write_number(static_cast<std::uint32_t>(N));
13927 }
13928 // LCOV_EXCL_START
13929 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13930 {
13931 oa->write_character(to_char_type(0x9B));
13932 write_number(static_cast<std::uint64_t>(N));
13933 }
13934 // LCOV_EXCL_STOP
13935
13936 // step 2: write each element
13937 for (const auto& el : *j.m_value.array)
13938 {
13939 write_cbor(el);
13940 }
13941 break;
13942 }
13943
13944 case value_t::binary:
13945 {
13946 if (j.m_value.binary->has_subtype())
13947 {
13948 if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
13949 {
13950 write_number(static_cast<std::uint8_t>(0xd8));
13951 write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
13952 }
13953 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
13954 {
13955 write_number(static_cast<std::uint8_t>(0xd9));
13956 write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
13957 }
13958 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
13959 {
13960 write_number(static_cast<std::uint8_t>(0xda));
13961 write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
13962 }
13963 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
13964 {
13965 write_number(static_cast<std::uint8_t>(0xdb));
13966 write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
13967 }
13968 }
13969
13970 // step 1: write control byte and the binary array size
13971 const auto N = j.m_value.binary->size();
13972 if (N <= 0x17)
13973 {
13974 write_number(static_cast<std::uint8_t>(0x40 + N));
13975 }
13976 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13977 {
13978 oa->write_character(to_char_type(0x58));
13979 write_number(static_cast<std::uint8_t>(N));
13980 }
13981 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13982 {
13983 oa->write_character(to_char_type(0x59));
13984 write_number(static_cast<std::uint16_t>(N));
13985 }
13986 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13987 {
13988 oa->write_character(to_char_type(0x5A));
13989 write_number(static_cast<std::uint32_t>(N));
13990 }
13991 // LCOV_EXCL_START
13992 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13993 {
13994 oa->write_character(to_char_type(0x5B));
13995 write_number(static_cast<std::uint64_t>(N));
13996 }
13997 // LCOV_EXCL_STOP
13998
13999 // step 2: write each element
14000 oa->write_characters(
14001 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14002 N);
14003
14004 break;
14005 }
14006
14007 case value_t::object:
14008 {
14009 // step 1: write control byte and the object size
14010 const auto N = j.m_value.object->size();
14011 if (N <= 0x17)
14012 {
14013 write_number(static_cast<std::uint8_t>(0xA0 + N));
14014 }
14015 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14016 {
14017 oa->write_character(to_char_type(0xB8));
14018 write_number(static_cast<std::uint8_t>(N));
14019 }
14020 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14021 {
14022 oa->write_character(to_char_type(0xB9));
14023 write_number(static_cast<std::uint16_t>(N));
14024 }
14025 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14026 {
14027 oa->write_character(to_char_type(0xBA));
14028 write_number(static_cast<std::uint32_t>(N));
14029 }
14030 // LCOV_EXCL_START
14031 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14032 {
14033 oa->write_character(to_char_type(0xBB));
14034 write_number(static_cast<std::uint64_t>(N));
14035 }
14036 // LCOV_EXCL_STOP
14037
14038 // step 2: write each element
14039 for (const auto& el : *j.m_value.object)
14040 {
14041 write_cbor(el.first);
14042 write_cbor(el.second);
14043 }
14044 break;
14045 }
14046
14047 case value_t::discarded:
14048 default:
14049 break;
14050 }
14051 }
14052
14056 void write_msgpack(const BasicJsonType& j)
14057 {
14058 switch (j.type())
14059 {
14060 case value_t::null: // nil
14061 {
14062 oa->write_character(to_char_type(0xC0));
14063 break;
14064 }
14065
14066 case value_t::boolean: // true and false
14067 {
14068 oa->write_character(j.m_value.boolean
14069 ? to_char_type(0xC3)
14070 : to_char_type(0xC2));
14071 break;
14072 }
14073
14074 case value_t::number_integer:
14075 {
14076 if (j.m_value.number_integer >= 0)
14077 {
14078 // MessagePack does not differentiate between positive
14079 // signed integers and unsigned integers. Therefore, we used
14080 // the code from the value_t::number_unsigned case here.
14081 if (j.m_value.number_unsigned < 128)
14082 {
14083 // positive fixnum
14084 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14085 }
14086 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14087 {
14088 // uint 8
14089 oa->write_character(to_char_type(0xCC));
14090 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14091 }
14092 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14093 {
14094 // uint 16
14095 oa->write_character(to_char_type(0xCD));
14096 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14097 }
14098 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14099 {
14100 // uint 32
14101 oa->write_character(to_char_type(0xCE));
14102 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14103 }
14104 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14105 {
14106 // uint 64
14107 oa->write_character(to_char_type(0xCF));
14108 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14109 }
14110 }
14111 else
14112 {
14113 if (j.m_value.number_integer >= -32)
14114 {
14115 // negative fixnum
14116 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14117 }
14118 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14119 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14120 {
14121 // int 8
14122 oa->write_character(to_char_type(0xD0));
14123 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14124 }
14125 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14126 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14127 {
14128 // int 16
14129 oa->write_character(to_char_type(0xD1));
14130 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
14131 }
14132 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14133 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14134 {
14135 // int 32
14136 oa->write_character(to_char_type(0xD2));
14137 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
14138 }
14139 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14140 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14141 {
14142 // int 64
14143 oa->write_character(to_char_type(0xD3));
14144 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
14145 }
14146 }
14147 break;
14148 }
14149
14150 case value_t::number_unsigned:
14151 {
14152 if (j.m_value.number_unsigned < 128)
14153 {
14154 // positive fixnum
14155 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14156 }
14157 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14158 {
14159 // uint 8
14160 oa->write_character(to_char_type(0xCC));
14161 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14162 }
14163 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14164 {
14165 // uint 16
14166 oa->write_character(to_char_type(0xCD));
14167 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14168 }
14169 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14170 {
14171 // uint 32
14172 oa->write_character(to_char_type(0xCE));
14173 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14174 }
14175 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14176 {
14177 // uint 64
14178 oa->write_character(to_char_type(0xCF));
14179 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14180 }
14181 break;
14182 }
14183
14184 case value_t::number_float:
14185 {
14186 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
14187 break;
14188 }
14189
14190 case value_t::string:
14191 {
14192 // step 1: write control byte and the string length
14193 const auto N = j.m_value.string->size();
14194 if (N <= 31)
14195 {
14196 // fixstr
14197 write_number(static_cast<std::uint8_t>(0xA0 | N));
14198 }
14199 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14200 {
14201 // str 8
14202 oa->write_character(to_char_type(0xD9));
14203 write_number(static_cast<std::uint8_t>(N));
14204 }
14205 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14206 {
14207 // str 16
14208 oa->write_character(to_char_type(0xDA));
14209 write_number(static_cast<std::uint16_t>(N));
14210 }
14211 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14212 {
14213 // str 32
14214 oa->write_character(to_char_type(0xDB));
14215 write_number(static_cast<std::uint32_t>(N));
14216 }
14217
14218 // step 2: write the string
14219 oa->write_characters(
14220 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14221 j.m_value.string->size());
14222 break;
14223 }
14224
14225 case value_t::array:
14226 {
14227 // step 1: write control byte and the array size
14228 const auto N = j.m_value.array->size();
14229 if (N <= 15)
14230 {
14231 // fixarray
14232 write_number(static_cast<std::uint8_t>(0x90 | N));
14233 }
14234 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14235 {
14236 // array 16
14237 oa->write_character(to_char_type(0xDC));
14238 write_number(static_cast<std::uint16_t>(N));
14239 }
14240 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14241 {
14242 // array 32
14243 oa->write_character(to_char_type(0xDD));
14244 write_number(static_cast<std::uint32_t>(N));
14245 }
14246
14247 // step 2: write each element
14248 for (const auto& el : *j.m_value.array)
14249 {
14250 write_msgpack(el);
14251 }
14252 break;
14253 }
14254
14255 case value_t::binary:
14256 {
14257 // step 0: determine if the binary type has a set subtype to
14258 // determine whether or not to use the ext or fixext types
14259 const bool use_ext = j.m_value.binary->has_subtype();
14260
14261 // step 1: write control byte and the byte string length
14262 const auto N = j.m_value.binary->size();
14263 if (N <= (std::numeric_limits<std::uint8_t>::max)())
14264 {
14265 std::uint8_t output_type{};
14266 bool fixed = true;
14267 if (use_ext)
14268 {
14269 switch (N)
14270 {
14271 case 1:
14272 output_type = 0xD4; // fixext 1
14273 break;
14274 case 2:
14275 output_type = 0xD5; // fixext 2
14276 break;
14277 case 4:
14278 output_type = 0xD6; // fixext 4
14279 break;
14280 case 8:
14281 output_type = 0xD7; // fixext 8
14282 break;
14283 case 16:
14284 output_type = 0xD8; // fixext 16
14285 break;
14286 default:
14287 output_type = 0xC7; // ext 8
14288 fixed = false;
14289 break;
14290 }
14291
14292 }
14293 else
14294 {
14295 output_type = 0xC4; // bin 8
14296 fixed = false;
14297 }
14298
14299 oa->write_character(to_char_type(output_type));
14300 if (!fixed)
14301 {
14302 write_number(static_cast<std::uint8_t>(N));
14303 }
14304 }
14305 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14306 {
14307 std::uint8_t output_type = use_ext
14308 ? 0xC8 // ext 16
14309 : 0xC5; // bin 16
14310
14311 oa->write_character(to_char_type(output_type));
14312 write_number(static_cast<std::uint16_t>(N));
14313 }
14314 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14315 {
14316 std::uint8_t output_type = use_ext
14317 ? 0xC9 // ext 32
14318 : 0xC6; // bin 32
14319
14320 oa->write_character(to_char_type(output_type));
14321 write_number(static_cast<std::uint32_t>(N));
14322 }
14323
14324 // step 1.5: if this is an ext type, write the subtype
14325 if (use_ext)
14326 {
14327 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14328 }
14329
14330 // step 2: write the byte string
14331 oa->write_characters(
14332 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14333 N);
14334
14335 break;
14336 }
14337
14338 case value_t::object:
14339 {
14340 // step 1: write control byte and the object size
14341 const auto N = j.m_value.object->size();
14342 if (N <= 15)
14343 {
14344 // fixmap
14345 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
14346 }
14347 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14348 {
14349 // map 16
14350 oa->write_character(to_char_type(0xDE));
14351 write_number(static_cast<std::uint16_t>(N));
14352 }
14353 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14354 {
14355 // map 32
14356 oa->write_character(to_char_type(0xDF));
14357 write_number(static_cast<std::uint32_t>(N));
14358 }
14359
14360 // step 2: write each element
14361 for (const auto& el : *j.m_value.object)
14362 {
14363 write_msgpack(el.first);
14364 write_msgpack(el.second);
14365 }
14366 break;
14367 }
14368
14369 case value_t::discarded:
14370 default:
14371 break;
14372 }
14373 }
14374
14381 void write_ubjson(const BasicJsonType& j, const bool use_count,
14382 const bool use_type, const bool add_prefix = true)
14383 {
14384 switch (j.type())
14385 {
14386 case value_t::null:
14387 {
14388 if (add_prefix)
14389 {
14390 oa->write_character(to_char_type('Z'));
14391 }
14392 break;
14393 }
14394
14395 case value_t::boolean:
14396 {
14397 if (add_prefix)
14398 {
14399 oa->write_character(j.m_value.boolean
14400 ? to_char_type('T')
14401 : to_char_type('F'));
14402 }
14403 break;
14404 }
14405
14406 case value_t::number_integer:
14407 {
14408 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
14409 break;
14410 }
14411
14412 case value_t::number_unsigned:
14413 {
14414 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
14415 break;
14416 }
14417
14418 case value_t::number_float:
14419 {
14420 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
14421 break;
14422 }
14423
14424 case value_t::string:
14425 {
14426 if (add_prefix)
14427 {
14428 oa->write_character(to_char_type('S'));
14429 }
14430 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
14431 oa->write_characters(
14432 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14433 j.m_value.string->size());
14434 break;
14435 }
14436
14437 case value_t::array:
14438 {
14439 if (add_prefix)
14440 {
14441 oa->write_character(to_char_type('['));
14442 }
14443
14444 bool prefix_required = true;
14445 if (use_type && !j.m_value.array->empty())
14446 {
14447 JSON_ASSERT(use_count);
14448 const CharType first_prefix = ubjson_prefix(j.front());
14449 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14450 [this, first_prefix](const BasicJsonType & v)
14451 {
14452 return ubjson_prefix(v) == first_prefix;
14453 });
14454
14455 if (same_prefix)
14456 {
14457 prefix_required = false;
14458 oa->write_character(to_char_type('$'));
14459 oa->write_character(first_prefix);
14460 }
14461 }
14462
14463 if (use_count)
14464 {
14465 oa->write_character(to_char_type('#'));
14466 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
14467 }
14468
14469 for (const auto& el : *j.m_value.array)
14470 {
14471 write_ubjson(el, use_count, use_type, prefix_required);
14472 }
14473
14474 if (!use_count)
14475 {
14476 oa->write_character(to_char_type(']'));
14477 }
14478
14479 break;
14480 }
14481
14482 case value_t::binary:
14483 {
14484 if (add_prefix)
14485 {
14486 oa->write_character(to_char_type('['));
14487 }
14488
14489 if (use_type && !j.m_value.binary->empty())
14490 {
14491 JSON_ASSERT(use_count);
14492 oa->write_character(to_char_type('$'));
14493 oa->write_character('U');
14494 }
14495
14496 if (use_count)
14497 {
14498 oa->write_character(to_char_type('#'));
14499 write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
14500 }
14501
14502 if (use_type)
14503 {
14504 oa->write_characters(
14505 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14506 j.m_value.binary->size());
14507 }
14508 else
14509 {
14510 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14511 {
14512 oa->write_character(to_char_type('U'));
14513 oa->write_character(j.m_value.binary->data()[i]);
14514 }
14515 }
14516
14517 if (!use_count)
14518 {
14519 oa->write_character(to_char_type(']'));
14520 }
14521
14522 break;
14523 }
14524
14525 case value_t::object:
14526 {
14527 if (add_prefix)
14528 {
14529 oa->write_character(to_char_type('{'));
14530 }
14531
14532 bool prefix_required = true;
14533 if (use_type && !j.m_value.object->empty())
14534 {
14535 JSON_ASSERT(use_count);
14536 const CharType first_prefix = ubjson_prefix(j.front());
14537 const bool same_prefix = std::all_of(j.begin(), j.end(),
14538 [this, first_prefix](const BasicJsonType & v)
14539 {
14540 return ubjson_prefix(v) == first_prefix;
14541 });
14542
14543 if (same_prefix)
14544 {
14545 prefix_required = false;
14546 oa->write_character(to_char_type('$'));
14547 oa->write_character(first_prefix);
14548 }
14549 }
14550
14551 if (use_count)
14552 {
14553 oa->write_character(to_char_type('#'));
14554 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
14555 }
14556
14557 for (const auto& el : *j.m_value.object)
14558 {
14559 write_number_with_ubjson_prefix(el.first.size(), true);
14560 oa->write_characters(
14561 reinterpret_cast<const CharType*>(el.first.c_str()),
14562 el.first.size());
14563 write_ubjson(el.second, use_count, use_type, prefix_required);
14564 }
14565
14566 if (!use_count)
14567 {
14568 oa->write_character(to_char_type('}'));
14569 }
14570
14571 break;
14572 }
14573
14574 case value_t::discarded:
14575 default:
14576 break;
14577 }
14578 }
14579
14580 private:
14582 // BSON //
14584
14589 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14590 {
14591 const auto it = name.find(static_cast<typename string_t::value_type>(0));
14592 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14593 {
14594 JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
14595 static_cast<void>(j);
14596 }
14597
14598 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14599 }
14600
14604 void write_bson_entry_header(const string_t& name,
14605 const std::uint8_t element_type)
14606 {
14607 oa->write_character(to_char_type(element_type)); // boolean
14608 oa->write_characters(
14609 reinterpret_cast<const CharType*>(name.c_str()),
14610 name.size() + 1u);
14611 }
14612
14616 void write_bson_boolean(const string_t& name,
14617 const bool value)
14618 {
14619 write_bson_entry_header(name, 0x08);
14620 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
14621 }
14622
14626 void write_bson_double(const string_t& name,
14627 const double value)
14628 {
14629 write_bson_entry_header(name, 0x01);
14630 write_number<double, true>(value);
14631 }
14632
14636 static std::size_t calc_bson_string_size(const string_t& value)
14637 {
14638 return sizeof(std::int32_t) + value.size() + 1ul;
14639 }
14640
14644 void write_bson_string(const string_t& name,
14645 const string_t& value)
14646 {
14647 write_bson_entry_header(name, 0x02);
14648
14649 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
14650 oa->write_characters(
14651 reinterpret_cast<const CharType*>(value.c_str()),
14652 value.size() + 1);
14653 }
14654
14658 void write_bson_null(const string_t& name)
14659 {
14660 write_bson_entry_header(name, 0x0A);
14661 }
14662
14666 static std::size_t calc_bson_integer_size(const std::int64_t value)
14667 {
14668 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
14669 ? sizeof(std::int32_t)
14670 : sizeof(std::int64_t);
14671 }
14672
14676 void write_bson_integer(const string_t& name,
14677 const std::int64_t value)
14678 {
14679 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
14680 {
14681 write_bson_entry_header(name, 0x10); // int32
14682 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
14683 }
14684 else
14685 {
14686 write_bson_entry_header(name, 0x12); // int64
14687 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
14688 }
14689 }
14690
14694 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
14695 {
14696 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14697 ? sizeof(std::int32_t)
14698 : sizeof(std::int64_t);
14699 }
14700
14704 void write_bson_unsigned(const string_t& name,
14705 const BasicJsonType& j)
14706 {
14707 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14708 {
14709 write_bson_entry_header(name, 0x10 /* int32 */);
14710 write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
14711 }
14712 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14713 {
14714 write_bson_entry_header(name, 0x12 /* int64 */);
14715 write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
14716 }
14717 else
14718 {
14719 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));
14720 }
14721 }
14722
14726 void write_bson_object_entry(const string_t& name,
14727 const typename BasicJsonType::object_t& value)
14728 {
14729 write_bson_entry_header(name, 0x03); // object
14730 write_bson_object(value);
14731 }
14732
14736 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
14737 {
14738 std::size_t array_index = 0ul;
14739
14740 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
14741 {
14742 return result + calc_bson_element_size(std::to_string(array_index++), el);
14743 });
14744
14745 return sizeof(std::int32_t) + embedded_document_size + 1ul;
14746 }
14747
14751 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
14752 {
14753 return sizeof(std::int32_t) + value.size() + 1ul;
14754 }
14755
14759 void write_bson_array(const string_t& name,
14760 const typename BasicJsonType::array_t& value)
14761 {
14762 write_bson_entry_header(name, 0x04); // array
14763 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
14764
14765 std::size_t array_index = 0ul;
14766
14767 for (const auto& el : value)
14768 {
14769 write_bson_element(std::to_string(array_index++), el);
14770 }
14771
14772 oa->write_character(to_char_type(0x00));
14773 }
14774
14778 void write_bson_binary(const string_t& name,
14779 const binary_t& value)
14780 {
14781 write_bson_entry_header(name, 0x05);
14782
14783 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
14784 write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : std::uint8_t(0x00));
14785
14786 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
14787 }
14788
14793 static std::size_t calc_bson_element_size(const string_t& name,
14794 const BasicJsonType& j)
14795 {
14796 const auto header_size = calc_bson_entry_header_size(name, j);
14797 switch (j.type())
14798 {
14799 case value_t::object:
14800 return header_size + calc_bson_object_size(*j.m_value.object);
14801
14802 case value_t::array:
14803 return header_size + calc_bson_array_size(*j.m_value.array);
14804
14805 case value_t::binary:
14806 return header_size + calc_bson_binary_size(*j.m_value.binary);
14807
14808 case value_t::boolean:
14809 return header_size + 1ul;
14810
14811 case value_t::number_float:
14812 return header_size + 8ul;
14813
14814 case value_t::number_integer:
14815 return header_size + calc_bson_integer_size(j.m_value.number_integer);
14816
14817 case value_t::number_unsigned:
14818 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
14819
14820 case value_t::string:
14821 return header_size + calc_bson_string_size(*j.m_value.string);
14822
14823 case value_t::null:
14824 return header_size + 0ul;
14825
14826 // LCOV_EXCL_START
14827 case value_t::discarded:
14828 default:
14829 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14830 return 0ul;
14831 // LCOV_EXCL_STOP
14832 }
14833 }
14834
14841 void write_bson_element(const string_t& name,
14842 const BasicJsonType& j)
14843 {
14844 switch (j.type())
14845 {
14846 case value_t::object:
14847 return write_bson_object_entry(name, *j.m_value.object);
14848
14849 case value_t::array:
14850 return write_bson_array(name, *j.m_value.array);
14851
14852 case value_t::binary:
14853 return write_bson_binary(name, *j.m_value.binary);
14854
14855 case value_t::boolean:
14856 return write_bson_boolean(name, j.m_value.boolean);
14857
14858 case value_t::number_float:
14859 return write_bson_double(name, j.m_value.number_float);
14860
14861 case value_t::number_integer:
14862 return write_bson_integer(name, j.m_value.number_integer);
14863
14864 case value_t::number_unsigned:
14865 return write_bson_unsigned(name, j);
14866
14867 case value_t::string:
14868 return write_bson_string(name, *j.m_value.string);
14869
14870 case value_t::null:
14871 return write_bson_null(name);
14872
14873 // LCOV_EXCL_START
14874 case value_t::discarded:
14875 default:
14876 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14877 return;
14878 // LCOV_EXCL_STOP
14879 }
14880 }
14881
14888 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14889 {
14890 std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
14891 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14892 {
14893 return result += calc_bson_element_size(el.first, el.second);
14894 });
14895
14896 return sizeof(std::int32_t) + document_size + 1ul;
14897 }
14898
14903 void write_bson_object(const typename BasicJsonType::object_t& value)
14904 {
14905 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14906
14907 for (const auto& el : value)
14908 {
14909 write_bson_element(el.first, el.second);
14910 }
14911
14912 oa->write_character(to_char_type(0x00));
14913 }
14914
14916 // CBOR //
14918
14919 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14920 {
14921 return to_char_type(0xFA); // Single-Precision Float
14922 }
14923
14924 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14925 {
14926 return to_char_type(0xFB); // Double-Precision Float
14927 }
14928
14930 // MsgPack //
14932
14933 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14934 {
14935 return to_char_type(0xCA); // float 32
14936 }
14937
14938 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14939 {
14940 return to_char_type(0xCB); // float 64
14941 }
14942
14944 // UBJSON //
14946
14947 // UBJSON: write number (floating point)
14948 template<typename NumberType, typename std::enable_if<
14949 std::is_floating_point<NumberType>::value, int>::type = 0>
14950 void write_number_with_ubjson_prefix(const NumberType n,
14951 const bool add_prefix)
14952 {
14953 if (add_prefix)
14954 {
14955 oa->write_character(get_ubjson_float_prefix(n));
14956 }
14957 write_number(n);
14958 }
14959
14960 // UBJSON: write number (unsigned integer)
14961 template<typename NumberType, typename std::enable_if<
14962 std::is_unsigned<NumberType>::value, int>::type = 0>
14963 void write_number_with_ubjson_prefix(const NumberType n,
14964 const bool add_prefix)
14965 {
14966 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14967 {
14968 if (add_prefix)
14969 {
14970 oa->write_character(to_char_type('i')); // int8
14971 }
14972 write_number(static_cast<std::uint8_t>(n));
14973 }
14974 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14975 {
14976 if (add_prefix)
14977 {
14978 oa->write_character(to_char_type('U')); // uint8
14979 }
14980 write_number(static_cast<std::uint8_t>(n));
14981 }
14982 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14983 {
14984 if (add_prefix)
14985 {
14986 oa->write_character(to_char_type('I')); // int16
14987 }
14988 write_number(static_cast<std::int16_t>(n));
14989 }
14990 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14991 {
14992 if (add_prefix)
14993 {
14994 oa->write_character(to_char_type('l')); // int32
14995 }
14996 write_number(static_cast<std::int32_t>(n));
14997 }
14998 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14999 {
15000 if (add_prefix)
15001 {
15002 oa->write_character(to_char_type('L')); // int64
15003 }
15004 write_number(static_cast<std::int64_t>(n));
15005 }
15006 else
15007 {
15008 if (add_prefix)
15009 {
15010 oa->write_character(to_char_type('H')); // high-precision number
15011 }
15012
15013 const auto number = BasicJsonType(n).dump();
15014 write_number_with_ubjson_prefix(number.size(), true);
15015 for (std::size_t i = 0; i < number.size(); ++i)
15016 {
15017 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15018 }
15019 }
15020 }
15021
15022 // UBJSON: write number (signed integer)
15023 template < typename NumberType, typename std::enable_if <
15024 std::is_signed<NumberType>::value&&
15025 !std::is_floating_point<NumberType>::value, int >::type = 0 >
15026 void write_number_with_ubjson_prefix(const NumberType n,
15027 const bool add_prefix)
15028 {
15029 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
15030 {
15031 if (add_prefix)
15032 {
15033 oa->write_character(to_char_type('i')); // int8
15034 }
15035 write_number(static_cast<std::int8_t>(n));
15036 }
15037 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)()))
15038 {
15039 if (add_prefix)
15040 {
15041 oa->write_character(to_char_type('U')); // uint8
15042 }
15043 write_number(static_cast<std::uint8_t>(n));
15044 }
15045 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
15046 {
15047 if (add_prefix)
15048 {
15049 oa->write_character(to_char_type('I')); // int16
15050 }
15051 write_number(static_cast<std::int16_t>(n));
15052 }
15053 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
15054 {
15055 if (add_prefix)
15056 {
15057 oa->write_character(to_char_type('l')); // int32
15058 }
15059 write_number(static_cast<std::int32_t>(n));
15060 }
15061 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
15062 {
15063 if (add_prefix)
15064 {
15065 oa->write_character(to_char_type('L')); // int64
15066 }
15067 write_number(static_cast<std::int64_t>(n));
15068 }
15069 // LCOV_EXCL_START
15070 else
15071 {
15072 if (add_prefix)
15073 {
15074 oa->write_character(to_char_type('H')); // high-precision number
15075 }
15076
15077 const auto number = BasicJsonType(n).dump();
15078 write_number_with_ubjson_prefix(number.size(), true);
15079 for (std::size_t i = 0; i < number.size(); ++i)
15080 {
15081 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15082 }
15083 }
15084 // LCOV_EXCL_STOP
15085 }
15086
15090 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
15091 {
15092 switch (j.type())
15093 {
15094 case value_t::null:
15095 return 'Z';
15096
15097 case value_t::boolean:
15098 return j.m_value.boolean ? 'T' : 'F';
15099
15100 case value_t::number_integer:
15101 {
15102 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)())
15103 {
15104 return 'i';
15105 }
15106 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)())
15107 {
15108 return 'U';
15109 }
15110 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)())
15111 {
15112 return 'I';
15113 }
15114 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)())
15115 {
15116 return 'l';
15117 }
15118 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)())
15119 {
15120 return 'L';
15121 }
15122 // anything else is treated as high-precision number
15123 return 'H'; // LCOV_EXCL_LINE
15124 }
15125
15126 case value_t::number_unsigned:
15127 {
15128 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15129 {
15130 return 'i';
15131 }
15132 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15133 {
15134 return 'U';
15135 }
15136 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15137 {
15138 return 'I';
15139 }
15140 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15141 {
15142 return 'l';
15143 }
15144 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15145 {
15146 return 'L';
15147 }
15148 // anything else is treated as high-precision number
15149 return 'H'; // LCOV_EXCL_LINE
15150 }
15151
15152 case value_t::number_float:
15153 return get_ubjson_float_prefix(j.m_value.number_float);
15154
15155 case value_t::string:
15156 return 'S';
15157
15158 case value_t::array: // fallthrough
15159 case value_t::binary:
15160 return '[';
15161
15162 case value_t::object:
15163 return '{';
15164
15165 case value_t::discarded:
15166 default: // discarded values
15167 return 'N';
15168 }
15169 }
15170
15171 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15172 {
15173 return 'd'; // float 32
15174 }
15175
15176 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15177 {
15178 return 'D'; // float 64
15179 }
15180
15182 // Utility functions //
15184
15185 /*
15186 @brief write a number to output input
15187 @param[in] n number of type @a NumberType
15188 @tparam NumberType the type of the number
15189 @tparam OutputIsLittleEndian Set to true if output data is
15190 required to be little endian
15191
15192 @note This function needs to respect the system's endianess, because bytes
15193 in CBOR, MessagePack, and UBJSON are stored in network order (big
15194 endian) and therefore need reordering on little endian systems.
15195 */
15196 template<typename NumberType, bool OutputIsLittleEndian = false>
15197 void write_number(const NumberType n)
15198 {
15199 // step 1: write number to array of length NumberType
15200 std::array<CharType, sizeof(NumberType)> vec{};
15201 std::memcpy(vec.data(), &n, sizeof(NumberType));
15202
15203 // step 2: write array to output (with possible reordering)
15204 if (is_little_endian != OutputIsLittleEndian)
15205 {
15206 // reverse byte order prior to conversion if necessary
15207 std::reverse(vec.begin(), vec.end());
15208 }
15209
15210 oa->write_characters(vec.data(), sizeof(NumberType));
15211 }
15212
15213 void write_compact_float(const number_float_t n, detail::input_format_t format)
15214 {
15215#ifdef __GNUC__
15216#pragma GCC diagnostic push
15217#pragma GCC diagnostic ignored "-Wfloat-equal"
15218#endif
15219 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
15220 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
15221 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
15222 {
15223 oa->write_character(format == detail::input_format_t::cbor
15224 ? get_cbor_float_prefix(static_cast<float>(n))
15225 : get_msgpack_float_prefix(static_cast<float>(n)));
15226 write_number(static_cast<float>(n));
15227 }
15228 else
15229 {
15230 oa->write_character(format == detail::input_format_t::cbor
15231 ? get_cbor_float_prefix(n)
15232 : get_msgpack_float_prefix(n));
15233 write_number(n);
15234 }
15235#ifdef __GNUC__
15236#pragma GCC diagnostic pop
15237#endif
15238 }
15239
15240 public:
15241 // The following to_char_type functions are implement the conversion
15242 // between uint8_t and CharType. In case CharType is not unsigned,
15243 // such a conversion is required to allow values greater than 128.
15244 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
15245 template < typename C = CharType,
15246 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
15247 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15248 {
15249 return *reinterpret_cast<char*>(&x);
15250 }
15251
15252 template < typename C = CharType,
15253 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
15254 static CharType to_char_type(std::uint8_t x) noexcept
15255 {
15256 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
15257 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
15258 CharType result;
15259 std::memcpy(&result, &x, sizeof(x));
15260 return result;
15261 }
15262
15263 template<typename C = CharType,
15264 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
15265 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15266 {
15267 return x;
15268 }
15269
15270 template < typename InputCharType, typename C = CharType,
15271 enable_if_t <
15272 std::is_signed<C>::value &&
15273 std::is_signed<char>::value &&
15274 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
15275 > * = nullptr >
15276 static constexpr CharType to_char_type(InputCharType x) noexcept
15277 {
15278 return x;
15279 }
15280
15281 private:
15283 const bool is_little_endian = little_endianess();
15284
15286 output_adapter_t<CharType> oa = nullptr;
15287};
15288} // namespace detail
15289} // namespace nlohmann
15290
15291// #include <nlohmann/detail/output/output_adapters.hpp>
15292
15293// #include <nlohmann/detail/output/serializer.hpp>
15294
15295
15296#include <algorithm> // reverse, remove, fill, find, none_of
15297#include <array> // array
15298#include <clocale> // localeconv, lconv
15299#include <cmath> // labs, isfinite, isnan, signbit
15300#include <cstddef> // size_t, ptrdiff_t
15301#include <cstdint> // uint8_t
15302#include <cstdio> // snprintf
15303#include <limits> // numeric_limits
15304#include <string> // string, char_traits
15305#include <type_traits> // is_same
15306#include <utility> // move
15307
15308// #include <nlohmann/detail/conversions/to_chars.hpp>
15309
15310
15311#include <array> // array
15312#include <cmath> // signbit, isfinite
15313#include <cstdint> // intN_t, uintN_t
15314#include <cstring> // memcpy, memmove
15315#include <limits> // numeric_limits
15316#include <type_traits> // conditional
15317
15318// #include <nlohmann/detail/macro_scope.hpp>
15319
15320
15321namespace nlohmann
15322{
15323namespace detail
15324{
15325
15345namespace dtoa_impl
15346{
15347
15348template<typename Target, typename Source>
15349Target reinterpret_bits(const Source source)
15350{
15351 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
15352
15353 Target target;
15354 std::memcpy(&target, &source, sizeof(Source));
15355 return target;
15356}
15357
15358struct diyfp // f * 2^e
15359{
15360 static constexpr int kPrecision = 64; // = q
15361
15362 std::uint64_t f = 0;
15363 int e = 0;
15364
15365 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
15366
15371 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
15372 {
15373 JSON_ASSERT(x.e == y.e);
15374 JSON_ASSERT(x.f >= y.f);
15375
15376 return {x.f - y.f, x.e};
15377 }
15378
15383 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
15384 {
15385 static_assert(kPrecision == 64, "internal error");
15386
15387 // Computes:
15388 // f = round((x.f * y.f) / 2^q)
15389 // e = x.e + y.e + q
15390
15391 // Emulate the 64-bit * 64-bit multiplication:
15392 //
15393 // p = u * v
15394 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15395 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
15396 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
15397 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
15398 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
15399 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
15400 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
15401 //
15402 // (Since Q might be larger than 2^32 - 1)
15403 //
15404 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15405 //
15406 // (Q_hi + H does not overflow a 64-bit int)
15407 //
15408 // = p_lo + 2^64 p_hi
15409
15410 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15411 const std::uint64_t u_hi = x.f >> 32u;
15412 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15413 const std::uint64_t v_hi = y.f >> 32u;
15414
15415 const std::uint64_t p0 = u_lo * v_lo;
15416 const std::uint64_t p1 = u_lo * v_hi;
15417 const std::uint64_t p2 = u_hi * v_lo;
15418 const std::uint64_t p3 = u_hi * v_hi;
15419
15420 const std::uint64_t p0_hi = p0 >> 32u;
15421 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15422 const std::uint64_t p1_hi = p1 >> 32u;
15423 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15424 const std::uint64_t p2_hi = p2 >> 32u;
15425
15426 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15427
15428 // The full product might now be computed as
15429 //
15430 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
15431 // p_lo = p0_lo + (Q << 32)
15432 //
15433 // But in this particular case here, the full p_lo is not required.
15434 // Effectively we only need to add the highest bit in p_lo to p_hi (and
15435 // Q_hi + 1 does not overflow).
15436
15437 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
15438
15439 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15440
15441 return {h, x.e + y.e + 64};
15442 }
15443
15448 static diyfp normalize(diyfp x) noexcept
15449 {
15450 JSON_ASSERT(x.f != 0);
15451
15452 while ((x.f >> 63u) == 0)
15453 {
15454 x.f <<= 1u;
15455 x.e--;
15456 }
15457
15458 return x;
15459 }
15460
15465 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
15466 {
15467 const int delta = x.e - target_exponent;
15468
15469 JSON_ASSERT(delta >= 0);
15470 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
15471
15472 return {x.f << delta, target_exponent};
15473 }
15474};
15475
15476struct boundaries
15477{
15478 diyfp w;
15479 diyfp minus;
15480 diyfp plus;
15481};
15482
15489template<typename FloatType>
15490boundaries compute_boundaries(FloatType value)
15491{
15492 JSON_ASSERT(std::isfinite(value));
15493 JSON_ASSERT(value > 0);
15494
15495 // Convert the IEEE representation into a diyfp.
15496 //
15497 // If v is denormal:
15498 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
15499 // If v is normalized:
15500 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
15501
15502 static_assert(std::numeric_limits<FloatType>::is_iec559,
15503 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
15504
15505 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
15506 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
15507 constexpr int kMinExp = 1 - kBias;
15508 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
15509
15510 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
15511
15512 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
15513 const std::uint64_t E = bits >> (kPrecision - 1);
15514 const std::uint64_t F = bits & (kHiddenBit - 1);
15515
15516 const bool is_denormal = E == 0;
15517 const diyfp v = is_denormal
15518 ? diyfp(F, kMinExp)
15519 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
15520
15521 // Compute the boundaries m- and m+ of the floating-point value
15522 // v = f * 2^e.
15523 //
15524 // Determine v- and v+, the floating-point predecessor and successor if v,
15525 // respectively.
15526 //
15527 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
15528 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
15529 //
15530 // v+ = v + 2^e
15531 //
15532 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
15533 // between m- and m+ round to v, regardless of how the input rounding
15534 // algorithm breaks ties.
15535 //
15536 // ---+-------------+-------------+-------------+-------------+--- (A)
15537 // v- m- v m+ v+
15538 //
15539 // -----------------+------+------+-------------+-------------+--- (B)
15540 // v- m- v m+ v+
15541
15542 const bool lower_boundary_is_closer = F == 0 && E > 1;
15543 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
15544 const diyfp m_minus = lower_boundary_is_closer
15545 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
15546 : diyfp(2 * v.f - 1, v.e - 1); // (A)
15547
15548 // Determine the normalized w+ = m+.
15549 const diyfp w_plus = diyfp::normalize(m_plus);
15550
15551 // Determine w- = m- such that e_(w-) = e_(w+).
15552 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
15553
15554 return {diyfp::normalize(v), w_minus, w_plus};
15555}
15556
15557// Given normalized diyfp w, Grisu needs to find a (normalized) cached
15558// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
15559// within a certain range [alpha, gamma] (Definition 3.2 from [1])
15560//
15561// alpha <= e = e_c + e_w + q <= gamma
15562//
15563// or
15564//
15565// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
15566// <= f_c * f_w * 2^gamma
15567//
15568// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
15569//
15570// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
15571//
15572// or
15573//
15574// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
15575//
15576// The choice of (alpha,gamma) determines the size of the table and the form of
15577// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
15578// in practice:
15579//
15580// The idea is to cut the number c * w = f * 2^e into two parts, which can be
15581// processed independently: An integral part p1, and a fractional part p2:
15582//
15583// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
15584// = (f div 2^-e) + (f mod 2^-e) * 2^e
15585// = p1 + p2 * 2^e
15586//
15587// The conversion of p1 into decimal form requires a series of divisions and
15588// modulos by (a power of) 10. These operations are faster for 32-bit than for
15589// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
15590// achieved by choosing
15591//
15592// -e >= 32 or e <= -32 := gamma
15593//
15594// In order to convert the fractional part
15595//
15596// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
15597//
15598// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
15599// d[-i] are extracted in order:
15600//
15601// (10 * p2) div 2^-e = d[-1]
15602// (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
15603//
15604// The multiplication by 10 must not overflow. It is sufficient to choose
15605//
15606// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
15607//
15608// Since p2 = f mod 2^-e < 2^-e,
15609//
15610// -e <= 60 or e >= -60 := alpha
15611
15612constexpr int kAlpha = -60;
15613constexpr int kGamma = -32;
15614
15615struct cached_power // c = f * 2^e ~= 10^k
15616{
15617 std::uint64_t f;
15618 int e;
15619 int k;
15620};
15621
15629inline cached_power get_cached_power_for_binary_exponent(int e)
15630{
15631 // Now
15632 //
15633 // alpha <= e_c + e + q <= gamma (1)
15634 // ==> f_c * 2^alpha <= c * 2^e * 2^q
15635 //
15636 // and since the c's are normalized, 2^(q-1) <= f_c,
15637 //
15638 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
15639 // ==> 2^(alpha - e - 1) <= c
15640 //
15641 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
15642 //
15643 // k = ceil( log_10( 2^(alpha - e - 1) ) )
15644 // = ceil( (alpha - e - 1) * log_10(2) )
15645 //
15646 // From the paper:
15647 // "In theory the result of the procedure could be wrong since c is rounded,
15648 // and the computation itself is approximated [...]. In practice, however,
15649 // this simple function is sufficient."
15650 //
15651 // For IEEE double precision floating-point numbers converted into
15652 // normalized diyfp's w = f * 2^e, with q = 64,
15653 //
15654 // e >= -1022 (min IEEE exponent)
15655 // -52 (p - 1)
15656 // -52 (p - 1, possibly normalize denormal IEEE numbers)
15657 // -11 (normalize the diyfp)
15658 // = -1137
15659 //
15660 // and
15661 //
15662 // e <= +1023 (max IEEE exponent)
15663 // -52 (p - 1)
15664 // -11 (normalize the diyfp)
15665 // = 960
15666 //
15667 // This binary exponent range [-1137,960] results in a decimal exponent
15668 // range [-307,324]. One does not need to store a cached power for each
15669 // k in this range. For each such k it suffices to find a cached power
15670 // such that the exponent of the product lies in [alpha,gamma].
15671 // This implies that the difference of the decimal exponents of adjacent
15672 // table entries must be less than or equal to
15673 //
15674 // floor( (gamma - alpha) * log_10(2) ) = 8.
15675 //
15676 // (A smaller distance gamma-alpha would require a larger table.)
15677
15678 // NB:
15679 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
15680
15681 constexpr int kCachedPowersMinDecExp = -300;
15682 constexpr int kCachedPowersDecStep = 8;
15683
15684 static constexpr std::array<cached_power, 79> kCachedPowers =
15685 {
15686 {
15687 { 0xAB70FE17C79AC6CA, -1060, -300 },
15688 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
15689 { 0xBE5691EF416BD60C, -1007, -284 },
15690 { 0x8DD01FAD907FFC3C, -980, -276 },
15691 { 0xD3515C2831559A83, -954, -268 },
15692 { 0x9D71AC8FADA6C9B5, -927, -260 },
15693 { 0xEA9C227723EE8BCB, -901, -252 },
15694 { 0xAECC49914078536D, -874, -244 },
15695 { 0x823C12795DB6CE57, -847, -236 },
15696 { 0xC21094364DFB5637, -821, -228 },
15697 { 0x9096EA6F3848984F, -794, -220 },
15698 { 0xD77485CB25823AC7, -768, -212 },
15699 { 0xA086CFCD97BF97F4, -741, -204 },
15700 { 0xEF340A98172AACE5, -715, -196 },
15701 { 0xB23867FB2A35B28E, -688, -188 },
15702 { 0x84C8D4DFD2C63F3B, -661, -180 },
15703 { 0xC5DD44271AD3CDBA, -635, -172 },
15704 { 0x936B9FCEBB25C996, -608, -164 },
15705 { 0xDBAC6C247D62A584, -582, -156 },
15706 { 0xA3AB66580D5FDAF6, -555, -148 },
15707 { 0xF3E2F893DEC3F126, -529, -140 },
15708 { 0xB5B5ADA8AAFF80B8, -502, -132 },
15709 { 0x87625F056C7C4A8B, -475, -124 },
15710 { 0xC9BCFF6034C13053, -449, -116 },
15711 { 0x964E858C91BA2655, -422, -108 },
15712 { 0xDFF9772470297EBD, -396, -100 },
15713 { 0xA6DFBD9FB8E5B88F, -369, -92 },
15714 { 0xF8A95FCF88747D94, -343, -84 },
15715 { 0xB94470938FA89BCF, -316, -76 },
15716 { 0x8A08F0F8BF0F156B, -289, -68 },
15717 { 0xCDB02555653131B6, -263, -60 },
15718 { 0x993FE2C6D07B7FAC, -236, -52 },
15719 { 0xE45C10C42A2B3B06, -210, -44 },
15720 { 0xAA242499697392D3, -183, -36 },
15721 { 0xFD87B5F28300CA0E, -157, -28 },
15722 { 0xBCE5086492111AEB, -130, -20 },
15723 { 0x8CBCCC096F5088CC, -103, -12 },
15724 { 0xD1B71758E219652C, -77, -4 },
15725 { 0x9C40000000000000, -50, 4 },
15726 { 0xE8D4A51000000000, -24, 12 },
15727 { 0xAD78EBC5AC620000, 3, 20 },
15728 { 0x813F3978F8940984, 30, 28 },
15729 { 0xC097CE7BC90715B3, 56, 36 },
15730 { 0x8F7E32CE7BEA5C70, 83, 44 },
15731 { 0xD5D238A4ABE98068, 109, 52 },
15732 { 0x9F4F2726179A2245, 136, 60 },
15733 { 0xED63A231D4C4FB27, 162, 68 },
15734 { 0xB0DE65388CC8ADA8, 189, 76 },
15735 { 0x83C7088E1AAB65DB, 216, 84 },
15736 { 0xC45D1DF942711D9A, 242, 92 },
15737 { 0x924D692CA61BE758, 269, 100 },
15738 { 0xDA01EE641A708DEA, 295, 108 },
15739 { 0xA26DA3999AEF774A, 322, 116 },
15740 { 0xF209787BB47D6B85, 348, 124 },
15741 { 0xB454E4A179DD1877, 375, 132 },
15742 { 0x865B86925B9BC5C2, 402, 140 },
15743 { 0xC83553C5C8965D3D, 428, 148 },
15744 { 0x952AB45CFA97A0B3, 455, 156 },
15745 { 0xDE469FBD99A05FE3, 481, 164 },
15746 { 0xA59BC234DB398C25, 508, 172 },
15747 { 0xF6C69A72A3989F5C, 534, 180 },
15748 { 0xB7DCBF5354E9BECE, 561, 188 },
15749 { 0x88FCF317F22241E2, 588, 196 },
15750 { 0xCC20CE9BD35C78A5, 614, 204 },
15751 { 0x98165AF37B2153DF, 641, 212 },
15752 { 0xE2A0B5DC971F303A, 667, 220 },
15753 { 0xA8D9D1535CE3B396, 694, 228 },
15754 { 0xFB9B7CD9A4A7443C, 720, 236 },
15755 { 0xBB764C4CA7A44410, 747, 244 },
15756 { 0x8BAB8EEFB6409C1A, 774, 252 },
15757 { 0xD01FEF10A657842C, 800, 260 },
15758 { 0x9B10A4E5E9913129, 827, 268 },
15759 { 0xE7109BFBA19C0C9D, 853, 276 },
15760 { 0xAC2820D9623BF429, 880, 284 },
15761 { 0x80444B5E7AA7CF85, 907, 292 },
15762 { 0xBF21E44003ACDD2D, 933, 300 },
15763 { 0x8E679C2F5E44FF8F, 960, 308 },
15764 { 0xD433179D9C8CB841, 986, 316 },
15765 { 0x9E19DB92B4E31BA9, 1013, 324 },
15766 }
15767 };
15768
15769 // This computation gives exactly the same results for k as
15770 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
15771 // for |e| <= 1500, but doesn't require floating-point operations.
15772 // NB: log_10(2) ~= 78913 / 2^18
15773 JSON_ASSERT(e >= -1500);
15774 JSON_ASSERT(e <= 1500);
15775 const int f = kAlpha - e - 1;
15776 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
15777
15778 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
15779 JSON_ASSERT(index >= 0);
15780 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
15781
15782 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
15783 JSON_ASSERT(kAlpha <= cached.e + e + 64);
15784 JSON_ASSERT(kGamma >= cached.e + e + 64);
15785
15786 return cached;
15787}
15788
15793inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
15794{
15795 // LCOV_EXCL_START
15796 if (n >= 1000000000)
15797 {
15798 pow10 = 1000000000;
15799 return 10;
15800 }
15801 // LCOV_EXCL_STOP
15802 if (n >= 100000000)
15803 {
15804 pow10 = 100000000;
15805 return 9;
15806 }
15807 if (n >= 10000000)
15808 {
15809 pow10 = 10000000;
15810 return 8;
15811 }
15812 if (n >= 1000000)
15813 {
15814 pow10 = 1000000;
15815 return 7;
15816 }
15817 if (n >= 100000)
15818 {
15819 pow10 = 100000;
15820 return 6;
15821 }
15822 if (n >= 10000)
15823 {
15824 pow10 = 10000;
15825 return 5;
15826 }
15827 if (n >= 1000)
15828 {
15829 pow10 = 1000;
15830 return 4;
15831 }
15832 if (n >= 100)
15833 {
15834 pow10 = 100;
15835 return 3;
15836 }
15837 if (n >= 10)
15838 {
15839 pow10 = 10;
15840 return 2;
15841 }
15842
15843 pow10 = 1;
15844 return 1;
15845}
15846
15847inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
15848 std::uint64_t rest, std::uint64_t ten_k)
15849{
15850 JSON_ASSERT(len >= 1);
15851 JSON_ASSERT(dist <= delta);
15852 JSON_ASSERT(rest <= delta);
15853 JSON_ASSERT(ten_k > 0);
15854
15855 // <--------------------------- delta ---->
15856 // <---- dist --------->
15857 // --------------[------------------+-------------------]--------------
15858 // M- w M+
15859 //
15860 // ten_k
15861 // <------>
15862 // <---- rest ---->
15863 // --------------[------------------+----+--------------]--------------
15864 // w V
15865 // = buf * 10^k
15866 //
15867 // ten_k represents a unit-in-the-last-place in the decimal representation
15868 // stored in buf.
15869 // Decrement buf by ten_k while this takes buf closer to w.
15870
15871 // The tests are written in this order to avoid overflow in unsigned
15872 // integer arithmetic.
15873
15874 while (rest < dist
15875 && delta - rest >= ten_k
15876 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
15877 {
15878 JSON_ASSERT(buf[len - 1] != '0');
15879 buf[len - 1]--;
15880 rest += ten_k;
15881 }
15882}
15883
15888inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
15889 diyfp M_minus, diyfp w, diyfp M_plus)
15890{
15891 static_assert(kAlpha >= -60, "internal error");
15892 static_assert(kGamma <= -32, "internal error");
15893
15894 // Generates the digits (and the exponent) of a decimal floating-point
15895 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15896 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15897 //
15898 // <--------------------------- delta ---->
15899 // <---- dist --------->
15900 // --------------[------------------+-------------------]--------------
15901 // M- w M+
15902 //
15903 // Grisu2 generates the digits of M+ from left to right and stops as soon as
15904 // V is in [M-,M+].
15905
15906 JSON_ASSERT(M_plus.e >= kAlpha);
15907 JSON_ASSERT(M_plus.e <= kGamma);
15908
15909 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15910 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
15911
15912 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15913 //
15914 // M+ = f * 2^e
15915 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15916 // = ((p1 ) * 2^-e + (p2 )) * 2^e
15917 // = p1 + p2 * 2^e
15918
15919 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15920
15921 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.)
15922 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
15923
15924 // 1)
15925 //
15926 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15927
15928 JSON_ASSERT(p1 > 0);
15929
15930 std::uint32_t pow10{};
15931 const int k = find_largest_pow10(p1, pow10);
15932
15933 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15934 //
15935 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15936 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
15937 //
15938 // M+ = p1 + p2 * 2^e
15939 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
15940 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15941 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
15942 //
15943 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15944 //
15945 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15946 //
15947 // but stop as soon as
15948 //
15949 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15950
15951 int n = k;
15952 while (n > 0)
15953 {
15954 // Invariants:
15955 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
15956 // pow10 = 10^(n-1) <= p1 < 10^n
15957 //
15958 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
15959 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
15960 //
15961 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15962 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15963 //
15964 JSON_ASSERT(d <= 9);
15965 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15966 //
15967 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15968 //
15969 p1 = r;
15970 n--;
15971 //
15972 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
15973 // pow10 = 10^n
15974 //
15975
15976 // Now check if enough digits have been generated.
15977 // Compute
15978 //
15979 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15980 //
15981 // Note:
15982 // Since rest and delta share the same exponent e, it suffices to
15983 // compare the significands.
15984 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15985 if (rest <= delta)
15986 {
15987 // V = buffer * 10^n, with M- <= V <= M+.
15988
15989 decimal_exponent += n;
15990
15991 // We may now just stop. But instead look if the buffer could be
15992 // decremented to bring V closer to w.
15993 //
15994 // pow10 = 10^n is now 1 ulp in the decimal representation V.
15995 // The rounding procedure works with diyfp's with an implicit
15996 // exponent of e.
15997 //
15998 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15999 //
16000 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
16001 grisu2_round(buffer, length, dist, delta, rest, ten_n);
16002
16003 return;
16004 }
16005
16006 pow10 /= 10;
16007 //
16008 // pow10 = 10^(n-1) <= p1 < 10^n
16009 // Invariants restored.
16010 }
16011
16012 // 2)
16013 //
16014 // The digits of the integral part have been generated:
16015 //
16016 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
16017 // = buffer + p2 * 2^e
16018 //
16019 // Now generate the digits of the fractional part p2 * 2^e.
16020 //
16021 // Note:
16022 // No decimal point is generated: the exponent is adjusted instead.
16023 //
16024 // p2 actually represents the fraction
16025 //
16026 // p2 * 2^e
16027 // = p2 / 2^-e
16028 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
16029 //
16030 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
16031 //
16032 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
16033 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
16034 //
16035 // using
16036 //
16037 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
16038 // = ( d) * 2^-e + ( r)
16039 //
16040 // or
16041 // 10^m * p2 * 2^e = d + r * 2^e
16042 //
16043 // i.e.
16044 //
16045 // M+ = buffer + p2 * 2^e
16046 // = buffer + 10^-m * (d + r * 2^e)
16047 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
16048 //
16049 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
16050
16051 JSON_ASSERT(p2 > delta);
16052
16053 int m = 0;
16054 for (;;)
16055 {
16056 // Invariant:
16057 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
16058 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
16059 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
16060 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
16061 //
16062 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
16063 p2 *= 10;
16064 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
16065 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
16066 //
16067 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
16068 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
16069 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
16070 //
16071 JSON_ASSERT(d <= 9);
16072 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16073 //
16074 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
16075 //
16076 p2 = r;
16077 m++;
16078 //
16079 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
16080 // Invariant restored.
16081
16082 // Check if enough digits have been generated.
16083 //
16084 // 10^-m * p2 * 2^e <= delta * 2^e
16085 // p2 * 2^e <= 10^m * delta * 2^e
16086 // p2 <= 10^m * delta
16087 delta *= 10;
16088 dist *= 10;
16089 if (p2 <= delta)
16090 {
16091 break;
16092 }
16093 }
16094
16095 // V = buffer * 10^-m, with M- <= V <= M+.
16096
16097 decimal_exponent -= m;
16098
16099 // 1 ulp in the decimal representation is now 10^-m.
16100 // Since delta and dist are now scaled by 10^m, we need to do the
16101 // same with ulp in order to keep the units in sync.
16102 //
16103 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16104 //
16105 const std::uint64_t ten_m = one.f;
16106 grisu2_round(buffer, length, dist, delta, p2, ten_m);
16107
16108 // By construction this algorithm generates the shortest possible decimal
16109 // number (Loitsch, Theorem 6.2) which rounds back to w.
16110 // For an input number of precision p, at least
16111 //
16112 // N = 1 + ceil(p * log_10(2))
16113 //
16114 // decimal digits are sufficient to identify all binary floating-point
16115 // numbers (Matula, "In-and-Out conversions").
16116 // This implies that the algorithm does not produce more than N decimal
16117 // digits.
16118 //
16119 // N = 17 for p = 53 (IEEE double precision)
16120 // N = 9 for p = 24 (IEEE single precision)
16121}
16122
16128JSON_HEDLEY_NON_NULL(1)
16129inline void grisu2(char* buf, int& len, int& decimal_exponent,
16130 diyfp m_minus, diyfp v, diyfp m_plus)
16131{
16132 JSON_ASSERT(m_plus.e == m_minus.e);
16133 JSON_ASSERT(m_plus.e == v.e);
16134
16135 // --------(-----------------------+-----------------------)-------- (A)
16136 // m- v m+
16137 //
16138 // --------------------(-----------+-----------------------)-------- (B)
16139 // m- v m+
16140 //
16141 // First scale v (and m- and m+) such that the exponent is in the range
16142 // [alpha, gamma].
16143
16144 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
16145
16146 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
16147
16148 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
16149 const diyfp w = diyfp::mul(v, c_minus_k);
16150 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
16151 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
16152
16153 // ----(---+---)---------------(---+---)---------------(---+---)----
16154 // w- w w+
16155 // = c*m- = c*v = c*m+
16156 //
16157 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
16158 // w+ are now off by a small amount.
16159 // In fact:
16160 //
16161 // w - v * 10^k < 1 ulp
16162 //
16163 // To account for this inaccuracy, add resp. subtract 1 ulp.
16164 //
16165 // --------+---[---------------(---+---)---------------]---+--------
16166 // w- M- w M+ w+
16167 //
16168 // Now any number in [M-, M+] (bounds included) will round to w when input,
16169 // regardless of how the input rounding algorithm breaks ties.
16170 //
16171 // And digit_gen generates the shortest possible such number in [M-, M+].
16172 // Note that this does not mean that Grisu2 always generates the shortest
16173 // possible number in the interval (m-, m+).
16174 const diyfp M_minus(w_minus.f + 1, w_minus.e);
16175 const diyfp M_plus (w_plus.f - 1, w_plus.e );
16176
16177 decimal_exponent = -cached.k; // = -(-k) = k
16178
16179 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
16180}
16181
16187template<typename FloatType>
16188JSON_HEDLEY_NON_NULL(1)
16189void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
16190{
16191 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
16192 "internal error: not enough precision");
16193
16194 JSON_ASSERT(std::isfinite(value));
16195 JSON_ASSERT(value > 0);
16196
16197 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
16198 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
16199 // decimal representations are not exactly "short".
16200 //
16201 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
16202 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
16203 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
16204 // does.
16205 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
16206 // representation using the corresponding std::from_chars function recovers value exactly". That
16207 // indicates that single precision floating-point numbers should be recovered using
16208 // 'std::strtof'.
16209 //
16210 // NB: If the neighbors are computed for single-precision numbers, there is a single float
16211 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
16212 // value is off by 1 ulp.
16213#if 0
16214 const boundaries w = compute_boundaries(static_cast<double>(value));
16215#else
16216 const boundaries w = compute_boundaries(value);
16217#endif
16218
16219 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
16220}
16221
16227JSON_HEDLEY_NON_NULL(1)
16228
16229inline char* append_exponent(char* buf, int e)
16230{
16231 JSON_ASSERT(e > -1000);
16232 JSON_ASSERT(e < 1000);
16233
16234 if (e < 0)
16235 {
16236 e = -e;
16237 *buf++ = '-';
16238 }
16239 else
16240 {
16241 *buf++ = '+';
16242 }
16243
16244 auto k = static_cast<std::uint32_t>(e);
16245 if (k < 10)
16246 {
16247 // Always print at least two digits in the exponent.
16248 // This is for compatibility with printf("%g").
16249 *buf++ = '0';
16250 *buf++ = static_cast<char>('0' + k);
16251 }
16252 else if (k < 100)
16253 {
16254 *buf++ = static_cast<char>('0' + k / 10);
16255 k %= 10;
16256 *buf++ = static_cast<char>('0' + k);
16257 }
16258 else
16259 {
16260 *buf++ = static_cast<char>('0' + k / 100);
16261 k %= 100;
16262 *buf++ = static_cast<char>('0' + k / 10);
16263 k %= 10;
16264 *buf++ = static_cast<char>('0' + k);
16265 }
16266
16267 return buf;
16268}
16269
16279JSON_HEDLEY_NON_NULL(1)
16280
16281inline char* format_buffer(char* buf, int len, int decimal_exponent,
16282 int min_exp, int max_exp)
16283{
16284 JSON_ASSERT(min_exp < 0);
16285 JSON_ASSERT(max_exp > 0);
16286
16287 const int k = len;
16288 const int n = len + decimal_exponent;
16289
16290 // v = buf * 10^(n-k)
16291 // k is the length of the buffer (number of decimal digits)
16292 // n is the position of the decimal point relative to the start of the buffer.
16293
16294 if (k <= n && n <= max_exp)
16295 {
16296 // digits[000]
16297 // len <= max_exp + 2
16298
16299 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
16300 // Make it look like a floating-point number (#362, #378)
16301 buf[n + 0] = '.';
16302 buf[n + 1] = '0';
16303 return buf + (static_cast<size_t>(n) + 2);
16304 }
16305
16306 if (0 < n && n <= max_exp)
16307 {
16308 // dig.its
16309 // len <= max_digits10 + 1
16310
16311 JSON_ASSERT(k > n);
16312
16313 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
16314 buf[n] = '.';
16315 return buf + (static_cast<size_t>(k) + 1U);
16316 }
16317
16318 if (min_exp < n && n <= 0)
16319 {
16320 // 0.[000]digits
16321 // len <= 2 + (-min_exp - 1) + max_digits10
16322
16323 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
16324 buf[0] = '0';
16325 buf[1] = '.';
16326 std::memset(buf + 2, '0', static_cast<size_t>(-n));
16327 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
16328 }
16329
16330 if (k == 1)
16331 {
16332 // dE+123
16333 // len <= 1 + 5
16334
16335 buf += 1;
16336 }
16337 else
16338 {
16339 // d.igitsE+123
16340 // len <= max_digits10 + 1 + 5
16341
16342 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
16343 buf[1] = '.';
16344 buf += 1 + static_cast<size_t>(k);
16345 }
16346
16347 *buf++ = 'e';
16348 return append_exponent(buf, n - 1);
16349}
16350
16351} // namespace dtoa_impl
16352
16363template<typename FloatType>
16364JSON_HEDLEY_NON_NULL(1, 2)
16365
16366char* to_chars(char* first, const char* last, FloatType value)
16367{
16368 static_cast<void>(last); // maybe unused - fix warning
16369 JSON_ASSERT(std::isfinite(value));
16370
16371 // Use signbit(value) instead of (value < 0) since signbit works for -0.
16372 if (std::signbit(value))
16373 {
16374 value = -value;
16375 *first++ = '-';
16376 }
16377
16378#ifdef __GNUC__
16379#pragma GCC diagnostic push
16380#pragma GCC diagnostic ignored "-Wfloat-equal"
16381#endif
16382 if (value == 0) // +-0
16383 {
16384 *first++ = '0';
16385 // Make it look like a floating-point number (#362, #378)
16386 *first++ = '.';
16387 *first++ = '0';
16388 return first;
16389 }
16390#ifdef __GNUC__
16391#pragma GCC diagnostic pop
16392#endif
16393
16394 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
16395
16396 // Compute v = buffer * 10^decimal_exponent.
16397 // The decimal digits are stored in the buffer, which needs to be interpreted
16398 // as an unsigned decimal integer.
16399 // len is the length of the buffer, i.e. the number of decimal digits.
16400 int len = 0;
16401 int decimal_exponent = 0;
16402 dtoa_impl::grisu2(first, len, decimal_exponent, value);
16403
16404 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
16405
16406 // Format the buffer like printf("%.*g", prec, value)
16407 constexpr int kMinExp = -4;
16408 // Use digits10 here to increase compatibility with version 2.
16409 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
16410
16411 JSON_ASSERT(last - first >= kMaxExp + 2);
16412 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
16413 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
16414
16415 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
16416}
16417
16418} // namespace detail
16419} // namespace nlohmann
16420
16421// #include <nlohmann/detail/exceptions.hpp>
16422
16423// #include <nlohmann/detail/macro_scope.hpp>
16424
16425// #include <nlohmann/detail/meta/cpp_future.hpp>
16426
16427// #include <nlohmann/detail/output/binary_writer.hpp>
16428
16429// #include <nlohmann/detail/output/output_adapters.hpp>
16430
16431// #include <nlohmann/detail/value_t.hpp>
16432
16433
16434namespace nlohmann
16435{
16436namespace detail
16437{
16439// serialization //
16441
16443enum class error_handler_t
16444{
16445 strict,
16446 replace,
16447 ignore
16448};
16449
16450template<typename BasicJsonType>
16451class serializer
16452{
16453 using string_t = typename BasicJsonType::string_t;
16454 using number_float_t = typename BasicJsonType::number_float_t;
16455 using number_integer_t = typename BasicJsonType::number_integer_t;
16456 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
16457 using binary_char_t = typename BasicJsonType::binary_t::value_type;
16458 static constexpr std::uint8_t UTF8_ACCEPT = 0;
16459 static constexpr std::uint8_t UTF8_REJECT = 1;
16460
16461 public:
16467 serializer(output_adapter_t<char> s, const char ichar,
16468 error_handler_t error_handler_ = error_handler_t::strict)
16469 : o(std::move(s))
16470 , loc(std::localeconv())
16471 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
16472 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
16473 , indent_char(ichar)
16474 , indent_string(512, indent_char)
16475 , error_handler(error_handler_)
16476 {}
16477
16478 // delete because of pointer members
16479 serializer(const serializer&) = delete;
16480 serializer& operator=(const serializer&) = delete;
16481 serializer(serializer&&) = delete;
16482 serializer& operator=(serializer&&) = delete;
16483 ~serializer() = default;
16484
16507 void dump(const BasicJsonType& val,
16508 const bool pretty_print,
16509 const bool ensure_ascii,
16510 const unsigned int indent_step,
16511 const unsigned int current_indent = 0)
16512 {
16513 switch (val.m_type)
16514 {
16515 case value_t::object:
16516 {
16517 if (val.m_value.object->empty())
16518 {
16519 o->write_characters("{}", 2);
16520 return;
16521 }
16522
16523 if (pretty_print)
16524 {
16525 o->write_characters("{\n", 2);
16526
16527 // variable to hold indentation for recursive calls
16528 const auto new_indent = current_indent + indent_step;
16529 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16530 {
16531 indent_string.resize(indent_string.size() * 2, ' ');
16532 }
16533
16534 // first n-1 elements
16535 auto i = val.m_value.object->cbegin();
16536 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16537 {
16538 o->write_characters(indent_string.c_str(), new_indent);
16539 o->write_character('\"');
16540 dump_escaped(i->first, ensure_ascii);
16541 o->write_characters("\": ", 3);
16542 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16543 o->write_characters(",\n", 2);
16544 }
16545
16546 // last element
16547 JSON_ASSERT(i != val.m_value.object->cend());
16548 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16549 o->write_characters(indent_string.c_str(), new_indent);
16550 o->write_character('\"');
16551 dump_escaped(i->first, ensure_ascii);
16552 o->write_characters("\": ", 3);
16553 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16554
16555 o->write_character('\n');
16556 o->write_characters(indent_string.c_str(), current_indent);
16557 o->write_character('}');
16558 }
16559 else
16560 {
16561 o->write_character('{');
16562
16563 // first n-1 elements
16564 auto i = val.m_value.object->cbegin();
16565 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16566 {
16567 o->write_character('\"');
16568 dump_escaped(i->first, ensure_ascii);
16569 o->write_characters("\":", 2);
16570 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16571 o->write_character(',');
16572 }
16573
16574 // last element
16575 JSON_ASSERT(i != val.m_value.object->cend());
16576 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16577 o->write_character('\"');
16578 dump_escaped(i->first, ensure_ascii);
16579 o->write_characters("\":", 2);
16580 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16581
16582 o->write_character('}');
16583 }
16584
16585 return;
16586 }
16587
16588 case value_t::array:
16589 {
16590 if (val.m_value.array->empty())
16591 {
16592 o->write_characters("[]", 2);
16593 return;
16594 }
16595
16596 if (pretty_print)
16597 {
16598 o->write_characters("[\n", 2);
16599
16600 // variable to hold indentation for recursive calls
16601 const auto new_indent = current_indent + indent_step;
16602 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16603 {
16604 indent_string.resize(indent_string.size() * 2, ' ');
16605 }
16606
16607 // first n-1 elements
16608 for (auto i = val.m_value.array->cbegin();
16609 i != val.m_value.array->cend() - 1; ++i)
16610 {
16611 o->write_characters(indent_string.c_str(), new_indent);
16612 dump(*i, true, ensure_ascii, indent_step, new_indent);
16613 o->write_characters(",\n", 2);
16614 }
16615
16616 // last element
16617 JSON_ASSERT(!val.m_value.array->empty());
16618 o->write_characters(indent_string.c_str(), new_indent);
16619 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
16620
16621 o->write_character('\n');
16622 o->write_characters(indent_string.c_str(), current_indent);
16623 o->write_character(']');
16624 }
16625 else
16626 {
16627 o->write_character('[');
16628
16629 // first n-1 elements
16630 for (auto i = val.m_value.array->cbegin();
16631 i != val.m_value.array->cend() - 1; ++i)
16632 {
16633 dump(*i, false, ensure_ascii, indent_step, current_indent);
16634 o->write_character(',');
16635 }
16636
16637 // last element
16638 JSON_ASSERT(!val.m_value.array->empty());
16639 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
16640
16641 o->write_character(']');
16642 }
16643
16644 return;
16645 }
16646
16647 case value_t::string:
16648 {
16649 o->write_character('\"');
16650 dump_escaped(*val.m_value.string, ensure_ascii);
16651 o->write_character('\"');
16652 return;
16653 }
16654
16655 case value_t::binary:
16656 {
16657 if (pretty_print)
16658 {
16659 o->write_characters("{\n", 2);
16660
16661 // variable to hold indentation for recursive calls
16662 const auto new_indent = current_indent + indent_step;
16663 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16664 {
16665 indent_string.resize(indent_string.size() * 2, ' ');
16666 }
16667
16668 o->write_characters(indent_string.c_str(), new_indent);
16669
16670 o->write_characters("\"bytes\": [", 10);
16671
16672 if (!val.m_value.binary->empty())
16673 {
16674 for (auto i = val.m_value.binary->cbegin();
16675 i != val.m_value.binary->cend() - 1; ++i)
16676 {
16677 dump_integer(*i);
16678 o->write_characters(", ", 2);
16679 }
16680 dump_integer(val.m_value.binary->back());
16681 }
16682
16683 o->write_characters("],\n", 3);
16684 o->write_characters(indent_string.c_str(), new_indent);
16685
16686 o->write_characters("\"subtype\": ", 11);
16687 if (val.m_value.binary->has_subtype())
16688 {
16689 dump_integer(val.m_value.binary->subtype());
16690 }
16691 else
16692 {
16693 o->write_characters("null", 4);
16694 }
16695 o->write_character('\n');
16696 o->write_characters(indent_string.c_str(), current_indent);
16697 o->write_character('}');
16698 }
16699 else
16700 {
16701 o->write_characters("{\"bytes\":[", 10);
16702
16703 if (!val.m_value.binary->empty())
16704 {
16705 for (auto i = val.m_value.binary->cbegin();
16706 i != val.m_value.binary->cend() - 1; ++i)
16707 {
16708 dump_integer(*i);
16709 o->write_character(',');
16710 }
16711 dump_integer(val.m_value.binary->back());
16712 }
16713
16714 o->write_characters("],\"subtype\":", 12);
16715 if (val.m_value.binary->has_subtype())
16716 {
16717 dump_integer(val.m_value.binary->subtype());
16718 o->write_character('}');
16719 }
16720 else
16721 {
16722 o->write_characters("null}", 5);
16723 }
16724 }
16725 return;
16726 }
16727
16728 case value_t::boolean:
16729 {
16730 if (val.m_value.boolean)
16731 {
16732 o->write_characters("true", 4);
16733 }
16734 else
16735 {
16736 o->write_characters("false", 5);
16737 }
16738 return;
16739 }
16740
16741 case value_t::number_integer:
16742 {
16743 dump_integer(val.m_value.number_integer);
16744 return;
16745 }
16746
16747 case value_t::number_unsigned:
16748 {
16749 dump_integer(val.m_value.number_unsigned);
16750 return;
16751 }
16752
16753 case value_t::number_float:
16754 {
16755 dump_float(val.m_value.number_float);
16756 return;
16757 }
16758
16759 case value_t::discarded:
16760 {
16761 o->write_characters("<discarded>", 11);
16762 return;
16763 }
16764
16765 case value_t::null:
16766 {
16767 o->write_characters("null", 4);
16768 return;
16769 }
16770
16771 default: // LCOV_EXCL_LINE
16772 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16773 }
16774 }
16775
16776 JSON_PRIVATE_UNLESS_TESTED:
16791 void dump_escaped(const string_t& s, const bool ensure_ascii)
16792 {
16793 std::uint32_t codepoint{};
16794 std::uint8_t state = UTF8_ACCEPT;
16795 std::size_t bytes = 0; // number of bytes written to string_buffer
16796
16797 // number of bytes written at the point of the last valid byte
16798 std::size_t bytes_after_last_accept = 0;
16799 std::size_t undumped_chars = 0;
16800
16801 for (std::size_t i = 0; i < s.size(); ++i)
16802 {
16803 const auto byte = static_cast<std::uint8_t>(s[i]);
16804
16805 switch (decode(state, codepoint, byte))
16806 {
16807 case UTF8_ACCEPT: // decode found a new code point
16808 {
16809 switch (codepoint)
16810 {
16811 case 0x08: // backspace
16812 {
16813 string_buffer[bytes++] = '\\';
16814 string_buffer[bytes++] = 'b';
16815 break;
16816 }
16817
16818 case 0x09: // horizontal tab
16819 {
16820 string_buffer[bytes++] = '\\';
16821 string_buffer[bytes++] = 't';
16822 break;
16823 }
16824
16825 case 0x0A: // newline
16826 {
16827 string_buffer[bytes++] = '\\';
16828 string_buffer[bytes++] = 'n';
16829 break;
16830 }
16831
16832 case 0x0C: // formfeed
16833 {
16834 string_buffer[bytes++] = '\\';
16835 string_buffer[bytes++] = 'f';
16836 break;
16837 }
16838
16839 case 0x0D: // carriage return
16840 {
16841 string_buffer[bytes++] = '\\';
16842 string_buffer[bytes++] = 'r';
16843 break;
16844 }
16845
16846 case 0x22: // quotation mark
16847 {
16848 string_buffer[bytes++] = '\\';
16849 string_buffer[bytes++] = '\"';
16850 break;
16851 }
16852
16853 case 0x5C: // reverse solidus
16854 {
16855 string_buffer[bytes++] = '\\';
16856 string_buffer[bytes++] = '\\';
16857 break;
16858 }
16859
16860 default:
16861 {
16862 // escape control characters (0x00..0x1F) or, if
16863 // ensure_ascii parameter is used, non-ASCII characters
16864 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
16865 {
16866 if (codepoint <= 0xFFFF)
16867 {
16868 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16869 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
16870 static_cast<std::uint16_t>(codepoint));
16871 bytes += 6;
16872 }
16873 else
16874 {
16875 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16876 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
16877 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
16878 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
16879 bytes += 12;
16880 }
16881 }
16882 else
16883 {
16884 // copy byte to buffer (all previous bytes
16885 // been copied have in default case above)
16886 string_buffer[bytes++] = s[i];
16887 }
16888 break;
16889 }
16890 }
16891
16892 // write buffer and reset index; there must be 13 bytes
16893 // left, as this is the maximal number of bytes to be
16894 // written ("\uxxxx\uxxxx\0") for one code point
16895 if (string_buffer.size() - bytes < 13)
16896 {
16897 o->write_characters(string_buffer.data(), bytes);
16898 bytes = 0;
16899 }
16900
16901 // remember the byte position of this accept
16902 bytes_after_last_accept = bytes;
16903 undumped_chars = 0;
16904 break;
16905 }
16906
16907 case UTF8_REJECT: // decode found invalid UTF-8 byte
16908 {
16909 switch (error_handler)
16910 {
16911 case error_handler_t::strict:
16912 {
16913 std::string sn(9, '\0');
16914 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16915 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
16916 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType()));
16917 }
16918
16919 case error_handler_t::ignore:
16920 case error_handler_t::replace:
16921 {
16922 // in case we saw this character the first time, we
16923 // would like to read it again, because the byte
16924 // may be OK for itself, but just not OK for the
16925 // previous sequence
16926 if (undumped_chars > 0)
16927 {
16928 --i;
16929 }
16930
16931 // reset length buffer to the last accepted index;
16932 // thus removing/ignoring the invalid characters
16933 bytes = bytes_after_last_accept;
16934
16935 if (error_handler == error_handler_t::replace)
16936 {
16937 // add a replacement character
16938 if (ensure_ascii)
16939 {
16940 string_buffer[bytes++] = '\\';
16941 string_buffer[bytes++] = 'u';
16942 string_buffer[bytes++] = 'f';
16943 string_buffer[bytes++] = 'f';
16944 string_buffer[bytes++] = 'f';
16945 string_buffer[bytes++] = 'd';
16946 }
16947 else
16948 {
16949 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
16950 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
16951 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
16952 }
16953
16954 // write buffer and reset index; there must be 13 bytes
16955 // left, as this is the maximal number of bytes to be
16956 // written ("\uxxxx\uxxxx\0") for one code point
16957 if (string_buffer.size() - bytes < 13)
16958 {
16959 o->write_characters(string_buffer.data(), bytes);
16960 bytes = 0;
16961 }
16962
16963 bytes_after_last_accept = bytes;
16964 }
16965
16966 undumped_chars = 0;
16967
16968 // continue processing the string
16969 state = UTF8_ACCEPT;
16970 break;
16971 }
16972
16973 default: // LCOV_EXCL_LINE
16974 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16975 }
16976 break;
16977 }
16978
16979 default: // decode found yet incomplete multi-byte code point
16980 {
16981 if (!ensure_ascii)
16982 {
16983 // code point will not be escaped - copy byte to buffer
16984 string_buffer[bytes++] = s[i];
16985 }
16986 ++undumped_chars;
16987 break;
16988 }
16989 }
16990 }
16991
16992 // we finished processing the string
16993 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
16994 {
16995 // write buffer
16996 if (bytes > 0)
16997 {
16998 o->write_characters(string_buffer.data(), bytes);
16999 }
17000 }
17001 else
17002 {
17003 // we finish reading, but do not accept: string was incomplete
17004 switch (error_handler)
17005 {
17006 case error_handler_t::strict:
17007 {
17008 std::string sn(9, '\0');
17009 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17010 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
17011 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType()));
17012 }
17013
17014 case error_handler_t::ignore:
17015 {
17016 // write all accepted bytes
17017 o->write_characters(string_buffer.data(), bytes_after_last_accept);
17018 break;
17019 }
17020
17021 case error_handler_t::replace:
17022 {
17023 // write all accepted bytes
17024 o->write_characters(string_buffer.data(), bytes_after_last_accept);
17025 // add a replacement character
17026 if (ensure_ascii)
17027 {
17028 o->write_characters("\\ufffd", 6);
17029 }
17030 else
17031 {
17032 o->write_characters("\xEF\xBF\xBD", 3);
17033 }
17034 break;
17035 }
17036
17037 default: // LCOV_EXCL_LINE
17038 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17039 }
17040 }
17041 }
17042
17043 private:
17052 inline unsigned int count_digits(number_unsigned_t x) noexcept
17053 {
17054 unsigned int n_digits = 1;
17055 for (;;)
17056 {
17057 if (x < 10)
17058 {
17059 return n_digits;
17060 }
17061 if (x < 100)
17062 {
17063 return n_digits + 1;
17064 }
17065 if (x < 1000)
17066 {
17067 return n_digits + 2;
17068 }
17069 if (x < 10000)
17070 {
17071 return n_digits + 3;
17072 }
17073 x = x / 10000u;
17074 n_digits += 4;
17075 }
17076 }
17077
17087 template < typename NumberType, detail::enable_if_t <
17088 std::is_integral<NumberType>::value ||
17089 std::is_same<NumberType, number_unsigned_t>::value ||
17090 std::is_same<NumberType, number_integer_t>::value ||
17091 std::is_same<NumberType, binary_char_t>::value,
17092 int > = 0 >
17093 void dump_integer(NumberType x)
17094 {
17095 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
17096 {
17097 {
17098 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
17099 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
17100 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
17101 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
17102 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
17103 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17104 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17105 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17106 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17107 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17108 }
17109 };
17110
17111 // special case for "0"
17112 if (x == 0)
17113 {
17114 o->write_character('0');
17115 return;
17116 }
17117
17118 // use a pointer to fill the buffer
17119 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17120
17121 const bool is_negative = std::is_signed<NumberType>::value && !(x >= 0); // see issue #755
17122 number_unsigned_t abs_value;
17123
17124 unsigned int n_chars{};
17125
17126 if (is_negative)
17127 {
17128 *buffer_ptr = '-';
17129 abs_value = remove_sign(static_cast<number_integer_t>(x));
17130
17131 // account one more byte for the minus sign
17132 n_chars = 1 + count_digits(abs_value);
17133 }
17134 else
17135 {
17136 abs_value = static_cast<number_unsigned_t>(x);
17137 n_chars = count_digits(abs_value);
17138 }
17139
17140 // spare 1 byte for '\0'
17141 JSON_ASSERT(n_chars < number_buffer.size() - 1);
17142
17143 // jump to the end to generate the string from backward
17144 // so we later avoid reversing the result
17145 buffer_ptr += n_chars;
17146
17147 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
17148 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
17149 while (abs_value >= 100)
17150 {
17151 const auto digits_index = static_cast<unsigned>((abs_value % 100));
17152 abs_value /= 100;
17153 *(--buffer_ptr) = digits_to_99[digits_index][1];
17154 *(--buffer_ptr) = digits_to_99[digits_index][0];
17155 }
17156
17157 if (abs_value >= 10)
17158 {
17159 const auto digits_index = static_cast<unsigned>(abs_value);
17160 *(--buffer_ptr) = digits_to_99[digits_index][1];
17161 *(--buffer_ptr) = digits_to_99[digits_index][0];
17162 }
17163 else
17164 {
17165 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
17166 }
17167
17168 o->write_characters(number_buffer.data(), n_chars);
17169 }
17170
17179 void dump_float(number_float_t x)
17180 {
17181 // NaN / inf
17182 if (!std::isfinite(x))
17183 {
17184 o->write_characters("null", 4);
17185 return;
17186 }
17187
17188 // If number_float_t is an IEEE-754 single or double precision number,
17189 // use the Grisu2 algorithm to produce short numbers which are
17190 // guaranteed to round-trip, using strtof and strtod, resp.
17191 //
17192 // NB: The test below works if <long double> == <double>.
17193 static constexpr bool is_ieee_single_or_double
17194 = (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) ||
17195 (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);
17196
17197 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
17198 }
17199
17200 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
17201 {
17202 auto* begin = number_buffer.data();
17203 auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
17204
17205 o->write_characters(begin, static_cast<size_t>(end - begin));
17206 }
17207
17208 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
17209 {
17210 // get number of digits for a float -> text -> float round-trip
17211 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
17212
17213 // the actual conversion
17214 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17215 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
17216
17217 // negative value indicates an error
17218 JSON_ASSERT(len > 0);
17219 // check if buffer was large enough
17220 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
17221
17222 // erase thousands separator
17223 if (thousands_sep != '\0')
17224 {
17225 auto* const end = std::remove(number_buffer.begin(),
17226 number_buffer.begin() + len, thousands_sep);
17227 std::fill(end, number_buffer.end(), '\0');
17228 JSON_ASSERT((end - number_buffer.begin()) <= len);
17229 len = (end - number_buffer.begin());
17230 }
17231
17232 // convert decimal point to '.'
17233 if (decimal_point != '\0' && decimal_point != '.')
17234 {
17235 auto* const dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
17236 if (dec_pos != number_buffer.end())
17237 {
17238 *dec_pos = '.';
17239 }
17240 }
17241
17242 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
17243
17244 // determine if need to append ".0"
17245 const bool value_is_int_like =
17246 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
17247 [](char c)
17248 {
17249 return c == '.' || c == 'e';
17250 });
17251
17252 if (value_is_int_like)
17253 {
17254 o->write_characters(".0", 2);
17255 }
17256 }
17257
17279 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
17280 {
17281 static const std::array<std::uint8_t, 400> utf8d =
17282 {
17283 {
17284 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
17285 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
17286 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
17287 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
17288 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
17289 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
17290 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
17291 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
17292 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
17293 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
17294 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
17295 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
17296 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
17297 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
17298 }
17299 };
17300
17301 JSON_ASSERT(byte < utf8d.size());
17302 const std::uint8_t type = utf8d[byte];
17303
17304 codep = (state != UTF8_ACCEPT)
17305 ? (byte & 0x3fu) | (codep << 6u)
17306 : (0xFFu >> type) & (byte);
17307
17308 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
17309 JSON_ASSERT(index < 400);
17310 state = utf8d[index];
17311 return state;
17312 }
17313
17314 /*
17315 * Overload to make the compiler happy while it is instantiating
17316 * dump_integer for number_unsigned_t.
17317 * Must never be called.
17318 */
17319 number_unsigned_t remove_sign(number_unsigned_t x)
17320 {
17321 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17322 return x; // LCOV_EXCL_LINE
17323 }
17324
17325 /*
17326 * Helper function for dump_integer
17327 *
17328 * This function takes a negative signed integer and returns its absolute
17329 * value as unsigned integer. The plus/minus shuffling is necessary as we can
17330 * not directly remove the sign of an arbitrary signed integer as the
17331 * absolute values of INT_MIN and INT_MAX are usually not the same. See
17332 * #1708 for details.
17333 */
17334 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
17335 {
17336 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
17337 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
17338 }
17339
17340 private:
17342 output_adapter_t<char> o = nullptr;
17343
17345 std::array<char, 64> number_buffer{{}};
17346
17348 const std::lconv* loc = nullptr;
17350 const char thousands_sep = '\0';
17352 const char decimal_point = '\0';
17353
17355 std::array<char, 512> string_buffer{{}};
17356
17358 const char indent_char;
17360 string_t indent_string;
17361
17363 const error_handler_t error_handler;
17364};
17365} // namespace detail
17366} // namespace nlohmann
17367
17368// #include <nlohmann/detail/value_t.hpp>
17369
17370// #include <nlohmann/json_fwd.hpp>
17371
17372// #include <nlohmann/ordered_map.hpp>
17373
17374
17375#include <functional> // less
17376#include <initializer_list> // initializer_list
17377#include <iterator> // input_iterator_tag, iterator_traits
17378#include <memory> // allocator
17379#include <stdexcept> // for out_of_range
17380#include <type_traits> // enable_if, is_convertible
17381#include <utility> // pair
17382#include <vector> // vector
17383
17384// #include <nlohmann/detail/macro_scope.hpp>
17385
17386
17387namespace nlohmann
17388{
17389
17392template <class Key, class T, class IgnoredLess = std::less<Key>,
17393 class Allocator = std::allocator<std::pair<const Key, T>>>
17394 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
17395{
17396 using key_type = Key;
17397 using mapped_type = T;
17398 using Container = std::vector<std::pair<const Key, T>, Allocator>;
17399 using typename Container::iterator;
17400 using typename Container::const_iterator;
17401 using typename Container::size_type;
17402 using typename Container::value_type;
17403
17404 // Explicit constructors instead of `using Container::Container`
17405 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
17406 ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
17407 template <class It>
17408 ordered_map(It first, It last, const Allocator& alloc = Allocator())
17409 : Container{first, last, alloc} {}
17410 ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
17411 : Container{init, alloc} {}
17412
17413 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
17414 {
17415 for (auto it = this->begin(); it != this->end(); ++it)
17416 {
17417 if (it->first == key)
17418 {
17419 return {it, false};
17420 }
17421 }
17422 Container::emplace_back(key, t);
17423 return {--this->end(), true};
17424 }
17425
17426 T& operator[](const Key& key)
17427 {
17428 return emplace(key, T{}).first->second;
17429 }
17430
17431 const T& operator[](const Key& key) const
17432 {
17433 return at(key);
17434 }
17435
17436 T& at(const Key& key)
17437 {
17438 for (auto it = this->begin(); it != this->end(); ++it)
17439 {
17440 if (it->first == key)
17441 {
17442 return it->second;
17443 }
17444 }
17445
17446 JSON_THROW(std::out_of_range("key not found"));
17447 }
17448
17449 const T& at(const Key& key) const
17450 {
17451 for (auto it = this->begin(); it != this->end(); ++it)
17452 {
17453 if (it->first == key)
17454 {
17455 return it->second;
17456 }
17457 }
17458
17459 JSON_THROW(std::out_of_range("key not found"));
17460 }
17461
17462 size_type erase(const Key& key)
17463 {
17464 for (auto it = this->begin(); it != this->end(); ++it)
17465 {
17466 if (it->first == key)
17467 {
17468 // Since we cannot move const Keys, re-construct them in place
17469 for (auto next = it; ++next != this->end(); ++it)
17470 {
17471 it->~value_type(); // Destroy but keep allocation
17472 new (&*it) value_type{std::move(*next)};
17473 }
17474 Container::pop_back();
17475 return 1;
17476 }
17477 }
17478 return 0;
17479 }
17480
17481 iterator erase(iterator pos)
17482 {
17483 auto it = pos;
17484
17485 // Since we cannot move const Keys, re-construct them in place
17486 for (auto next = it; ++next != this->end(); ++it)
17487 {
17488 it->~value_type(); // Destroy but keep allocation
17489 new (&*it) value_type{std::move(*next)};
17490 }
17491 Container::pop_back();
17492 return pos;
17493 }
17494
17495 size_type count(const Key& key) const
17496 {
17497 for (auto it = this->begin(); it != this->end(); ++it)
17498 {
17499 if (it->first == key)
17500 {
17501 return 1;
17502 }
17503 }
17504 return 0;
17505 }
17506
17507 iterator find(const Key& key)
17508 {
17509 for (auto it = this->begin(); it != this->end(); ++it)
17510 {
17511 if (it->first == key)
17512 {
17513 return it;
17514 }
17515 }
17516 return Container::end();
17517 }
17518
17519 const_iterator find(const Key& key) const
17520 {
17521 for (auto it = this->begin(); it != this->end(); ++it)
17522 {
17523 if (it->first == key)
17524 {
17525 return it;
17526 }
17527 }
17528 return Container::end();
17529 }
17530
17531 std::pair<iterator, bool> insert( value_type&& value )
17532 {
17533 return emplace(value.first, std::move(value.second));
17534 }
17535
17536 std::pair<iterator, bool> insert( const value_type& value )
17537 {
17538 for (auto it = this->begin(); it != this->end(); ++it)
17539 {
17540 if (it->first == value.first)
17541 {
17542 return {it, false};
17543 }
17544 }
17545 Container::push_back(value);
17546 return {--this->end(), true};
17547 }
17548
17549 template<typename InputIt>
17550 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
17551 std::input_iterator_tag>::value>::type;
17552
17553 template<typename InputIt, typename = require_input_iter<InputIt>>
17554 void insert(InputIt first, InputIt last)
17555 {
17556 for (auto it = first; it != last; ++it)
17557 {
17558 insert(*it);
17559 }
17560 }
17561};
17562
17563} // namespace nlohmann
17564
17565
17566#if defined(JSON_HAS_CPP_17)
17567 #include <string_view>
17568#endif
17569
17575namespace nlohmann
17576{
17577
17662NLOHMANN_BASIC_JSON_TPL_DECLARATION
17663class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
17664{
17665 private:
17666 template<detail::value_t> friend struct detail::external_constructor;
17667 friend ::nlohmann::json_pointer<basic_json>;
17668
17669 template<typename BasicJsonType, typename InputType>
17670 friend class ::nlohmann::detail::parser;
17671 friend ::nlohmann::detail::serializer<basic_json>;
17672 template<typename BasicJsonType>
17673 friend class ::nlohmann::detail::iter_impl;
17674 template<typename BasicJsonType, typename CharType>
17675 friend class ::nlohmann::detail::binary_writer;
17676 template<typename BasicJsonType, typename InputType, typename SAX>
17677 friend class ::nlohmann::detail::binary_reader;
17678 template<typename BasicJsonType>
17679 friend class ::nlohmann::detail::json_sax_dom_parser;
17680 template<typename BasicJsonType>
17681 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
17682 friend class ::nlohmann::detail::exception;
17683
17685 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
17686
17687 JSON_PRIVATE_UNLESS_TESTED:
17688 // convenience aliases for types residing in namespace detail;
17689 using lexer = ::nlohmann::detail::lexer_base<basic_json>;
17690
17691 template<typename InputAdapterType>
17692 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
17693 InputAdapterType adapter,
17694 detail::parser_callback_t<basic_json>cb = nullptr,
17695 const bool allow_exceptions = true,
17696 const bool ignore_comments = false
17697 )
17698 {
17699 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
17700 std::move(cb), allow_exceptions, ignore_comments);
17701 }
17702
17703 private:
17704 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
17705 template<typename BasicJsonType>
17706 using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
17707 template<typename BasicJsonType>
17708 using iter_impl = ::nlohmann::detail::iter_impl<BasicJsonType>;
17709 template<typename Iterator>
17710 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
17711 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
17712
17713 template<typename CharType>
17714 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
17715
17716 template<typename InputType>
17717 using binary_reader = ::nlohmann::detail::binary_reader<basic_json, InputType>;
17718 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
17719
17720 JSON_PRIVATE_UNLESS_TESTED:
17721 using serializer = ::nlohmann::detail::serializer<basic_json>;
17722
17723 public:
17724 using value_t = detail::value_t;
17727 template<typename T, typename SFINAE>
17728 using json_serializer = JSONSerializer<T, SFINAE>;
17730 using error_handler_t = detail::error_handler_t;
17732 using cbor_tag_handler_t = detail::cbor_tag_handler_t;
17734 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
17735
17736 using input_format_t = detail::input_format_t;
17739
17741 // exceptions //
17743
17747
17749 using exception = detail::exception;
17751 using parse_error = detail::parse_error;
17753 using invalid_iterator = detail::invalid_iterator;
17755 using type_error = detail::type_error;
17757 using out_of_range = detail::out_of_range;
17759 using other_error = detail::other_error;
17760
17762
17763
17765 // container types //
17767
17772
17775
17780
17782 using difference_type = std::ptrdiff_t;
17784 using size_type = std::size_t;
17785
17787 using allocator_type = AllocatorType<basic_json>;
17788
17790 using pointer = typename std::allocator_traits<allocator_type>::pointer;
17792 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
17793
17795 using iterator = iter_impl<basic_json>;
17797 using const_iterator = iter_impl<const basic_json>;
17799 using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>;
17801 using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>;
17802
17804
17805
17810 {
17811 return allocator_type();
17812 }
17813
17840
17842 {
17843 basic_json result;
17844
17845 result["copyright"] = "(C) 2013-2021 Niels Lohmann";
17846 result["name"] = "JSON for Modern C++";
17847 result["url"] = "https://github.com/nlohmann/json";
17848 result["version"]["string"] =
17849 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
17850 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
17851 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
17852 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
17853 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
17854 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
17855
17856#ifdef _WIN32
17857 result["platform"] = "win32";
17858#elif defined __linux__
17859 result["platform"] = "linux";
17860#elif defined __APPLE__
17861 result["platform"] = "apple";
17862#elif defined __unix__
17863 result["platform"] = "unix";
17864#else
17865 result["platform"] = "unknown";
17866#endif
17867
17868#if defined(__ICC) || defined(__INTEL_COMPILER)
17869 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
17870#elif defined(__clang__)
17871 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
17872#elif defined(__GNUC__) || defined(__GNUG__)
17873 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
17874#elif defined(__HP_cc) || defined(__HP_aCC)
17875 result["compiler"] = "hp"
17876#elif defined(__IBMCPP__)
17877 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
17878#elif defined(_MSC_VER)
17879 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
17880#elif defined(__PGI)
17881 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
17882#elif defined(__SUNPRO_CC)
17883 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
17884#else
17885 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
17886#endif
17887
17888#ifdef __cplusplus
17889 result["compiler"]["c++"] = std::to_string(__cplusplus);
17890#else
17891 result["compiler"]["c++"] = "unknown";
17892#endif
17893 return result;
17894 }
17895
17896
17898 // JSON value data types //
17900
17905
17906#if defined(JSON_HAS_CPP_14)
17907 // Use transparent comparator if possible, combined with perfect forwarding
17908 // on find() and count() calls prevents unnecessary string construction.
17909 using object_comparator_t = std::less<>;
17910#else
17911 using object_comparator_t = std::less<StringType>;
17912#endif
17913
17997 using object_t = ObjectType<StringType,
17998 basic_json,
18000 AllocatorType<std::pair<const StringType,
18001 basic_json>>>;
18002
18047 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
18048
18100 using string_t = StringType;
18101
18126 using boolean_t = BooleanType;
18127
18198 using number_integer_t = NumberIntegerType;
18199
18269 using number_unsigned_t = NumberUnsignedType;
18270
18337 using number_float_t = NumberFloatType;
18338
18410
18411 private:
18412
18414 template<typename T, typename... Args>
18415
18416 static T* create(Args&& ... args)
18417 {
18418 AllocatorType<T> alloc;
18419 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18420
18421 auto deleter = [&](T * obj)
18422 {
18423 AllocatorTraits::deallocate(alloc, obj, 1);
18424 };
18425 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18426 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18427 JSON_ASSERT(obj != nullptr);
18428 return obj.release();
18429 }
18430
18432 // JSON value storage //
18434
18435 JSON_PRIVATE_UNLESS_TESTED:
18461 union json_value
18462 {
18466 array_t* array;
18468 string_t* string;
18470 binary_t* binary;
18472 boolean_t boolean;
18474 number_integer_t number_integer;
18476 number_unsigned_t number_unsigned;
18478 number_float_t number_float;
18479
18481 json_value() = default;
18483 json_value(boolean_t v) noexcept : boolean(v) {}
18485 json_value(number_integer_t v) noexcept : number_integer(v) {}
18487 json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
18489 json_value(number_float_t v) noexcept : number_float(v) {}
18491 json_value(value_t t)
18492 {
18493 switch (t)
18494 {
18495 case value_t::object:
18496 {
18497 object = create<object_t>();
18498 break;
18499 }
18500
18501 case value_t::array:
18502 {
18503 array = create<array_t>();
18504 break;
18505 }
18506
18507 case value_t::string:
18508 {
18509 string = create<string_t>("");
18510 break;
18511 }
18512
18513 case value_t::binary:
18514 {
18515 binary = create<binary_t>();
18516 break;
18517 }
18518
18519 case value_t::boolean:
18520 {
18521 boolean = boolean_t(false);
18522 break;
18523 }
18524
18525 case value_t::number_integer:
18526 {
18527 number_integer = number_integer_t(0);
18528 break;
18529 }
18530
18531 case value_t::number_unsigned:
18532 {
18533 number_unsigned = number_unsigned_t(0);
18534 break;
18535 }
18536
18537 case value_t::number_float:
18538 {
18539 number_float = number_float_t(0.0);
18540 break;
18541 }
18542
18543 case value_t::null:
18544 {
18545 object = nullptr; // silence warning, see #821
18546 break;
18547 }
18548
18549 case value_t::discarded:
18550 default:
18551 {
18552 object = nullptr; // silence warning, see #821
18553 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
18554 {
18555 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.3", basic_json())); // LCOV_EXCL_LINE
18556 }
18557 break;
18558 }
18559 }
18560 }
18561
18563 json_value(const string_t& value)
18564 {
18565 string = create<string_t>(value);
18566 }
18567
18569 json_value(string_t&& value)
18570 {
18571 string = create<string_t>(std::move(value));
18572 }
18573
18575 json_value(const object_t& value)
18576 {
18577 object = create<object_t>(value);
18578 }
18579
18581 json_value(object_t&& value)
18582 {
18583 object = create<object_t>(std::move(value));
18584 }
18585
18587 json_value(const array_t& value)
18588 {
18589 array = create<array_t>(value);
18590 }
18591
18593 json_value(array_t&& value)
18594 {
18595 array = create<array_t>(std::move(value));
18596 }
18597
18599 json_value(const typename binary_t::container_type& value)
18600 {
18601 binary = create<binary_t>(value);
18602 }
18603
18605 json_value(typename binary_t::container_type&& value)
18606 {
18607 binary = create<binary_t>(std::move(value));
18608 }
18609
18611 json_value(const binary_t& value)
18612 {
18613 binary = create<binary_t>(value);
18614 }
18615
18617 json_value(binary_t&& value)
18618 {
18619 binary = create<binary_t>(std::move(value));
18620 }
18621
18622 void destroy(value_t t)
18623 {
18624 if (t == value_t::array || t == value_t::object)
18625 {
18626 // flatten the current json_value to a heap-allocated stack
18627 std::vector<basic_json> stack;
18628
18629 // move the top-level items to stack
18630 if (t == value_t::array)
18631 {
18632 stack.reserve(array->size());
18633 std::move(array->begin(), array->end(), std::back_inserter(stack));
18634 }
18635 else
18636 {
18637 stack.reserve(object->size());
18638 for (auto&& it : *object)
18639 {
18640 stack.push_back(std::move(it.second));
18641 }
18642 }
18643
18644 while (!stack.empty())
18645 {
18646 // move the last item to local variable to be processed
18647 basic_json current_item(std::move(stack.back()));
18648 stack.pop_back();
18649
18650 // if current_item is array/object, move
18651 // its children to the stack to be processed later
18652 if (current_item.is_array())
18653 {
18654 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
18655
18656 current_item.m_value.array->clear();
18657 }
18658 else if (current_item.is_object())
18659 {
18660 for (auto&& it : *current_item.m_value.object)
18661 {
18662 stack.push_back(std::move(it.second));
18663 }
18664
18665 current_item.m_value.object->clear();
18666 }
18667
18668 // it's now safe that current_item get destructed
18669 // since it doesn't have any children
18670 }
18671 }
18672
18673 switch (t)
18674 {
18675 case value_t::object:
18676 {
18677 AllocatorType<object_t> alloc;
18678 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18679 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18680 break;
18681 }
18682
18683 case value_t::array:
18684 {
18685 AllocatorType<array_t> alloc;
18686 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18687 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18688 break;
18689 }
18690
18691 case value_t::string:
18692 {
18693 AllocatorType<string_t> alloc;
18694 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18695 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18696 break;
18697 }
18698
18699 case value_t::binary:
18700 {
18701 AllocatorType<binary_t> alloc;
18702 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18703 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18704 break;
18705 }
18706
18707 case value_t::null:
18708 case value_t::boolean:
18709 case value_t::number_integer:
18710 case value_t::number_unsigned:
18711 case value_t::number_float:
18712 case value_t::discarded:
18713 default:
18714 {
18715 break;
18716 }
18717 }
18718 }
18719 };
18720
18721 private:
18740 void assert_invariant(bool check_parents = true) const noexcept
18741 {
18742 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18743 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18744 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18745 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18746
18747#if JSON_DIAGNOSTICS
18748 JSON_TRY
18749 {
18750 // cppcheck-suppress assertWithSideEffect
18751 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
18752 {
18753 return j.m_parent == this;
18754 }));
18755 }
18756 JSON_CATCH(...) {} // LCOV_EXCL_LINE
18757#endif
18758 static_cast<void>(check_parents);
18759 }
18760
18761 void set_parents()
18762 {
18763#if JSON_DIAGNOSTICS
18764 switch (m_type)
18765 {
18766 case value_t::array:
18767 {
18768 for (auto& element : *m_value.array)
18769 {
18770 element.m_parent = this;
18771 }
18772 break;
18773 }
18774
18775 case value_t::object:
18776 {
18777 for (auto& element : *m_value.object)
18778 {
18779 element.second.m_parent = this;
18780 }
18781 break;
18782 }
18783
18784 case value_t::null:
18785 case value_t::string:
18786 case value_t::boolean:
18787 case value_t::number_integer:
18788 case value_t::number_unsigned:
18789 case value_t::number_float:
18790 case value_t::binary:
18791 case value_t::discarded:
18792 default:
18793 break;
18794 }
18795#endif
18796 }
18797
18798 iterator set_parents(iterator it, typename iterator::difference_type count)
18799 {
18800#if JSON_DIAGNOSTICS
18801 for (typename iterator::difference_type i = 0; i < count; ++i)
18802 {
18803 (it + i)->m_parent = this;
18804 }
18805#else
18806 static_cast<void>(count);
18807#endif
18808 return it;
18809 }
18810
18811 reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1))
18812 {
18813#if JSON_DIAGNOSTICS
18814 if (old_capacity != std::size_t(-1))
18815 {
18816 // see https://github.com/nlohmann/json/issues/2838
18817 JSON_ASSERT(type() == value_t::array);
18818 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
18819 {
18820 // capacity has changed: update all parents
18821 set_parents();
18822 return j;
18823 }
18824 }
18825
18826 // ordered_json uses a vector internally, so pointers could have
18827 // been invalidated; see https://github.com/nlohmann/json/issues/2962
18828#ifdef JSON_HEDLEY_MSVC_VERSION
18829#pragma warning(push )
18830#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
18831#endif
18832 if (detail::is_ordered_map<object_t>::value)
18833 {
18834 set_parents();
18835 return j;
18836 }
18837#ifdef JSON_HEDLEY_MSVC_VERSION
18838#pragma warning( pop )
18839#endif
18840
18841 j.m_parent = this;
18842#else
18843 static_cast<void>(j);
18844 static_cast<void>(old_capacity);
18845#endif
18846 return j;
18847 }
18848
18849 public:
18851 // JSON parser callback //
18853
18869 using parse_event_t = detail::parse_event_t;
18870
18920 using parser_callback_t = detail::parser_callback_t<basic_json>;
18921
18923 // constructors //
18925
18930
18961 basic_json(const value_t v)
18962 : m_type(v), m_value(v)
18963 {
18964 assert_invariant();
18965 }
18966
18985 basic_json(std::nullptr_t = nullptr) noexcept
18986 : basic_json(value_t::null)
18987 {
18988 assert_invariant();
18989 }
18990
19053 template < typename CompatibleType,
19054 typename U = detail::uncvref_t<CompatibleType>,
19055 detail::enable_if_t <
19056 !detail::is_basic_json<U>::value && detail::is_compatible_type<basic_json_t, U>::value, int > = 0 >
19057 basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
19058 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
19059 std::forward<CompatibleType>(val))))
19060 {
19061 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
19062 set_parents();
19063 assert_invariant();
19064 }
19065
19092 template < typename BasicJsonType,
19093 detail::enable_if_t <
19094 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
19095 basic_json(const BasicJsonType& val)
19096 {
19097 using other_boolean_t = typename BasicJsonType::boolean_t;
19098 using other_number_float_t = typename BasicJsonType::number_float_t;
19099 using other_number_integer_t = typename BasicJsonType::number_integer_t;
19100 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
19101 using other_string_t = typename BasicJsonType::string_t;
19102 using other_object_t = typename BasicJsonType::object_t;
19103 using other_array_t = typename BasicJsonType::array_t;
19104 using other_binary_t = typename BasicJsonType::binary_t;
19105
19106 switch (val.type())
19107 {
19108 case value_t::boolean:
19109 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
19110 break;
19111 case value_t::number_float:
19112 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
19113 break;
19114 case value_t::number_integer:
19115 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
19116 break;
19117 case value_t::number_unsigned:
19118 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
19119 break;
19120 case value_t::string:
19121 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
19122 break;
19123 case value_t::object:
19124 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
19125 break;
19126 case value_t::array:
19127 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
19128 break;
19129 case value_t::binary:
19130 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
19131 break;
19132 case value_t::null:
19133 *this = nullptr;
19134 break;
19135 case value_t::discarded:
19136 m_type = value_t::discarded;
19137 break;
19138 default: // LCOV_EXCL_LINE
19139 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19140 }
19141 set_parents();
19142 assert_invariant();
19143 }
19144
19220 bool type_deduction = true,
19221 value_t manual_type = value_t::array)
19222 {
19223 // check if each element is an array with two elements whose first
19224 // element is a string
19225 bool is_an_object = std::all_of(init.begin(), init.end(),
19226 [](const detail::json_ref<basic_json>& element_ref)
19227 {
19228 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19229 });
19230
19231 // adjust type if type deduction is not wanted
19232 if (!type_deduction)
19233 {
19234 // if array is wanted, do not create an object though possible
19235 if (manual_type == value_t::array)
19236 {
19237 is_an_object = false;
19238 }
19239
19240 // if object is wanted but impossible, throw an exception
19241 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19242 {
19243 JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
19244 }
19245 }
19246
19247 if (is_an_object)
19248 {
19249 // the initializer list is a list of pairs -> create object
19250 m_type = value_t::object;
19251 m_value = value_t::object;
19252
19253 for (auto& element_ref : init)
19254 {
19255 auto element = element_ref.moved_or_copied();
19256 m_value.object->emplace(
19257 std::move(*((*element.m_value.array)[0].m_value.string)),
19258 std::move((*element.m_value.array)[1]));
19259 }
19260 }
19261 else
19262 {
19263 // the initializer list describes an array -> create array
19264 m_type = value_t::array;
19265 m_value.array = create<array_t>(init.begin(), init.end());
19266 }
19267
19268 set_parents();
19269 assert_invariant();
19270 }
19271
19299
19300 static basic_json binary(const typename binary_t::container_type& init)
19301 {
19302 auto res = basic_json();
19303 res.m_type = value_t::binary;
19304 res.m_value = init;
19305 return res;
19306 }
19307
19336
19337 static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
19338 {
19339 auto res = basic_json();
19340 res.m_type = value_t::binary;
19341 res.m_value = binary_t(init, subtype);
19342 return res;
19343 }
19344
19346
19348 {
19349 auto res = basic_json();
19350 res.m_type = value_t::binary;
19351 res.m_value = std::move(init);
19352 return res;
19353 }
19354
19356
19357 static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
19358 {
19359 auto res = basic_json();
19360 res.m_type = value_t::binary;
19361 res.m_value = binary_t(std::move(init), subtype);
19362 return res;
19363 }
19364
19402
19404 {
19405 return basic_json(init, false, value_t::array);
19406 }
19407
19446
19448 {
19449 return basic_json(init, false, value_t::object);
19450 }
19451
19475 : m_type(value_t::array)
19476 {
19477 m_value.array = create<array_t>(cnt, val);
19478 set_parents();
19479 assert_invariant();
19480 }
19481
19537 template < class InputIT, typename std::enable_if <
19538 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19539 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19540 basic_json(InputIT first, InputIT last)
19541 {
19542 JSON_ASSERT(first.m_object != nullptr);
19543 JSON_ASSERT(last.m_object != nullptr);
19544
19545 // make sure iterator fits the current value
19546 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19547 {
19548 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
19549 }
19550
19551 // copy type from first iterator
19552 m_type = first.m_object->m_type;
19553
19554 // check if iterator range is complete for primitive values
19555 switch (m_type)
19556 {
19557 case value_t::boolean:
19558 case value_t::number_float:
19559 case value_t::number_integer:
19560 case value_t::number_unsigned:
19561 case value_t::string:
19562 {
19563 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19564 || !last.m_it.primitive_iterator.is_end()))
19565 {
19566 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
19567 }
19568 break;
19569 }
19570
19571 case value_t::null:
19572 case value_t::object:
19573 case value_t::array:
19574 case value_t::binary:
19575 case value_t::discarded:
19576 default:
19577 break;
19578 }
19579
19580 switch (m_type)
19581 {
19582 case value_t::number_integer:
19583 {
19584 m_value.number_integer = first.m_object->m_value.number_integer;
19585 break;
19586 }
19587
19588 case value_t::number_unsigned:
19589 {
19590 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19591 break;
19592 }
19593
19594 case value_t::number_float:
19595 {
19596 m_value.number_float = first.m_object->m_value.number_float;
19597 break;
19598 }
19599
19600 case value_t::boolean:
19601 {
19602 m_value.boolean = first.m_object->m_value.boolean;
19603 break;
19604 }
19605
19606 case value_t::string:
19607 {
19608 m_value = *first.m_object->m_value.string;
19609 break;
19610 }
19611
19612 case value_t::object:
19613 {
19614 m_value.object = create<object_t>(first.m_it.object_iterator,
19615 last.m_it.object_iterator);
19616 break;
19617 }
19618
19619 case value_t::array:
19620 {
19621 m_value.array = create<array_t>(first.m_it.array_iterator,
19622 last.m_it.array_iterator);
19623 break;
19624 }
19625
19626 case value_t::binary:
19627 {
19628 m_value = *first.m_object->m_value.binary;
19629 break;
19630 }
19631
19632 case value_t::null:
19633 case value_t::discarded:
19634 default:
19635 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
19636 }
19637
19638 set_parents();
19639 assert_invariant();
19640 }
19641
19642
19644 // other constructors and destructor //
19646
19647 template<typename JsonRef,
19648 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
19649 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19650 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19651
19678 : m_type(other.m_type)
19679 {
19680 // check of passed value is valid
19681 other.assert_invariant();
19682
19683 switch (m_type)
19684 {
19685 case value_t::object:
19686 {
19687 m_value = *other.m_value.object;
19688 break;
19689 }
19690
19691 case value_t::array:
19692 {
19693 m_value = *other.m_value.array;
19694 break;
19695 }
19696
19697 case value_t::string:
19698 {
19699 m_value = *other.m_value.string;
19700 break;
19701 }
19702
19703 case value_t::boolean:
19704 {
19705 m_value = other.m_value.boolean;
19706 break;
19707 }
19708
19709 case value_t::number_integer:
19710 {
19711 m_value = other.m_value.number_integer;
19712 break;
19713 }
19714
19715 case value_t::number_unsigned:
19716 {
19717 m_value = other.m_value.number_unsigned;
19718 break;
19719 }
19720
19721 case value_t::number_float:
19722 {
19723 m_value = other.m_value.number_float;
19724 break;
19725 }
19726
19727 case value_t::binary:
19728 {
19729 m_value = *other.m_value.binary;
19730 break;
19731 }
19732
19733 case value_t::null:
19734 case value_t::discarded:
19735 default:
19736 break;
19737 }
19738
19739 set_parents();
19740 assert_invariant();
19741 }
19742
19769 basic_json(basic_json&& other) noexcept
19770 : m_type(std::move(other.m_type)),
19771 m_value(std::move(other.m_value))
19772 {
19773 // check that passed value is valid
19774 other.assert_invariant(false);
19775
19776 // invalidate payload
19777 other.m_type = value_t::null;
19778 other.m_value = {};
19779
19780 set_parents();
19781 assert_invariant();
19782 }
19783
19808 std::is_nothrow_move_constructible<value_t>::value&&
19809 std::is_nothrow_move_assignable<value_t>::value&&
19810 std::is_nothrow_move_constructible<json_value>::value&&
19811 std::is_nothrow_move_assignable<json_value>::value
19812 )
19813 {
19814 // check that passed value is valid
19815 other.assert_invariant();
19816
19817 using std::swap;
19818 swap(m_type, other.m_type);
19819 swap(m_value, other.m_value);
19820
19821 set_parents();
19822 assert_invariant();
19823 return *this;
19824 }
19825
19841 ~basic_json() noexcept
19842 {
19843 assert_invariant(false);
19844 m_value.destroy(m_type);
19845 }
19846
19848
19849 public:
19851 // object inspection //
19853
19857
19905 string_t dump(const int indent = -1,
19906 const char indent_char = ' ',
19907 const bool ensure_ascii = false,
19908 const error_handler_t error_handler = error_handler_t::strict) const
19909 {
19910 string_t result;
19911 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19912
19913 if (indent >= 0)
19914 {
19915 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19916 }
19917 else
19918 {
19919 s.dump(*this, false, ensure_ascii, 0);
19920 }
19921
19922 return result;
19923 }
19924
19958 constexpr value_t type() const noexcept
19959 {
19960 return m_type;
19961 }
19962
19989 constexpr bool is_primitive() const noexcept
19990 {
19991 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
19992 }
19993
20016 constexpr bool is_structured() const noexcept
20017 {
20018 return is_array() || is_object();
20019 }
20020
20038 constexpr bool is_null() const noexcept
20039 {
20040 return m_type == value_t::null;
20041 }
20042
20060 constexpr bool is_boolean() const noexcept
20061 {
20062 return m_type == value_t::boolean;
20063 }
20064
20090 constexpr bool is_number() const noexcept
20091 {
20092 return is_number_integer() || is_number_float();
20093 }
20094
20119 constexpr bool is_number_integer() const noexcept
20120 {
20121 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
20122 }
20123
20147 constexpr bool is_number_unsigned() const noexcept
20148 {
20149 return m_type == value_t::number_unsigned;
20150 }
20151
20175 constexpr bool is_number_float() const noexcept
20176 {
20177 return m_type == value_t::number_float;
20178 }
20179
20197 constexpr bool is_object() const noexcept
20198 {
20199 return m_type == value_t::object;
20200 }
20201
20219 constexpr bool is_array() const noexcept
20220 {
20221 return m_type == value_t::array;
20222 }
20223
20241 constexpr bool is_string() const noexcept
20242 {
20243 return m_type == value_t::string;
20244 }
20245
20263 constexpr bool is_binary() const noexcept
20264 {
20265 return m_type == value_t::binary;
20266 }
20267
20290 constexpr bool is_discarded() const noexcept
20291 {
20292 return m_type == value_t::discarded;
20293 }
20294
20316 constexpr operator value_t() const noexcept
20317 {
20318 return m_type;
20319 }
20320
20322
20323 private:
20325 // value access //
20327
20329 boolean_t get_impl(boolean_t* /*unused*/) const
20330 {
20331 if (JSON_HEDLEY_LIKELY(is_boolean()))
20332 {
20333 return m_value.boolean;
20334 }
20335
20336 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
20337 }
20338
20340 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20341 {
20342 return is_object() ? m_value.object : nullptr;
20343 }
20344
20346 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20347 {
20348 return is_object() ? m_value.object : nullptr;
20349 }
20350
20352 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20353 {
20354 return is_array() ? m_value.array : nullptr;
20355 }
20356
20358 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20359 {
20360 return is_array() ? m_value.array : nullptr;
20361 }
20362
20364 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20365 {
20366 return is_string() ? m_value.string : nullptr;
20367 }
20368
20370 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20371 {
20372 return is_string() ? m_value.string : nullptr;
20373 }
20374
20376 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20377 {
20378 return is_boolean() ? &m_value.boolean : nullptr;
20379 }
20380
20382 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20383 {
20384 return is_boolean() ? &m_value.boolean : nullptr;
20385 }
20386
20388 number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
20389 {
20390 return is_number_integer() ? &m_value.number_integer : nullptr;
20391 }
20392
20394 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20395 {
20396 return is_number_integer() ? &m_value.number_integer : nullptr;
20397 }
20398
20400 number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
20401 {
20402 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20403 }
20404
20406 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20407 {
20408 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20409 }
20410
20412 number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
20413 {
20414 return is_number_float() ? &m_value.number_float : nullptr;
20415 }
20416
20418 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20419 {
20420 return is_number_float() ? &m_value.number_float : nullptr;
20421 }
20422
20424 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20425 {
20426 return is_binary() ? m_value.binary : nullptr;
20427 }
20428
20430 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20431 {
20432 return is_binary() ? m_value.binary : nullptr;
20433 }
20434
20446 template<typename ReferenceType, typename ThisType>
20447 static ReferenceType get_ref_impl(ThisType& obj)
20448 {
20449 // delegate the call to get_ptr<>()
20450 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20451
20452 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20453 {
20454 return *ptr;
20455 }
20456
20457 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
20458 }
20459
20460 public:
20464
20491 template<typename PointerType, typename std::enable_if<
20492 std::is_pointer<PointerType>::value, int>::type = 0>
20493 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20494 {
20495 // delegate the call to get_impl_ptr<>()
20496 return get_impl_ptr(static_cast<PointerType>(nullptr));
20497 }
20498
20503 template < typename PointerType, typename std::enable_if <
20504 std::is_pointer<PointerType>::value&&
20505 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20506 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20507 {
20508 // delegate the call to get_impl_ptr<>() const
20509 return get_impl_ptr(static_cast<PointerType>(nullptr));
20510 }
20511
20512 private:
20551 template < typename ValueType,
20552 detail::enable_if_t <
20553 detail::is_default_constructible<ValueType>::value&&
20554 detail::has_from_json<basic_json_t, ValueType>::value,
20555 int > = 0 >
20556 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20557 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20558 {
20559 ValueType ret{};
20560 JSONSerializer<ValueType>::from_json(*this, ret);
20561 return ret;
20562 }
20563
20594 template < typename ValueType,
20595 detail::enable_if_t <
20596 detail::has_non_default_from_json<basic_json_t, ValueType>::value,
20597 int > = 0 >
20598 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20599 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20600 {
20601 return JSONSerializer<ValueType>::from_json(*this);
20602 }
20603
20619 template < typename BasicJsonType,
20620 detail::enable_if_t <
20621 detail::is_basic_json<BasicJsonType>::value,
20622 int > = 0 >
20623 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20624 {
20625 return *this;
20626 }
20627
20642 template<typename BasicJsonType,
20643 detail::enable_if_t<
20644 std::is_same<BasicJsonType, basic_json_t>::value,
20645 int> = 0>
20646 basic_json get_impl(detail::priority_tag<3> /*unused*/) const
20647 {
20648 return *this;
20649 }
20650
20655 template<typename PointerType,
20656 detail::enable_if_t<
20657 std::is_pointer<PointerType>::value,
20658 int> = 0>
20659 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20660 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20661 {
20662 // delegate the call to get_ptr
20663 return get_ptr<PointerType>();
20664 }
20665
20666 public:
20690 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20691#if defined(JSON_HAS_CPP_14)
20692 constexpr
20693#endif
20694 auto get() const noexcept(
20695 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20696 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20697 {
20698 // we cannot static_assert on ValueTypeCV being non-const, because
20699 // there is support for get<const basic_json_t>(), which is why we
20700 // still need the uncvref
20701 static_assert(!std::is_reference<ValueTypeCV>::value,
20702 "get() cannot be used with reference types, you might want to use get_ref()");
20703 return get_impl<ValueType>(detail::priority_tag<4> {});
20704 }
20705
20733 template<typename PointerType, typename std::enable_if<
20734 std::is_pointer<PointerType>::value, int>::type = 0>
20735 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20736 {
20737 // delegate the call to get_ptr
20738 return get_ptr<PointerType>();
20739 }
20740
20774 template < typename ValueType,
20775 detail::enable_if_t <
20776 !detail::is_basic_json<ValueType>::value&&
20777 detail::has_from_json<basic_json_t, ValueType>::value,
20778 int > = 0 >
20779 ValueType & get_to(ValueType& v) const noexcept(noexcept(
20780 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20781 {
20782 JSONSerializer<ValueType>::from_json(*this, v);
20783 return v;
20784 }
20785
20786 // specialization to allow to call get_to with a basic_json value
20787 // see https://github.com/nlohmann/json/issues/2175
20788 template<typename ValueType,
20789 detail::enable_if_t <
20790 detail::is_basic_json<ValueType>::value,
20791 int> = 0>
20792 ValueType & get_to(ValueType& v) const
20793 {
20794 v = *this;
20795 return v;
20796 }
20797
20798 template <
20799 typename T, std::size_t N,
20800 typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20801 detail::enable_if_t <
20802 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
20803 Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20804 noexcept(noexcept(JSONSerializer<Array>::from_json(
20805 std::declval<const basic_json_t&>(), v)))
20806 {
20807 JSONSerializer<Array>::from_json(*this, v);
20808 return v;
20809 }
20810
20837 template<typename ReferenceType, typename std::enable_if<
20838 std::is_reference<ReferenceType>::value, int>::type = 0>
20839 ReferenceType get_ref()
20840 {
20841 // delegate call to get_ref_impl
20842 return get_ref_impl<ReferenceType>(*this);
20843 }
20844
20849 template < typename ReferenceType, typename std::enable_if <
20850 std::is_reference<ReferenceType>::value&&
20851 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
20852 ReferenceType get_ref() const
20853 {
20854 // delegate call to get_ref_impl
20855 return get_ref_impl<ReferenceType>(*this);
20856 }
20857
20887 template < typename ValueType, typename std::enable_if <
20888 detail::conjunction <
20889 detail::negation<std::is_pointer<ValueType>>,
20890 detail::negation<std::is_same<ValueType, detail::json_ref<basic_json>>>,
20891 detail::negation<std::is_same<ValueType, typename string_t::value_type>>,
20892 detail::negation<detail::is_basic_json<ValueType>>,
20893 detail::negation<std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>>,
20894
20895#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20896 detail::negation<std::is_same<ValueType, std::string_view>>,
20897#endif
20898 detail::is_detected_lazy<detail::get_template_function, const basic_json_t&, ValueType>
20899 >::value, int >::type = 0 >
20900 JSON_EXPLICIT operator ValueType() const
20901 {
20902 // delegate the call to get<>() const
20903 return get<ValueType>();
20904 }
20905
20916 {
20917 if (!is_binary())
20918 {
20919 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20920 }
20921
20922 return *get_ptr<binary_t*>();
20923 }
20924
20926 const binary_t& get_binary() const
20927 {
20928 if (!is_binary())
20929 {
20930 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20931 }
20932
20933 return *get_ptr<const binary_t*>();
20934 }
20935
20937
20938
20940 // element access //
20942
20946
20974 {
20975 // at only works for arrays
20976 if (JSON_HEDLEY_LIKELY(is_array()))
20977 {
20978 JSON_TRY
20979 {
20980 return set_parent(m_value.array->at(idx));
20981 }
20982 JSON_CATCH (std::out_of_range&)
20983 {
20984 // create better exception explanation
20985 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20986 }
20987 }
20988 else
20989 {
20990 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20991 }
20992 }
20993
21020 const_reference at(size_type idx) const
21021 {
21022 // at only works for arrays
21023 if (JSON_HEDLEY_LIKELY(is_array()))
21024 {
21025 JSON_TRY
21026 {
21027 return m_value.array->at(idx);
21028 }
21029 JSON_CATCH (std::out_of_range&)
21030 {
21031 // create better exception explanation
21032 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21033 }
21034 }
21035 else
21036 {
21037 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21038 }
21039 }
21040
21071 reference at(const typename object_t::key_type& key)
21072 {
21073 // at only works for objects
21074 if (JSON_HEDLEY_LIKELY(is_object()))
21075 {
21076 JSON_TRY
21077 {
21078 return set_parent(m_value.object->at(key));
21079 }
21080 JSON_CATCH (std::out_of_range&)
21081 {
21082 // create better exception explanation
21083 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21084 }
21085 }
21086 else
21087 {
21088 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21089 }
21090 }
21091
21122 const_reference at(const typename object_t::key_type& key) const
21123 {
21124 // at only works for objects
21125 if (JSON_HEDLEY_LIKELY(is_object()))
21126 {
21127 JSON_TRY
21128 {
21129 return m_value.object->at(key);
21130 }
21131 JSON_CATCH (std::out_of_range&)
21133 // create better exception explanation
21134 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21135 }
21136 }
21137 else
21138 {
21139 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21140 }
21141 }
21142
21169 {
21170 // implicitly convert null value to an empty array
21171 if (is_null())
21172 {
21173 m_type = value_t::array;
21174 m_value.array = create<array_t>();
21175 assert_invariant();
21176 }
21177
21178 // operator[] only works for arrays
21179 if (JSON_HEDLEY_LIKELY(is_array()))
21180 {
21181 // fill up array with null values if given idx is outside range
21182 if (idx >= m_value.array->size())
21183 {
21184#if JSON_DIAGNOSTICS
21185 // remember array size & capacity before resizing
21186 const auto old_size = m_value.array->size();
21187 const auto old_capacity = m_value.array->capacity();
21188#endif
21189 m_value.array->resize(idx + 1);
21190
21191#if JSON_DIAGNOSTICS
21192 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
21193 {
21194 // capacity has changed: update all parents
21195 set_parents();
21196 }
21197 else
21198 {
21199 // set parent for values added above
21200 set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
21201 }
21202#endif
21203 assert_invariant();
21204 }
21205
21206 return m_value.array->operator[](idx);
21207 }
21208
21209 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21210 }
21211
21232 {
21233 // const operator[] only works for arrays
21234 if (JSON_HEDLEY_LIKELY(is_array()))
21235 {
21236 return m_value.array->operator[](idx);
21237 }
21238
21239 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21240 }
21269 reference operator[](const typename object_t::key_type& key)
21270 {
21271 // implicitly convert null value to an empty object
21272 if (is_null())
21273 {
21274 m_type = value_t::object;
21275 m_value.object = create<object_t>();
21276 assert_invariant();
21277 }
21278
21279 // operator[] only works for objects
21280 if (JSON_HEDLEY_LIKELY(is_object()))
21281 {
21282 return set_parent(m_value.object->operator[](key));
21283 }
21284
21285 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21286 }
21287
21318 const_reference operator[](const typename object_t::key_type& key) const
21319 {
21320 // const operator[] only works for objects
21321 if (JSON_HEDLEY_LIKELY(is_object()))
21322 {
21323 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21324 return m_value.object->find(key)->second;
21325 }
21326
21327 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21329
21357 template<typename T>
21358 JSON_HEDLEY_NON_NULL(2)
21359 reference operator[](T* key)
21360 {
21361 // implicitly convert null to object
21362 if (is_null())
21363 {
21364 m_type = value_t::object;
21365 m_value = value_t::object;
21366 assert_invariant();
21367 }
21368
21369 // at only works for objects
21370 if (JSON_HEDLEY_LIKELY(is_object()))
21371 {
21372 return set_parent(m_value.object->operator[](key));
21373 }
21374
21375 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21376 }
21377
21408 template<typename T>
21409 JSON_HEDLEY_NON_NULL(2)
21410 const_reference operator[](T* key) const
21411 {
21412 // at only works for objects
21413 if (JSON_HEDLEY_LIKELY(is_object()))
21414 {
21415 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21416 return m_value.object->find(key)->second;
21417 }
21418
21419 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21421
21472 // using std::is_convertible in a std::enable_if will fail when using explicit conversions
21473 template < class ValueType, typename std::enable_if <
21474 detail::is_getable<basic_json_t, ValueType>::value
21475 && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
21476 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21477 {
21478 // at only works for objects
21479 if (JSON_HEDLEY_LIKELY(is_object()))
21480 {
21481 // if key is found, return value and given default value otherwise
21482 const auto it = find(key);
21483 if (it != end())
21484 {
21485 return it->template get<ValueType>();
21487
21488 return default_value;
21489 }
21490
21491 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21492 }
21493
21498 string_t value(const typename object_t::key_type& key, const char* default_value) const
21499 {
21500 return value(key, string_t(default_value));
21501 }
21502
21546 template<class ValueType, typename std::enable_if<
21547 detail::is_getable<basic_json_t, ValueType>::value, int>::type = 0>
21548 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21549 {
21550 // at only works for objects
21551 if (JSON_HEDLEY_LIKELY(is_object()))
21552 {
21553 // if pointer resolves a value, return it or use default value
21554 JSON_TRY
21555 {
21556 return ptr.get_checked(this).template get<ValueType>();
21557 }
21558 JSON_INTERNAL_CATCH (out_of_range&)
21559 {
21560 return default_value;
21561 }
21562 }
21563
21564 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21565 }
21566
21571 JSON_HEDLEY_NON_NULL(3)
21572 string_t value(const json_pointer& ptr, const char* default_value) const
21573 {
21574 return value(ptr, string_t(default_value));
21575 }
21576
21603 {
21604 return *begin();
21605 }
21606
21610 const_reference front() const
21611 {
21612 return *cbegin();
21613 }
21614
21646 reference back()
21647 {
21648 auto tmp = end();
21649 --tmp;
21650 return *tmp;
21651 }
21652
21657 {
21658 auto tmp = cend();
21659 --tmp;
21660 return *tmp;
21661 }
21662
21709 template < class IteratorType, typename std::enable_if <
21710 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21711 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21712 = 0 >
21713 IteratorType erase(IteratorType pos)
21714 {
21715 // make sure iterator fits the current value
21716 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21717 {
21718 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
21719 }
21720
21721 IteratorType result = end();
21722
21723 switch (m_type)
21724 {
21725 case value_t::boolean:
21726 case value_t::number_float:
21727 case value_t::number_integer:
21728 case value_t::number_unsigned:
21729 case value_t::string:
21730 case value_t::binary:
21731 {
21732 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21733 {
21734 JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
21735 }
21736
21737 if (is_string())
21738 {
21739 AllocatorType<string_t> alloc;
21740 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21741 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21742 m_value.string = nullptr;
21743 }
21744 else if (is_binary())
21745 {
21746 AllocatorType<binary_t> alloc;
21747 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21748 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21749 m_value.binary = nullptr;
21750 }
21751
21752 m_type = value_t::null;
21753 assert_invariant();
21754 break;
21755 }
21756
21757 case value_t::object:
21758 {
21759 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21760 break;
21761 }
21762
21763 case value_t::array:
21764 {
21765 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21766 break;
21767 }
21768
21769 case value_t::null:
21770 case value_t::discarded:
21771 default:
21772 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21773 }
21774
21775 return result;
21776 }
21777
21824 template < class IteratorType, typename std::enable_if <
21825 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21826 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21827 = 0 >
21828 IteratorType erase(IteratorType first, IteratorType last)
21829 {
21830 // make sure iterator fits the current value
21831 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21832 {
21833 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
21834 }
21835
21836 IteratorType result = end();
21837
21838 switch (m_type)
21839 {
21840 case value_t::boolean:
21841 case value_t::number_float:
21842 case value_t::number_integer:
21843 case value_t::number_unsigned:
21844 case value_t::string:
21845 case value_t::binary:
21846 {
21847 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21848 || !last.m_it.primitive_iterator.is_end()))
21849 {
21850 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
21851 }
21852
21853 if (is_string())
21854 {
21855 AllocatorType<string_t> alloc;
21856 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21857 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21858 m_value.string = nullptr;
21859 }
21860 else if (is_binary())
21861 {
21862 AllocatorType<binary_t> alloc;
21863 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21864 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21865 m_value.binary = nullptr;
21866 }
21867
21868 m_type = value_t::null;
21869 assert_invariant();
21870 break;
21871 }
21872
21873 case value_t::object:
21874 {
21875 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21876 last.m_it.object_iterator);
21877 break;
21878 }
21879
21880 case value_t::array:
21881 {
21882 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21883 last.m_it.array_iterator);
21884 break;
21885 }
21886
21887 case value_t::null:
21888 case value_t::discarded:
21889 default:
21890 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21891 }
21892
21893 return result;
21894 }
21895
21925 size_type erase(const typename object_t::key_type& key)
21926 {
21927 // this erase only works for objects
21928 if (JSON_HEDLEY_LIKELY(is_object()))
21929 {
21930 return m_value.object->erase(key);
21931 }
21932
21933 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21934 }
21960 void erase(const size_type idx)
21961 {
21962 // this erase only works for arrays
21963 if (JSON_HEDLEY_LIKELY(is_array()))
21964 {
21965 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21966 {
21967 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21968 }
21969
21970 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21971 }
21972 else
21973 {
21974 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21975 }
21976 }
21977
21979
21980
21982 // lookup //
21984
21987
22012 template<typename KeyT>
22013 iterator find(KeyT&& key)
22014 {
22015 auto result = end();
22016
22017 if (is_object())
22018 {
22019 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
22020 }
22021
22022 return result;
22024
22029 template<typename KeyT>
22030 const_iterator find(KeyT&& key) const
22031 {
22032 auto result = cend();
22033
22034 if (is_object())
22035 {
22036 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
22037 }
22038
22039 return result;
22041
22063 template<typename KeyT>
22064 size_type count(KeyT&& key) const
22065 {
22066 // return 0 for all nonobject types
22067 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
22068 }
22069
22095 template < typename KeyT, typename std::enable_if <
22096 !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
22097 bool contains(KeyT && key) const
22098 {
22099 return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
22100 }
22101
22128 bool contains(const json_pointer& ptr) const
22129 {
22130 return ptr.contains(this);
22131 }
22132
22134
22135
22137 // iterators //
22139
22142
22167 iterator begin() noexcept
22168 {
22169 iterator result(this);
22170 result.set_begin();
22171 return result;
22172 }
22173
22177 const_iterator begin() const noexcept
22178 {
22179 return cbegin();
22180 }
22181
22207 const_iterator cbegin() const noexcept
22208 {
22209 const_iterator result(this);
22210 result.set_begin();
22211 return result;
22212 }
22213
22238 iterator end() noexcept
22239 {
22240 iterator result(this);
22241 result.set_end();
22242 return result;
22243 }
22244
22248 const_iterator end() const noexcept
22249 {
22250 return cend();
22251 }
22252
22278 const_iterator cend() const noexcept
22279 {
22280 const_iterator result(this);
22281 result.set_end();
22282 return result;
22283 }
22284
22308 reverse_iterator rbegin() noexcept
22309 {
22310 return reverse_iterator(end());
22311 }
22312
22316 const_reverse_iterator rbegin() const noexcept
22317 {
22318 return crbegin();
22319 }
22320
22345 reverse_iterator rend() noexcept
22346 {
22347 return reverse_iterator(begin());
22348 }
22349
22353 const_reverse_iterator rend() const noexcept
22354 {
22355 return crend();
22356 }
22357
22382 const_reverse_iterator crbegin() const noexcept
22383 {
22384 return const_reverse_iterator(cend());
22385 }
22386
22411 const_reverse_iterator crend() const noexcept
22412 {
22414 }
22415
22416 public:
22474 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22475 static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
22476 {
22477 return ref.items();
22478 }
22479
22483 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22484 static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
22486 return ref.items();
22487 }
22488
22557 iteration_proxy<iterator> items() noexcept
22558 {
22559 return iteration_proxy<iterator>(*this);
22560 }
22561
22565 iteration_proxy<const_iterator> items() const noexcept
22566 {
22567 return iteration_proxy<const_iterator>(*this);
22568 }
22569
22571
22572
22574 // capacity //
22576
22579
22622 bool empty() const noexcept
22623 {
22624 switch (m_type)
22625 {
22626 case value_t::null:
22627 {
22628 // null values are empty
22629 return true;
22630 }
22631
22632 case value_t::array:
22633 {
22634 // delegate call to array_t::empty()
22635 return m_value.array->empty();
22636 }
22637
22638 case value_t::object:
22639 {
22640 // delegate call to object_t::empty()
22641 return m_value.object->empty();
22642 }
22643
22644 case value_t::string:
22645 case value_t::boolean:
22646 case value_t::number_integer:
22647 case value_t::number_unsigned:
22648 case value_t::number_float:
22649 case value_t::binary:
22650 case value_t::discarded:
22651 default:
22652 {
22653 // all other types are nonempty
22654 return false;
22655 }
22656 }
22657 }
22658
22702 size_type size() const noexcept
22703 {
22704 switch (m_type)
22705 {
22706 case value_t::null:
22707 {
22708 // null values are empty
22709 return 0;
22710 }
22711
22712 case value_t::array:
22713 {
22714 // delegate call to array_t::size()
22715 return m_value.array->size();
22716 }
22717
22718 case value_t::object:
22719 {
22720 // delegate call to object_t::size()
22721 return m_value.object->size();
22722 }
22723
22724 case value_t::string:
22725 case value_t::boolean:
22726 case value_t::number_integer:
22727 case value_t::number_unsigned:
22728 case value_t::number_float:
22729 case value_t::binary:
22730 case value_t::discarded:
22731 default:
22732 {
22733 // all other types have size 1
22734 return 1;
22735 }
22736 }
22737 }
22738
22780 size_type max_size() const noexcept
22781 {
22782 switch (m_type)
22783 {
22784 case value_t::array:
22785 {
22786 // delegate call to array_t::max_size()
22787 return m_value.array->max_size();
22788 }
22789
22790 case value_t::object:
22791 {
22792 // delegate call to object_t::max_size()
22793 return m_value.object->max_size();
22794 }
22795
22796 case value_t::null:
22797 case value_t::string:
22798 case value_t::boolean:
22799 case value_t::number_integer:
22800 case value_t::number_unsigned:
22801 case value_t::number_float:
22802 case value_t::binary:
22803 case value_t::discarded:
22804 default:
22805 {
22806 // all other types have max_size() == size()
22807 return size();
22808 }
22809 }
22810 }
22811
22813
22814
22816 // modifiers //
22818
22821
22859 void clear() noexcept
22860 {
22861 switch (m_type)
22862 {
22863 case value_t::number_integer:
22864 {
22865 m_value.number_integer = 0;
22866 break;
22867 }
22868
22869 case value_t::number_unsigned:
22870 {
22871 m_value.number_unsigned = 0;
22872 break;
22873 }
22874
22875 case value_t::number_float:
22876 {
22877 m_value.number_float = 0.0;
22878 break;
22879 }
22880
22881 case value_t::boolean:
22882 {
22883 m_value.boolean = false;
22884 break;
22885 }
22886
22887 case value_t::string:
22888 {
22889 m_value.string->clear();
22890 break;
22891 }
22892
22893 case value_t::binary:
22894 {
22895 m_value.binary->clear();
22896 break;
22897 }
22898
22899 case value_t::array:
22900 {
22901 m_value.array->clear();
22902 break;
22903 }
22904
22905 case value_t::object:
22906 {
22907 m_value.object->clear();
22908 break;
22909 }
22910
22911 case value_t::null:
22912 case value_t::discarded:
22913 default:
22914 break;
22915 }
22916 }
22917
22938 void push_back(basic_json&& val)
22939 {
22940 // push_back only works for null objects or arrays
22941 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22942 {
22943 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22944 }
22945
22946 // transform null object into an array
22947 if (is_null())
22949 m_type = value_t::array;
22950 m_value = value_t::array;
22951 assert_invariant();
22952 }
22953
22954 // add element to array (move semantics)
22955 const auto old_capacity = m_value.array->capacity();
22956 m_value.array->push_back(std::move(val));
22957 set_parent(m_value.array->back(), old_capacity);
22958 // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
22959 }
22960
22966 {
22967 push_back(std::move(val));
22968 return *this;
22969 }
22970
22975 void push_back(const basic_json& val)
22976 {
22977 // push_back only works for null objects or arrays
22978 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22979 {
22980 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22981 }
22982
22983 // transform null object into an array
22984 if (is_null())
22986 m_type = value_t::array;
22987 m_value = value_t::array;
22988 assert_invariant();
22989 }
22990
22991 // add element to array
22992 const auto old_capacity = m_value.array->capacity();
22993 m_value.array->push_back(val);
22994 set_parent(m_value.array->back(), old_capacity);
22995 }
22996
23001 reference operator+=(const basic_json& val)
23002 {
23003 push_back(val);
23004 return *this;
23005 }
23006
23027 void push_back(const typename object_t::value_type& val)
23028 {
23029 // push_back only works for null objects or objects
23030 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23031 {
23032 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
23033 }
23034
23035 // transform null object into an object
23036 if (is_null())
23038 m_type = value_t::object;
23039 m_value = value_t::object;
23040 assert_invariant();
23041 }
23042
23043 // add element to object
23044 auto res = m_value.object->insert(val);
23045 set_parent(res.first->second);
23046 }
23047
23052 reference operator+=(const typename object_t::value_type& val)
23053 {
23054 push_back(val);
23055 return *this;
23056 }
23057
23083 void push_back(initializer_list_t init)
23084 {
23085 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
23086 {
23087 basic_json&& key = init.begin()->moved_or_copied();
23088 push_back(typename object_t::value_type(
23089 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
23090 }
23091 else
23092 {
23094 }
23095 }
23096
23102 {
23103 push_back(init);
23104 return *this;
23105 }
23106
23130 template<class... Args>
23131 reference emplace_back(Args&& ... args)
23132 {
23133 // emplace_back only works for null objects or arrays
23134 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23135 {
23136 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
23137 }
23138
23139 // transform null object into an array
23140 if (is_null())
23142 m_type = value_t::array;
23143 m_value = value_t::array;
23144 assert_invariant();
23145 }
23146
23147 // add element to array (perfect forwarding)
23148 const auto old_capacity = m_value.array->capacity();
23149 m_value.array->emplace_back(std::forward<Args>(args)...);
23150 return set_parent(m_value.array->back(), old_capacity);
23151 }
23152
23180 template<class... Args>
23181 std::pair<iterator, bool> emplace(Args&& ... args)
23182 {
23183 // emplace only works for null objects or arrays
23184 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23185 {
23186 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
23187 }
23188
23189 // transform null object into an object
23190 if (is_null())
23192 m_type = value_t::object;
23193 m_value = value_t::object;
23194 assert_invariant();
23195 }
23196
23197 // add element to array (perfect forwarding)
23198 auto res = m_value.object->emplace(std::forward<Args>(args)...);
23199 set_parent(res.first->second);
23200
23201 // create result iterator and set iterator to the result of emplace
23202 auto it = begin();
23203 it.m_it.object_iterator = res.first;
23204
23205 // return pair of iterator and boolean
23206 return {it, res.second};
23207 }
23208
23212 template<typename... Args>
23213 iterator insert_iterator(const_iterator pos, Args&& ... args)
23214 {
23215 iterator result(this);
23216 JSON_ASSERT(m_value.array != nullptr);
23217
23218 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
23219 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
23220 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
23221
23222 // This could have been written as:
23223 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
23224 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
23225
23226 set_parents();
23227 return result;
23228 }
23229
23252 iterator insert(const_iterator pos, const basic_json& val)
23253 {
23254 // insert only works for arrays
23255 if (JSON_HEDLEY_LIKELY(is_array()))
23256 {
23257 // check if iterator pos fits to this JSON value
23258 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23259 {
23260 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23261 }
23263 // insert to array and return iterator
23264 return insert_iterator(pos, val);
23265 }
23266
23267 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23268 }
23269
23275 {
23276 return insert(pos, val);
23277 }
23278
23303 iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
23304 {
23305 // insert only works for arrays
23306 if (JSON_HEDLEY_LIKELY(is_array()))
23307 {
23308 // check if iterator pos fits to this JSON value
23309 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23310 {
23311 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23312 }
23314 // insert to array and return iterator
23315 return insert_iterator(pos, cnt, val);
23316 }
23317
23318 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23319 }
23320
23352 {
23353 // insert only works for arrays
23354 if (JSON_HEDLEY_UNLIKELY(!is_array()))
23355 {
23356 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23357 }
23358
23359 // check if iterator pos fits to this JSON value
23360 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23362 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23363 }
23364
23365 // check if range iterators belong to the same JSON object
23366 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23367 {
23368 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23369 }
23370
23371 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
23372 {
23373 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
23374 }
23375
23376 // insert to array and return iterator
23377 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
23378 }
23379
23405 {
23406 // insert only works for arrays
23407 if (JSON_HEDLEY_UNLIKELY(!is_array()))
23408 {
23409 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23410 }
23411
23412 // check if iterator pos fits to this JSON value
23413 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23415 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23416 }
23417
23418 // insert to array and return iterator
23419 return insert_iterator(pos, ilist.begin(), ilist.end());
23420 }
23421
23445 void insert(const_iterator first, const_iterator last)
23446 {
23447 // insert only works for objects
23448 if (JSON_HEDLEY_UNLIKELY(!is_object()))
23449 {
23450 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23451 }
23452
23453 // check if range iterators belong to the same JSON object
23454 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23456 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23457 }
23458
23459 // passed iterators must belong to objects
23460 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23461 {
23462 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23463 }
23464
23465 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
23466 }
23467
23487 void update(const_reference j)
23488 {
23489 // implicitly convert null value to an empty object
23490 if (is_null())
23491 {
23492 m_type = value_t::object;
23493 m_value.object = create<object_t>();
23494 assert_invariant();
23495 }
23496
23497 if (JSON_HEDLEY_UNLIKELY(!is_object()))
23498 {
23499 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23500 }
23501 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
23502 {
23503 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
23504 }
23505
23506 for (auto it = j.cbegin(); it != j.cend(); ++it)
23507 {
23508 m_value.object->operator[](it.key()) = it.value();
23509#if JSON_DIAGNOSTICS
23510 m_value.object->operator[](it.key()).m_parent = this;
23511#endif
23512 }
23513 }
23514
23541 void update(const_iterator first, const_iterator last)
23542 {
23543 // implicitly convert null value to an empty object
23544 if (is_null())
23545 {
23546 m_type = value_t::object;
23547 m_value.object = create<object_t>();
23548 assert_invariant();
23549 }
23550
23551 if (JSON_HEDLEY_UNLIKELY(!is_object()))
23552 {
23553 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23554 }
23555
23556 // check if range iterators belong to the same JSON object
23557 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23558 {
23559 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23560 }
23561
23562 // passed iterators must belong to objects
23563 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
23564 || !last.m_object->is_object()))
23565 {
23566 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23567 }
23568
23569 for (auto it = first; it != last; ++it)
23570 {
23571 m_value.object->operator[](it.key()) = it.value();
23572#if JSON_DIAGNOSTICS
23573 m_value.object->operator[](it.key()).m_parent = this;
23574#endif
23575 }
23576 }
23577
23595 void swap(reference other) noexcept (
23596 std::is_nothrow_move_constructible<value_t>::value&&
23597 std::is_nothrow_move_assignable<value_t>::value&&
23598 std::is_nothrow_move_constructible<json_value>::value&&
23599 std::is_nothrow_move_assignable<json_value>::value
23600 )
23601 {
23602 std::swap(m_type, other.m_type);
23603 std::swap(m_value, other.m_value);
23604
23605 set_parents();
23606 other.set_parents();
23607 assert_invariant();
23608 }
23609
23628 friend void swap(reference left, reference right) noexcept (
23629 std::is_nothrow_move_constructible<value_t>::value&&
23630 std::is_nothrow_move_assignable<value_t>::value&&
23631 std::is_nothrow_move_constructible<json_value>::value&&
23632 std::is_nothrow_move_assignable<json_value>::value
23633 )
23634 {
23635 left.swap(right);
23636 }
23637
23658 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
23659 {
23660 // swap only works for arrays
23661 if (JSON_HEDLEY_LIKELY(is_array()))
23662 {
23663 std::swap(*(m_value.array), other);
23664 }
23665 else
23666 {
23667 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23669 }
23670
23691 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
23692 {
23693 // swap only works for objects
23694 if (JSON_HEDLEY_LIKELY(is_object()))
23695 {
23696 std::swap(*(m_value.object), other);
23697 }
23698 else
23699 {
23700 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23702 }
23703
23724 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
23725 {
23726 // swap only works for strings
23727 if (JSON_HEDLEY_LIKELY(is_string()))
23728 {
23729 std::swap(*(m_value.string), other);
23730 }
23731 else
23732 {
23733 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23735 }
23736
23757 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
23758 {
23759 // swap only works for strings
23760 if (JSON_HEDLEY_LIKELY(is_binary()))
23761 {
23762 std::swap(*(m_value.binary), other);
23763 }
23764 else
23765 {
23766 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23768 }
23769
23771 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
23772 {
23773 // swap only works for strings
23774 if (JSON_HEDLEY_LIKELY(is_binary()))
23775 {
23776 std::swap(*(m_value.binary), other);
23777 }
23778 else
23779 {
23780 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23782 }
23783
23785
23786 public:
23788 // lexicographical comparison operators //
23790
23793
23849 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23850 {
23851#ifdef __GNUC__
23852#pragma GCC diagnostic push
23853#pragma GCC diagnostic ignored "-Wfloat-equal"
23854#endif
23855 const auto lhs_type = lhs.type();
23856 const auto rhs_type = rhs.type();
23857
23858 if (lhs_type == rhs_type)
23860 switch (lhs_type)
23861 {
23862 case value_t::array:
23863 return *lhs.m_value.array == *rhs.m_value.array;
23864
23865 case value_t::object:
23866 return *lhs.m_value.object == *rhs.m_value.object;
23867
23868 case value_t::null:
23869 return true;
23870
23871 case value_t::string:
23872 return *lhs.m_value.string == *rhs.m_value.string;
23873
23874 case value_t::boolean:
23875 return lhs.m_value.boolean == rhs.m_value.boolean;
23876
23877 case value_t::number_integer:
23878 return lhs.m_value.number_integer == rhs.m_value.number_integer;
23879
23880 case value_t::number_unsigned:
23881 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
23882
23883 case value_t::number_float:
23884 return lhs.m_value.number_float == rhs.m_value.number_float;
23885
23886 case value_t::binary:
23887 return *lhs.m_value.binary == *rhs.m_value.binary;
23888
23889 case value_t::discarded:
23890 default:
23891 return false;
23892 }
23893 }
23894 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23895 {
23896 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
23897 }
23898 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23899 {
23900 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
23901 }
23902 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23903 {
23904 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
23905 }
23906 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23907 {
23908 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
23909 }
23910 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23911 {
23912 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
23913 }
23914 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23915 {
23916 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23917 }
23918
23919 return false;
23920#ifdef __GNUC__
23921#pragma GCC diagnostic pop
23922#endif
23923 }
23924
23929 template<typename ScalarType, typename std::enable_if<
23930 std::is_scalar<ScalarType>::value, int>::type = 0>
23931 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23932 {
23933 return lhs == basic_json(rhs);
23934 }
23935
23940 template<typename ScalarType, typename std::enable_if<
23941 std::is_scalar<ScalarType>::value, int>::type = 0>
23942 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23943 {
23944 return basic_json(lhs) == rhs;
23945 }
23946
23965 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23966 {
23967 return !(lhs == rhs);
23968 }
23969
23974 template<typename ScalarType, typename std::enable_if<
23975 std::is_scalar<ScalarType>::value, int>::type = 0>
23976 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23977 {
23978 return lhs != basic_json(rhs);
23979 }
23980
23985 template<typename ScalarType, typename std::enable_if<
23986 std::is_scalar<ScalarType>::value, int>::type = 0>
23987 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23988 {
23989 return basic_json(lhs) != rhs;
23990 }
23991
24018 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
24019 {
24020 const auto lhs_type = lhs.type();
24021 const auto rhs_type = rhs.type();
24022
24023 if (lhs_type == rhs_type)
24024 {
24025 switch (lhs_type)
24026 {
24027 case value_t::array:
24028 // note parentheses are necessary, see
24029 // https://github.com/nlohmann/json/issues/1530
24030 return (*lhs.m_value.array) < (*rhs.m_value.array);
24031
24032 case value_t::object:
24033 return (*lhs.m_value.object) < (*rhs.m_value.object);
24034
24035 case value_t::null:
24036 return false;
24037
24038 case value_t::string:
24039 return (*lhs.m_value.string) < (*rhs.m_value.string);
24040
24041 case value_t::boolean:
24042 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
24043
24044 case value_t::number_integer:
24045 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
24046
24047 case value_t::number_unsigned:
24048 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
24049
24050 case value_t::number_float:
24051 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
24052
24053 case value_t::binary:
24054 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
24055
24056 case value_t::discarded:
24057 default:
24058 return false;
24059 }
24060 }
24061 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
24062 {
24063 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
24064 }
24065 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
24066 {
24067 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
24068 }
24069 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
24070 {
24071 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
24072 }
24073 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
24074 {
24075 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
24076 }
24077 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
24078 {
24079 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
24080 }
24081 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
24082 {
24083 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
24084 }
24085
24086 // We only reach this line if we cannot compare values. In that case,
24087 // we compare types. Note we have to call the operator explicitly,
24088 // because MSVC has problems otherwise.
24089 return operator<(lhs_type, rhs_type);
24090 }
24091
24096 template<typename ScalarType, typename std::enable_if<
24097 std::is_scalar<ScalarType>::value, int>::type = 0>
24098 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
24099 {
24100 return lhs < basic_json(rhs);
24101 }
24102
24107 template<typename ScalarType, typename std::enable_if<
24108 std::is_scalar<ScalarType>::value, int>::type = 0>
24109 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
24110 {
24111 return basic_json(lhs) < rhs;
24112 }
24113
24133 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
24134 {
24135 return !(rhs < lhs);
24136 }
24137
24142 template<typename ScalarType, typename std::enable_if<
24143 std::is_scalar<ScalarType>::value, int>::type = 0>
24144 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
24145 {
24146 return lhs <= basic_json(rhs);
24147 }
24148
24153 template<typename ScalarType, typename std::enable_if<
24154 std::is_scalar<ScalarType>::value, int>::type = 0>
24155 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
24156 {
24157 return basic_json(lhs) <= rhs;
24158 }
24159
24179 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
24180 {
24181 return !(lhs <= rhs);
24182 }
24183
24188 template<typename ScalarType, typename std::enable_if<
24189 std::is_scalar<ScalarType>::value, int>::type = 0>
24190 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
24191 {
24192 return lhs > basic_json(rhs);
24193 }
24194
24199 template<typename ScalarType, typename std::enable_if<
24200 std::is_scalar<ScalarType>::value, int>::type = 0>
24201 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
24202 {
24203 return basic_json(lhs) > rhs;
24204 }
24205
24225 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
24226 {
24227 return !(lhs < rhs);
24228 }
24229
24234 template<typename ScalarType, typename std::enable_if<
24235 std::is_scalar<ScalarType>::value, int>::type = 0>
24236 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
24237 {
24238 return lhs >= basic_json(rhs);
24239 }
24240
24245 template<typename ScalarType, typename std::enable_if<
24246 std::is_scalar<ScalarType>::value, int>::type = 0>
24247 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
24248 {
24249 return basic_json(lhs) >= rhs;
24250 }
24251
24253
24255 // serialization //
24260#ifndef JSON_NO_IO
24292 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
24293 {
24294 // read width member and use it as indentation parameter if nonzero
24295 const bool pretty_print = o.width() > 0;
24296 const auto indentation = pretty_print ? o.width() : 0;
24297
24298 // reset width to 0 for subsequent calls to this stream
24299 o.width(0);
24300
24301 // do the actual serialization
24302 serializer s(detail::output_adapter<char>(o), o.fill());
24303 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
24304 return o;
24305 }
24306
24315 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
24316 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
24317 {
24318 return o << j;
24319 }
24320#endif // JSON_NO_IO
24322
24323
24325 // deserialization //
24327
24330
24382 template<typename InputType>
24383
24384 static basic_json parse(InputType&& i,
24385 const parser_callback_t cb = nullptr,
24386 const bool allow_exceptions = true,
24387 const bool ignore_comments = false)
24388 {
24389 basic_json result;
24390 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
24391 return result;
24392 }
24393
24420 template<typename IteratorType>
24421
24422 static basic_json parse(IteratorType first,
24423 IteratorType last,
24424 const parser_callback_t cb = nullptr,
24425 const bool allow_exceptions = true,
24426 const bool ignore_comments = false)
24427 {
24428 basic_json result;
24429 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
24430 return result;
24431 }
24433
24434 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
24435 static basic_json parse(detail::span_input_adapter&& i,
24436 const parser_callback_t cb = nullptr,
24437 const bool allow_exceptions = true,
24438 const bool ignore_comments = false)
24439 {
24440 basic_json result;
24441 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
24442 return result;
24443 }
24444
24475 template<typename InputType>
24476 static bool accept(InputType&& i,
24477 const bool ignore_comments = false)
24478 {
24479 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
24480 }
24481
24482 template<typename IteratorType>
24483 static bool accept(IteratorType first, IteratorType last,
24484 const bool ignore_comments = false)
24485 {
24486 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
24487 }
24488
24489
24490 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
24491 static bool accept(detail::span_input_adapter&& i,
24492 const bool ignore_comments = false)
24494 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
24495 }
24496
24537 template <typename InputType, typename SAX>
24538 JSON_HEDLEY_NON_NULL(2)
24539 static bool sax_parse(InputType&& i, SAX* sax,
24541 const bool strict = true,
24542 const bool ignore_comments = false)
24543 {
24544 auto ia = detail::input_adapter(std::forward<InputType>(i));
24545 return format == input_format_t::json
24546 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24547 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24548 }
24550 template<class IteratorType, class SAX>
24551 JSON_HEDLEY_NON_NULL(3)
24552 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
24553 input_format_t format = input_format_t::json,
24554 const bool strict = true,
24555 const bool ignore_comments = false)
24556 {
24557 auto ia = detail::input_adapter(std::move(first), std::move(last));
24558 return format == input_format_t::json
24559 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24560 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24561 }
24563 template <typename SAX>
24564 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
24565 JSON_HEDLEY_NON_NULL(2)
24566 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
24567 input_format_t format = input_format_t::json,
24568 const bool strict = true,
24569 const bool ignore_comments = false)
24570 {
24571 auto ia = i.get();
24572 return format == input_format_t::json
24573 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24574 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24575 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24576 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24577 }
24578#ifndef JSON_NO_IO
24587 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
24588 friend std::istream& operator<<(basic_json& j, std::istream& i)
24589 {
24590 return operator>>(i, j);
24591 }
24592
24618 friend std::istream& operator>>(std::istream& i, basic_json& j)
24619 {
24620 parser(detail::input_adapter(i)).parse(false, j);
24621 return i;
24622 }
24623#endif // JSON_NO_IO
24625
24627 // convenience functions //
24629
24661
24662 const char* type_name() const noexcept
24663 {
24664 {
24665 switch (m_type)
24666 {
24667 case value_t::null:
24668 return "null";
24669 case value_t::object:
24670 return "object";
24671 case value_t::array:
24672 return "array";
24673 case value_t::string:
24674 return "string";
24675 case value_t::boolean:
24676 return "boolean";
24677 case value_t::binary:
24678 return "binary";
24679 case value_t::discarded:
24680 return "discarded";
24681 case value_t::number_integer:
24682 case value_t::number_unsigned:
24683 case value_t::number_float:
24684 default:
24685 return "number";
24686 }
24687 }
24688 }
24689
24690
24691 JSON_PRIVATE_UNLESS_TESTED:
24693 // member variables //
24695
24697 value_t m_type = value_t::null;
24698
24700 json_value m_value = {};
24702#if JSON_DIAGNOSTICS
24704 basic_json* m_parent = nullptr;
24705#endif
24706
24708 // binary serialization/deserialization //
24713
24714 public:
24813 static std::vector<std::uint8_t> to_cbor(const basic_json& j)
24814 {
24815 std::vector<std::uint8_t> result;
24816 to_cbor(j, result);
24817 return result;
24818 }
24819
24820 static void to_cbor(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24821 {
24822 binary_writer<std::uint8_t>(o).write_cbor(j);
24824
24825 static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
24826 {
24827 binary_writer<char>(o).write_cbor(j);
24828 }
24829
24908 static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
24909 {
24910 std::vector<std::uint8_t> result;
24911 to_msgpack(j, result);
24912 return result;
24913 }
24914
24915 static void to_msgpack(const basic_json& j, detail::output_adapter<std::uint8_t> o)
24916 {
24917 binary_writer<std::uint8_t>(o).write_msgpack(j);
24919
24920 static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
24921 {
24922 binary_writer<char>(o).write_msgpack(j);
24923 }
24924
25011 static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
25012 const bool use_size = false,
25013 const bool use_type = false)
25014 {
25015 std::vector<std::uint8_t> result;
25016 to_ubjson(j, result, use_size, use_type);
25017 return result;
25018 }
25019
25020 static void to_ubjson(const basic_json& j, detail::output_adapter<std::uint8_t> o,
25021 const bool use_size = false, const bool use_type = false)
25022 {
25023 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
25024 }
25025
25026 static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
25027 const bool use_size = false, const bool use_type = false)
25028 {
25029 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
25031
25032
25089 static std::vector<std::uint8_t> to_bson(const basic_json& j)
25090 {
25091 std::vector<std::uint8_t> result;
25092 to_bson(j, result);
25093 return result;
25094 }
25095
25104 static void to_bson(const basic_json& j, detail::output_adapter<std::uint8_t> o)
25105 {
25106 binary_writer<std::uint8_t>(o).write_bson(j);
25107 }
25108
25112 static void to_bson(const basic_json& j, detail::output_adapter<char> o)
25113 {
25114 binary_writer<char>(o).write_bson(j);
25115 }
25116
25117
25220 template<typename InputType>
25221
25222 static basic_json from_cbor(InputType&& i,
25223 const bool strict = true,
25224 const bool allow_exceptions = true,
25225 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25226 {
25227 basic_json result;
25228 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25229 auto ia = detail::input_adapter(std::forward<InputType>(i));
25230 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25231 return res ? result : basic_json(value_t::discarded);
25233
25237 template<typename IteratorType>
25238
25239 static basic_json from_cbor(IteratorType first, IteratorType last,
25240 const bool strict = true,
25241 const bool allow_exceptions = true,
25242 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25243 {
25244 basic_json result;
25245 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25246 auto ia = detail::input_adapter(std::move(first), std::move(last));
25247 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25248 return res ? result : basic_json(value_t::discarded);
25250
25251 template<typename T>
25252
25253 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25254 static basic_json from_cbor(const T* ptr, std::size_t len,
25255 const bool strict = true,
25256 const bool allow_exceptions = true,
25257 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25258 {
25259 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
25260 }
25261
25262
25263
25264 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25265 static basic_json from_cbor(detail::span_input_adapter&& i,
25266 const bool strict = true,
25267 const bool allow_exceptions = true,
25268 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25269 {
25270 basic_json result;
25271 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25272 auto ia = i.get();
25273 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25274 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25275 return res ? result : basic_json(value_t::discarded);
25276 }
25277
25364 template<typename InputType>
25365
25366 static basic_json from_msgpack(InputType&& i,
25367 const bool strict = true,
25368 const bool allow_exceptions = true)
25369 {
25370 basic_json result;
25371 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25372 auto ia = detail::input_adapter(std::forward<InputType>(i));
25373 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25374 return res ? result : basic_json(value_t::discarded);
25375 }
25380 template<typename IteratorType>
25381
25382 static basic_json from_msgpack(IteratorType first, IteratorType last,
25383 const bool strict = true,
25384 const bool allow_exceptions = true)
25385 {
25386 basic_json result;
25387 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25388 auto ia = detail::input_adapter(std::move(first), std::move(last));
25389 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25390 return res ? result : basic_json(value_t::discarded);
25391 }
25393
25394 template<typename T>
25395
25396 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25397 static basic_json from_msgpack(const T* ptr, std::size_t len,
25398 const bool strict = true,
25399 const bool allow_exceptions = true)
25400 {
25401 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
25402 }
25403
25404
25405 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25406 static basic_json from_msgpack(detail::span_input_adapter&& i,
25407 const bool strict = true,
25408 const bool allow_exceptions = true)
25409 {
25410 basic_json result;
25411 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25412 auto ia = i.get();
25413 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25414 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25415 return res ? result : basic_json(value_t::discarded);
25417
25418
25481 template<typename InputType>
25482
25483 static basic_json from_ubjson(InputType&& i,
25484 const bool strict = true,
25485 const bool allow_exceptions = true)
25486 {
25487 basic_json result;
25488 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25489 auto ia = detail::input_adapter(std::forward<InputType>(i));
25490 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25491 return res ? result : basic_json(value_t::discarded);
25492 }
25497 template<typename IteratorType>
25498
25499 static basic_json from_ubjson(IteratorType first, IteratorType last,
25500 const bool strict = true,
25501 const bool allow_exceptions = true)
25502 {
25503 basic_json result;
25504 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25505 auto ia = detail::input_adapter(std::move(first), std::move(last));
25506 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25507 return res ? result : basic_json(value_t::discarded);
25508 }
25510 template<typename T>
25511
25512 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25513 static basic_json from_ubjson(const T* ptr, std::size_t len,
25514 const bool strict = true,
25515 const bool allow_exceptions = true)
25516 {
25517 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
25518 }
25519
25520
25521 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25522 static basic_json from_ubjson(detail::span_input_adapter&& i,
25523 const bool strict = true,
25524 const bool allow_exceptions = true)
25525 {
25526 basic_json result;
25527 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25528 auto ia = i.get();
25529 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25530 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25531 return res ? result : basic_json(value_t::discarded);
25533
25534
25595 template<typename InputType>
25596
25597 static basic_json from_bson(InputType&& i,
25598 const bool strict = true,
25599 const bool allow_exceptions = true)
25600 {
25601 basic_json result;
25602 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25603 auto ia = detail::input_adapter(std::forward<InputType>(i));
25604 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25605 return res ? result : basic_json(value_t::discarded);
25606 }
25611 template<typename IteratorType>
25612
25613 static basic_json from_bson(IteratorType first, IteratorType last,
25614 const bool strict = true,
25615 const bool allow_exceptions = true)
25616 {
25617 basic_json result;
25618 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25619 auto ia = detail::input_adapter(std::move(first), std::move(last));
25620 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25621 return res ? result : basic_json(value_t::discarded);
25622 }
25624 template<typename T>
25625
25626 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25627 static basic_json from_bson(const T* ptr, std::size_t len,
25628 const bool strict = true,
25629 const bool allow_exceptions = true)
25630 {
25631 return from_bson(ptr, ptr + len, strict, allow_exceptions);
25632 }
25633
25634
25635 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25636 static basic_json from_bson(detail::span_input_adapter&& i,
25637 const bool strict = true,
25638 const bool allow_exceptions = true)
25639 {
25640 basic_json result;
25641 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25642 auto ia = i.get();
25643 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25644 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25645 return res ? result : basic_json(value_t::discarded);
25648
25650 // JSON Pointer support //
25652
25655
25690 {
25691 return ptr.get_unchecked(this);
25692 }
25693
25717 const_reference operator[](const json_pointer& ptr) const
25718 {
25719 return ptr.get_unchecked(this);
25720 }
25721
25760 reference at(const json_pointer& ptr)
25761 {
25762 return ptr.get_checked(this);
25763 }
25764
25803 const_reference at(const json_pointer& ptr) const
25804 {
25805 return ptr.get_checked(this);
25806 }
25807
25830 basic_json flatten() const
25831 {
25832 basic_json result(value_t::object);
25833 json_pointer::flatten("", *this, result);
25834 return result;
25835 }
25836
25867 basic_json unflatten() const
25868 {
25869 return json_pointer::unflatten(*this);
25870 }
25871
25873
25875 // JSON Patch functions //
25880
25928 basic_json patch(const basic_json& json_patch) const
25929 {
25930 // make a working copy to apply the patch to
25931 basic_json result = *this;
25932
25933 // the valid JSON Patch operations
25934 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
25935
25936 const auto get_op = [](const std::string & op)
25937 {
25938 if (op == "add")
25939 {
25940 return patch_operations::add;
25941 }
25942 if (op == "remove")
25943 {
25944 return patch_operations::remove;
25945 }
25946 if (op == "replace")
25947 {
25948 return patch_operations::replace;
25949 }
25950 if (op == "move")
25951 {
25952 return patch_operations::move;
25953 }
25954 if (op == "copy")
25955 {
25956 return patch_operations::copy;
25957 }
25958 if (op == "test")
25959 {
25960 return patch_operations::test;
25961 }
25962
25963 return patch_operations::invalid;
25964 };
25965
25966 // wrapper for "add" operation; add value at ptr
25967 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
25968 {
25969 // adding to the root of the target document means replacing it
25970 if (ptr.empty())
25971 {
25972 result = val;
25973 return;
25974 }
25975
25976 // make sure the top element of the pointer exists
25977 json_pointer top_pointer = ptr.top();
25978 if (top_pointer != ptr)
25979 {
25980 result.at(top_pointer);
25981 }
25982
25983 // get reference to parent of JSON pointer ptr
25984 const auto last_path = ptr.back();
25985 ptr.pop_back();
25986 basic_json& parent = result[ptr];
25987
25988 switch (parent.m_type)
25989 {
25990 case value_t::null:
25991 case value_t::object:
25992 {
25993 // use operator[] to add value
25994 parent[last_path] = val;
25995 break;
25996 }
25997
25998 case value_t::array:
25999 {
26000 if (last_path == "-")
26001 {
26002 // special case: append to back
26003 parent.push_back(val);
26004 }
26005 else
26006 {
26007 const auto idx = json_pointer::array_index(last_path);
26008 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
26009 {
26010 // avoid undefined behavior
26011 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
26012 }
26013
26014 // default case: insert add offset
26015 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
26016 }
26017 break;
26018 }
26019
26020 // if there exists a parent it cannot be primitive
26021 case value_t::string: // LCOV_EXCL_LINE
26022 case value_t::boolean: // LCOV_EXCL_LINE
26023 case value_t::number_integer: // LCOV_EXCL_LINE
26024 case value_t::number_unsigned: // LCOV_EXCL_LINE
26025 case value_t::number_float: // LCOV_EXCL_LINE
26026 case value_t::binary: // LCOV_EXCL_LINE
26027 case value_t::discarded: // LCOV_EXCL_LINE
26028 default: // LCOV_EXCL_LINE
26029 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
26030 }
26031 };
26032
26033 // wrapper for "remove" operation; remove value at ptr
26034 const auto operation_remove = [this, &result](json_pointer & ptr)
26035 {
26036 // get reference to parent of JSON pointer ptr
26037 const auto last_path = ptr.back();
26038 ptr.pop_back();
26039 basic_json& parent = result.at(ptr);
26040
26041 // remove child
26042 if (parent.is_object())
26043 {
26044 // perform range check
26045 auto it = parent.find(last_path);
26046 if (JSON_HEDLEY_LIKELY(it != parent.end()))
26047 {
26048 parent.erase(it);
26049 }
26050 else
26051 {
26052 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
26053 }
26054 }
26055 else if (parent.is_array())
26056 {
26057 // note erase performs range check
26058 parent.erase(json_pointer::array_index(last_path));
26059 }
26060 };
26061
26062 // type check: top level value must be an array
26063 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
26064 {
26065 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
26066 }
26067
26068 // iterate and apply the operations
26069 for (const auto& val : json_patch)
26070 {
26071 // wrapper to get a value for an operation
26072 const auto get_value = [&val](const std::string & op,
26073 const std::string & member,
26074 bool string_type) -> basic_json &
26075 {
26076 // find value
26077 auto it = val.m_value.object->find(member);
26078
26079 // context-sensitive error message
26080 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
26081
26082 // check if desired value is present
26083 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
26084 {
26085 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
26086 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
26087 }
26088
26089 // check if result is of type string
26090 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
26091 {
26092 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
26093 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
26094 }
26095
26096 // no error: return value
26097 return it->second;
26098 };
26099
26100 // type check: every element of the array must be an object
26101 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
26102 {
26103 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
26104 }
26105
26106 // collect mandatory members
26107 const auto op = get_value("op", "op", true).template get<std::string>();
26108 const auto path = get_value(op, "path", true).template get<std::string>();
26109 json_pointer ptr(path);
26110
26111 switch (get_op(op))
26112 {
26113 case patch_operations::add:
26114 {
26115 operation_add(ptr, get_value("add", "value", false));
26116 break;
26117 }
26118
26119 case patch_operations::remove:
26120 {
26121 operation_remove(ptr);
26122 break;
26123 }
26124
26125 case patch_operations::replace:
26126 {
26127 // the "path" location must exist - use at()
26128 result.at(ptr) = get_value("replace", "value", false);
26129 break;
26130 }
26131
26132 case patch_operations::move:
26133 {
26134 const auto from_path = get_value("move", "from", true).template get<std::string>();
26135 json_pointer from_ptr(from_path);
26136
26137 // the "from" location must exist - use at()
26138 basic_json v = result.at(from_ptr);
26139
26140 // The move operation is functionally identical to a
26141 // "remove" operation on the "from" location, followed
26142 // immediately by an "add" operation at the target
26143 // location with the value that was just removed.
26144 operation_remove(from_ptr);
26145 operation_add(ptr, v);
26146 break;
26147 }
26148
26149 case patch_operations::copy:
26150 {
26151 const auto from_path = get_value("copy", "from", true).template get<std::string>();
26152 const json_pointer from_ptr(from_path);
26153
26154 // the "from" location must exist - use at()
26155 basic_json v = result.at(from_ptr);
26156
26157 // The copy is functionally identical to an "add"
26158 // operation at the target location using the value
26159 // specified in the "from" member.
26160 operation_add(ptr, v);
26161 break;
26162 }
26163
26164 case patch_operations::test:
26165 {
26166 bool success = false;
26167 JSON_TRY
26168 {
26169 // check if "value" matches the one at "path"
26170 // the "path" location must exist - use at()
26171 success = (result.at(ptr) == get_value("test", "value", false));
26172 }
26173 JSON_INTERNAL_CATCH (out_of_range&)
26174 {
26175 // ignore out of range errors: success remains false
26176 }
26177
26178 // throw an exception if test fails
26179 if (JSON_HEDLEY_UNLIKELY(!success))
26180 {
26181 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
26182 }
26183
26184 break;
26185 }
26186
26187 case patch_operations::invalid:
26188 default:
26189 {
26190 // op must be "add", "remove", "replace", "move", "copy", or
26191 // "test"
26192 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
26193 }
26194 }
26195 }
26196
26197 return result;
26198 }
26199
26233
26234 static basic_json diff(const basic_json& source, const basic_json& target,
26235 const std::string& path = "")
26236 {
26237 // the patch
26238 basic_json result(value_t::array);
26239
26240 // if the values are the same, return empty patch
26241 if (source == target)
26242 {
26243 return result;
26245
26246 if (source.type() != target.type())
26247 {
26248 // different types: replace value
26249 result.push_back(
26250 {
26251 {"op", "replace"}, {"path", path}, {"value", target}
26252 });
26253 return result;
26254 }
26255
26256 switch (source.type())
26257 {
26258 case value_t::array:
26259 {
26260 // first pass: traverse common elements
26261 std::size_t i = 0;
26262 while (i < source.size() && i < target.size())
26263 {
26264 // recursive call to compare array values at index i
26265 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
26266 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26267 ++i;
26268 }
26269
26270 // i now reached the end of at least one array
26271 // in a second pass, traverse the remaining elements
26272
26273 // remove my remaining elements
26274 const auto end_index = static_cast<difference_type>(result.size());
26275 while (i < source.size())
26276 {
26277 // add operations in reverse order to avoid invalid
26278 // indices
26279 result.insert(result.begin() + end_index, object(
26280 {
26281 {"op", "remove"},
26282 {"path", path + "/" + std::to_string(i)}
26283 }));
26284 ++i;
26285 }
26286
26287 // add other remaining elements
26288 while (i < target.size())
26289 {
26290 result.push_back(
26291 {
26292 {"op", "add"},
26293 {"path", path + "/-"},
26294 {"value", target[i]}
26295 });
26296 ++i;
26297 }
26298
26299 break;
26300 }
26301
26302 case value_t::object:
26303 {
26304 // first pass: traverse this object's elements
26305 for (auto it = source.cbegin(); it != source.cend(); ++it)
26306 {
26307 // escape the key name to be used in a JSON patch
26308 const auto path_key = path + "/" + detail::escape(it.key());
26309
26310 if (target.find(it.key()) != target.end())
26311 {
26312 // recursive call to compare object values at key it
26313 auto temp_diff = diff(it.value(), target[it.key()], path_key);
26314 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26315 }
26316 else
26317 {
26318 // found a key that is not in o -> remove it
26319 result.push_back(object(
26320 {
26321 {"op", "remove"}, {"path", path_key}
26322 }));
26323 }
26324 }
26325
26326 // second pass: traverse other object's elements
26327 for (auto it = target.cbegin(); it != target.cend(); ++it)
26328 {
26329 if (source.find(it.key()) == source.end())
26330 {
26331 // found a key that is not in this -> add it
26332 const auto path_key = path + "/" + detail::escape(it.key());
26333 result.push_back(
26334 {
26335 {"op", "add"}, {"path", path_key},
26336 {"value", it.value()}
26337 });
26338 }
26339 }
26340
26341 break;
26342 }
26343
26344 case value_t::null:
26345 case value_t::string:
26346 case value_t::boolean:
26347 case value_t::number_integer:
26348 case value_t::number_unsigned:
26349 case value_t::number_float:
26350 case value_t::binary:
26351 case value_t::discarded:
26352 default:
26353 {
26354 // both primitive type: replace value
26355 result.push_back(
26356 {
26357 {"op", "replace"}, {"path", path}, {"value", target}
26358 });
26359 break;
26360 }
26361 }
26362
26363 return result;
26364 }
26365
26367
26369 // JSON Merge Patch functions //
26371
26374
26417 void merge_patch(const basic_json& apply_patch)
26418 {
26419 if (apply_patch.is_object())
26420 {
26421 if (!is_object())
26422 {
26423 *this = object();
26424 }
26425 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
26426 {
26427 if (it.value().is_null())
26428 {
26429 erase(it.key());
26430 }
26431 else
26432 {
26433 operator[](it.key()).merge_patch(it.value());
26434 }
26435 }
26436 }
26437 else
26438 {
26439 *this = apply_patch;
26440 }
26441 }
26442
26444};
26445
26455NLOHMANN_BASIC_JSON_TPL_DECLARATION
26456std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
26457{
26458 return j.dump();
26459}
26460} // namespace nlohmann
26461
26463// nonmember support //
26465
26466// specialization of std::swap, and std::hash
26467namespace std
26468{
26469
26471template<>
26472struct hash<nlohmann::json>
26473{
26479 std::size_t operator()(const nlohmann::json& j) const
26480 {
26481 return nlohmann::detail::hash(j);
26483};
26484
26488template<>
26489struct less<::nlohmann::detail::value_t>
26490{
26495 bool operator()(nlohmann::detail::value_t lhs,
26496 nlohmann::detail::value_t rhs) const noexcept
26497 {
26498 return nlohmann::detail::operator<(lhs, rhs);
26499 }
26500};
26501
26502// C++20 prohibit function specialization in the std namespace.
26503#ifndef JSON_HAS_CPP_20
26504
26510template<>
26511inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
26512 is_nothrow_move_constructible<nlohmann::json>::value&& // NOLINT(misc-redundant-expression)
26513 is_nothrow_move_assignable<nlohmann::json>::value
26514 )
26515{
26516 j1.swap(j2);
26517}
26518
26519#endif
26520
26521} // namespace std
26522
26536JSON_HEDLEY_NON_NULL(1)
26537inline nlohmann::json operator "" _json(const char* s, std::size_t n)
26538{
26539 return nlohmann::json::parse(s, s + n);
26540}
26541
26555JSON_HEDLEY_NON_NULL(1)
26556inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
26557{
26558 return nlohmann::json::json_pointer(std::string(s, n));
26559}
26560
26561// #include <nlohmann/detail/macro_unscope.hpp>
26562
26563
26564// restore clang diagnostic settings
26565#if defined(__clang__)
26566 #pragma clang diagnostic pop
26567#endif
26568
26569// clean up
26570#undef JSON_ASSERT
26571#undef JSON_INTERNAL_CATCH
26572#undef JSON_CATCH
26573#undef JSON_THROW
26574#undef JSON_TRY
26575#undef JSON_PRIVATE_UNLESS_TESTED
26576#undef JSON_HAS_CPP_11
26577#undef JSON_HAS_CPP_14
26578#undef JSON_HAS_CPP_17
26579#undef JSON_HAS_CPP_20
26580#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
26581#undef NLOHMANN_BASIC_JSON_TPL
26582#undef JSON_EXPLICIT
26583#undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
26584
26585// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
26586
26587
26588#undef JSON_HEDLEY_ALWAYS_INLINE
26589#undef JSON_HEDLEY_ARM_VERSION
26590#undef JSON_HEDLEY_ARM_VERSION_CHECK
26591#undef JSON_HEDLEY_ARRAY_PARAM
26592#undef JSON_HEDLEY_ASSUME
26593#undef JSON_HEDLEY_BEGIN_C_DECLS
26594#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
26595#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
26596#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
26597#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
26598#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
26599#undef JSON_HEDLEY_CLANG_HAS_FEATURE
26600#undef JSON_HEDLEY_CLANG_HAS_WARNING
26601#undef JSON_HEDLEY_COMPCERT_VERSION
26602#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
26603#undef JSON_HEDLEY_CONCAT
26604#undef JSON_HEDLEY_CONCAT3
26605#undef JSON_HEDLEY_CONCAT3_EX
26606#undef JSON_HEDLEY_CONCAT_EX
26607#undef JSON_HEDLEY_CONST
26608#undef JSON_HEDLEY_CONSTEXPR
26609#undef JSON_HEDLEY_CONST_CAST
26610#undef JSON_HEDLEY_CPP_CAST
26611#undef JSON_HEDLEY_CRAY_VERSION
26612#undef JSON_HEDLEY_CRAY_VERSION_CHECK
26613#undef JSON_HEDLEY_C_DECL
26614#undef JSON_HEDLEY_DEPRECATED
26615#undef JSON_HEDLEY_DEPRECATED_FOR
26616#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
26617#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
26618#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
26619#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
26620#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
26621#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
26622#undef JSON_HEDLEY_DIAGNOSTIC_POP
26623#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
26624#undef JSON_HEDLEY_DMC_VERSION
26625#undef JSON_HEDLEY_DMC_VERSION_CHECK
26626#undef JSON_HEDLEY_EMPTY_BASES
26627#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
26628#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
26629#undef JSON_HEDLEY_END_C_DECLS
26630#undef JSON_HEDLEY_FLAGS
26631#undef JSON_HEDLEY_FLAGS_CAST
26632#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
26633#undef JSON_HEDLEY_GCC_HAS_BUILTIN
26634#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
26635#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
26636#undef JSON_HEDLEY_GCC_HAS_EXTENSION
26637#undef JSON_HEDLEY_GCC_HAS_FEATURE
26638#undef JSON_HEDLEY_GCC_HAS_WARNING
26639#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
26640#undef JSON_HEDLEY_GCC_VERSION
26641#undef JSON_HEDLEY_GCC_VERSION_CHECK
26642#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
26643#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
26644#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
26645#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
26646#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
26647#undef JSON_HEDLEY_GNUC_HAS_FEATURE
26648#undef JSON_HEDLEY_GNUC_HAS_WARNING
26649#undef JSON_HEDLEY_GNUC_VERSION
26650#undef JSON_HEDLEY_GNUC_VERSION_CHECK
26651#undef JSON_HEDLEY_HAS_ATTRIBUTE
26652#undef JSON_HEDLEY_HAS_BUILTIN
26653#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
26654#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
26655#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
26656#undef JSON_HEDLEY_HAS_EXTENSION
26657#undef JSON_HEDLEY_HAS_FEATURE
26658#undef JSON_HEDLEY_HAS_WARNING
26659#undef JSON_HEDLEY_IAR_VERSION
26660#undef JSON_HEDLEY_IAR_VERSION_CHECK
26661#undef JSON_HEDLEY_IBM_VERSION
26662#undef JSON_HEDLEY_IBM_VERSION_CHECK
26663#undef JSON_HEDLEY_IMPORT
26664#undef JSON_HEDLEY_INLINE
26665#undef JSON_HEDLEY_INTEL_CL_VERSION
26666#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
26667#undef JSON_HEDLEY_INTEL_VERSION
26668#undef JSON_HEDLEY_INTEL_VERSION_CHECK
26669#undef JSON_HEDLEY_IS_CONSTANT
26670#undef JSON_HEDLEY_IS_CONSTEXPR_
26671#undef JSON_HEDLEY_LIKELY
26672#undef JSON_HEDLEY_MALLOC
26673#undef JSON_HEDLEY_MCST_LCC_VERSION
26674#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
26675#undef JSON_HEDLEY_MESSAGE
26676#undef JSON_HEDLEY_MSVC_VERSION
26677#undef JSON_HEDLEY_MSVC_VERSION_CHECK
26678#undef JSON_HEDLEY_NEVER_INLINE
26679#undef JSON_HEDLEY_NON_NULL
26680#undef JSON_HEDLEY_NO_ESCAPE
26681#undef JSON_HEDLEY_NO_RETURN
26682#undef JSON_HEDLEY_NO_THROW
26683#undef JSON_HEDLEY_NULL
26684#undef JSON_HEDLEY_PELLES_VERSION
26685#undef JSON_HEDLEY_PELLES_VERSION_CHECK
26686#undef JSON_HEDLEY_PGI_VERSION
26687#undef JSON_HEDLEY_PGI_VERSION_CHECK
26688#undef JSON_HEDLEY_PREDICT
26689#undef JSON_HEDLEY_PRINTF_FORMAT
26690#undef JSON_HEDLEY_PRIVATE
26691#undef JSON_HEDLEY_PUBLIC
26692#undef JSON_HEDLEY_PURE
26693#undef JSON_HEDLEY_REINTERPRET_CAST
26694#undef JSON_HEDLEY_REQUIRE
26695#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
26696#undef JSON_HEDLEY_REQUIRE_MSG
26697#undef JSON_HEDLEY_RESTRICT
26698#undef
26699#undef JSON_HEDLEY_SENTINEL
26700#undef JSON_HEDLEY_STATIC_ASSERT
26701#undef JSON_HEDLEY_STATIC_CAST
26702#undef JSON_HEDLEY_STRINGIFY
26703#undef JSON_HEDLEY_STRINGIFY_EX
26704#undef JSON_HEDLEY_SUNPRO_VERSION
26705#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
26706#undef JSON_HEDLEY_TINYC_VERSION
26707#undef JSON_HEDLEY_TINYC_VERSION_CHECK
26708#undef JSON_HEDLEY_TI_ARMCL_VERSION
26709#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
26710#undef JSON_HEDLEY_TI_CL2000_VERSION
26711#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
26712#undef JSON_HEDLEY_TI_CL430_VERSION
26713#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
26714#undef JSON_HEDLEY_TI_CL6X_VERSION
26715#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
26716#undef JSON_HEDLEY_TI_CL7X_VERSION
26717#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
26718#undef JSON_HEDLEY_TI_CLPRU_VERSION
26719#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
26720#undef JSON_HEDLEY_TI_VERSION
26721#undef JSON_HEDLEY_TI_VERSION_CHECK
26722#undef JSON_HEDLEY_UNAVAILABLE
26723#undef JSON_HEDLEY_UNLIKELY
26724#undef JSON_HEDLEY_UNPREDICTABLE
26725#undef JSON_HEDLEY_UNREACHABLE
26726#undef JSON_HEDLEY_UNREACHABLE_RETURN
26727#undef JSON_HEDLEY_VERSION
26728#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
26729#undef JSON_HEDLEY_VERSION_DECODE_MINOR
26730#undef JSON_HEDLEY_VERSION_DECODE_REVISION
26731#undef JSON_HEDLEY_VERSION_ENCODE
26732#undef JSON_HEDLEY_WARNING
26733#undef
26734#undef _MSG
26735#undef JSON_HEDLEY_FALL_THROUGH
26736
26737
26738
26739#endif // INCLUDE_NLOHMANN_JSON_HPP_
ValueType & get_to(ValueType &v) const
Definition: json.hpp:20792
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:18920
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:22107
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:22567
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:22392
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21486
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:20175
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:18198
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:23859
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:24549
detail::exception exception
general exception of the basic_json class
Definition: json.hpp:17749
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:20839
static 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:24394
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:23141
static basic_json from_cbor(const T *ptr, std::size_t len, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:25264
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:18961
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:22790
static 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:26244
detail::input_format_t input_format_t
Definition: json.hpp:17736
static std::vector< std::uint8_t > to_bson(const basic_json &j)
Serializes the given JSON object j to BSON and returns a vector containing the corresponding BSON-rep...
Definition: json.hpp:25099
value_type & reference
the type of an element reference
Definition: json.hpp:17777
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:22421
detail::out_of_range out_of_range
exception indicating access out of the defined range
Definition: json.hpp:17757
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:22177
binary_t & get_binary()
Definition: json.hpp:20915
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:19540
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:24918
basic_json(const JsonRef &ref)
Definition: json.hpp:19650
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:24823
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:19807
static basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:19403
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:22288
reference back()
access the last element
Definition: json.hpp:21656
const binary_t & get_binary() const
Definition: json.hpp:20926
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition: json.hpp:24486
StringType string_t
a type for a string
Definition: json.hpp:18100
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:22712
static basic_json meta()
returns version information on the library
Definition: json.hpp:17841
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:23497
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:17784
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:20779
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:17782
static basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:19300
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:22975
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:19095
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:17792
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:17790
static 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:25232
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:18126
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:23093
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:19905
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21723
static 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:25607
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:20016
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:20973
static 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:19357
reference front()
access the first element
Definition: json.hpp:21612
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:19989
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:20147
detail::cbor_tag_handler_t cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:17732
detail::parse_error parse_error
exception indicating a parse error
Definition: json.hpp:17751
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:20197
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:19958
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:18337
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:17799
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:24302
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:24143
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:22632
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:19677
~basic_json() noexcept
destructor
Definition: json.hpp:19841
friend struct detail::external_constructor
Definition: json.hpp:17666
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:25021
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:19769
detail::invalid_iterator invalid_iterator
exception indicating errors with iterators
Definition: json.hpp:17753
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:23975
detail::other_error other_error
exception indicating other library errors
Definition: json.hpp:17759
json_value m_value
the value of the current element
Definition: json.hpp:24710
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:24235
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:22355
static 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:19337
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:22485
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:20852
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:20735
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:26427
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20493
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:18047
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.hpp:20803
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:24189
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:20060
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:22248
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:23605
void clear() noexcept
clears the contents
Definition: json.hpp:22869
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:20263
static basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:19447
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:21178
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:17795
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:17801
static 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:25493
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:17726
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:24028
static basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array (without subtype)
Definition: json.hpp:19347
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:20241
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:20219
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.hpp:23223
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:25840
const char * type_name() const noexcept
return the type as string
Definition: json.hpp:24672
const value_type & const_reference
the type of an element const reference
Definition: json.hpp:17779
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:22948
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:22074
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:20090
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:24326
std::less< StringType > object_comparator_t
Definition: json.hpp:17911
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:20119
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:17734
detail::value_t value_t
Definition: json.hpp:17724
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:22023
detail::type_error type_error
exception indicating executing a member function with a wrong type
Definition: json.hpp:17755
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:18985
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:17787
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:18408
JSONSerializer< T, SFINAE > json_serializer
Definition: json.hpp:17728
static 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:25376
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:25938
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
Definition: json.hpp:19057
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:25877
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:18269
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:22217
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:19219
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:23262
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.hpp:17797
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:20290
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:20038
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > > > object_t
a type for an object
Definition: json.hpp:18001
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:20694
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:23191
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:19474
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:17809
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:20506
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:22318
a class to store JSON values
Definition: json.hpp:17664
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5133
BinaryType container_type
the type of the underlying container
Definition: json.hpp:5117
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.hpp:5125
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5129
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5151
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5247
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.hpp:5121
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.hpp:5139
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:5223
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:5174
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:5202
std::uint64_t subtype_type
the type of the subtype
Definition: json.hpp:5119
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.hpp:5145
an internal type for a backed binary type
Definition: json.hpp:5114
json_pointer & operator/=(std::string token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:12563
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:12539
std::string to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:12507
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for equality
Definition: json.hpp:13405
void pop_back()
remove last reference token
Definition: json.hpp:12689
const std::string & back() const
return last reference token
Definition: json.hpp:12713
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:12760
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.hpp:13422
void push_back(const std::string &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:12735
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:12489
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:12605
friend json_pointer operator/(const json_pointer &ptr, std::string token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.hpp:12626
void push_back(std::string &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:12741
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:12585
friend json_pointer operator/(const json_pointer &ptr, 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:12646
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:12664
JSON Pointer.
Definition: json.hpp:12462
constexpr const auto & to_json
Definition: json.hpp:5016
constexpr const auto & from_json
Definition: json.hpp:4412
basic_json<> json
default JSON class
Definition: json.hpp:3472
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:26466
NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin)
namespace for Niels Lohmann
Definition: json.hpp:89
STL namespace.
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:5043
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:5063
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:5080
default JSONSerializer template argument
Definition: json.hpp:5030
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
virtual bool string(string_t &val)=0
a string was read
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.hpp:5924
typename BasicJsonType::binary_t binary_t
Definition: json.hpp:5928
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:5925
virtual bool binary(binary_t &val)=0
a binary string was read
typename BasicJsonType::number_float_t number_float_t
Definition: json.hpp:5926
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
json_sax & operator=(const json_sax &)=default
virtual bool end_object()=0
the end of an object was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
typename BasicJsonType::string_t string_t
Definition: json.hpp:5927
virtual bool number_float(number_float_t val, const string_t &s)=0
an floating-point number was read
virtual bool number_integer(number_integer_t val)=0
an integer number was read
SAX interface.
Definition: json.hpp:5923
T & at(const Key &key)
Definition: json.hpp:17436
ordered_map(std::initializer_list< T > init, const Allocator &alloc=Allocator())
Definition: json.hpp:17410
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.hpp:17398
const T & at(const Key &key) const
Definition: json.hpp:17449
iterator find(const Key &key)
Definition: json.hpp:17507
iterator erase(iterator pos)
Definition: json.hpp:17481
void insert(InputIt first, InputIt last)
Definition: json.hpp:17554
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.hpp:17531
const_iterator find(const Key &key) const
Definition: json.hpp:17519
size_type erase(const Key &key)
Definition: json.hpp:17462
T & operator[](const Key &key)
Definition: json.hpp:17426
ordered_map(const Allocator &alloc=Allocator())
Definition: json.hpp:17406
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:17551
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.hpp:17408
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.hpp:17536
size_type count(const Key &key) const
Definition: json.hpp:17495
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.hpp:17413
const T & operator[](const Key &key) const
Definition: json.hpp:17431