xrootd
Loading...
Searching...
No Matches
XrdOucJson.hh
Go to the documentation of this file.
1/*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++
4| | |__ | | | | | | version 3.10.2
5|_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8SPDX-License-Identifier: MIT
9Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10
11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal
13in the Software without restriction, including without limitation the rights
14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15copies of the Software, and to permit persons to whom the Software is
16furnished to do so, subject to the following conditions:
17
18The above copyright notice and this permission notice shall be included in all
19copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27SOFTWARE.
28*/
29
30#ifndef INCLUDE_NLOHMANN_JSON_HPP_
31#define INCLUDE_NLOHMANN_JSON_HPP_
32
33#define NLOHMANN_JSON_VERSION_MAJOR 3
34#define NLOHMANN_JSON_VERSION_MINOR 10
35#define NLOHMANN_JSON_VERSION_PATCH 2
36
37#include <algorithm> // all_of, find, for_each
38#include <cstddef> // nullptr_t, ptrdiff_t, size_t
39#include <functional> // hash, less
40#include <initializer_list> // initializer_list
41#ifndef JSON_NO_IO
42 #include <iosfwd> // istream, ostream
43#endif // JSON_NO_IO
44#include <iterator> // random_access_iterator_tag
45#include <memory> // unique_ptr
46#include <numeric> // accumulate
47#include <string> // string, stoi, to_string
48#include <utility> // declval, forward, move, pair, swap
49#include <vector> // vector
50
51// #include <nlohmann/adl_serializer.hpp>
52
53
54#include <type_traits>
55#include <utility>
56
57// #include <nlohmann/detail/conversions/from_json.hpp>
58
59
60#include <algorithm> // transform
61#include <array> // array
62#include <forward_list> // forward_list
63#include <iterator> // inserter, front_inserter, end
64#include <map> // map
65#include <string> // string
66#include <tuple> // tuple, make_tuple
67#include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
68#include <unordered_map> // unordered_map
69#include <utility> // pair, declval
70#include <valarray> // valarray
71
72// #include <nlohmann/detail/exceptions.hpp>
73
74
75#include <exception> // exception
76#include <stdexcept> // runtime_error
77#include <string> // to_string
78#include <vector> // vector
79
80// #include <nlohmann/detail/value_t.hpp>
81
82
83#include <array> // array
84#include <cstddef> // size_t
85#include <cstdint> // uint8_t
86#include <string> // string
87
88namespace nlohmann
89{
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,
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> // pair
171// #include <nlohmann/thirdparty/hedley/hedley.hpp>
172
173
174/* Hedley - https://nemequ.github.io/hedley
175 * Created by Evan Nemerson <evan@nemerson.com>
176 *
177 * To the extent possible under law, the author(s) have dedicated all
178 * copyright and related and neighboring rights to this software to
179 * the public domain worldwide. This software is distributed without
180 * any warranty.
181 *
182 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
183 * SPDX-License-Identifier: CC0-1.0
184 */
185
186#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
187#if defined(JSON_HEDLEY_VERSION)
188 #undef JSON_HEDLEY_VERSION
189#endif
190#define JSON_HEDLEY_VERSION 15
191
192#if defined(JSON_HEDLEY_STRINGIFY_EX)
193 #undef JSON_HEDLEY_STRINGIFY_EX
194#endif
195#define JSON_HEDLEY_STRINGIFY_EX(x) #x
196
197#if defined(JSON_HEDLEY_STRINGIFY)
198 #undef JSON_HEDLEY_STRINGIFY
199#endif
200#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
201
202#if defined(JSON_HEDLEY_CONCAT_EX)
203 #undef JSON_HEDLEY_CONCAT_EX
204#endif
205#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
206
207#if defined(JSON_HEDLEY_CONCAT)
208 #undef JSON_HEDLEY_CONCAT
209#endif
210#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
211
212#if defined(JSON_HEDLEY_CONCAT3_EX)
213 #undef JSON_HEDLEY_CONCAT3_EX
214#endif
215#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
216
217#if defined(JSON_HEDLEY_CONCAT3)
218 #undef JSON_HEDLEY_CONCAT3
219#endif
220#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
221
222#if defined(JSON_HEDLEY_VERSION_ENCODE)
223 #undef JSON_HEDLEY_VERSION_ENCODE
224#endif
225#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
226
227#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
228 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
229#endif
230#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
231
232#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
233 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
234#endif
235#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
236
237#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
238 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
239#endif
240#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
241
242#if defined(JSON_HEDLEY_GNUC_VERSION)
243 #undef JSON_HEDLEY_GNUC_VERSION
244#endif
245#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
246 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
247#elif defined(__GNUC__)
248 #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
249#endif
250
251#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
252 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
253#endif
254#if defined(JSON_HEDLEY_GNUC_VERSION)
255 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
256#else
257 #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
258#endif
259
260#if defined(JSON_HEDLEY_MSVC_VERSION)
261 #undef JSON_HEDLEY_MSVC_VERSION
262#endif
263#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
264 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
265#elif defined(_MSC_FULL_VER) && !defined(__ICL)
266 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
267#elif defined(_MSC_VER) && !defined(__ICL)
268 #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
269#endif
270
271#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
272 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
273#endif
274#if !defined(JSON_HEDLEY_MSVC_VERSION)
275 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
276#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
277 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
278#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
279 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
280#else
281 #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
282#endif
283
284#if defined(JSON_HEDLEY_INTEL_VERSION)
285 #undef JSON_HEDLEY_INTEL_VERSION
286#endif
287#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
288 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
289#elif defined(__INTEL_COMPILER) && !defined(__ICL)
290 #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
291#endif
292
293#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
294 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
295#endif
296#if defined(JSON_HEDLEY_INTEL_VERSION)
297 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
298#else
299 #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
300#endif
301
302#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
303 #undef JSON_HEDLEY_INTEL_CL_VERSION
304#endif
305#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
306 #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
307#endif
308
309#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
310 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
311#endif
312#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
313 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
314#else
315 #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
316#endif
317
318#if defined(JSON_HEDLEY_PGI_VERSION)
319 #undef JSON_HEDLEY_PGI_VERSION
320#endif
321#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
322 #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
323#endif
324
325#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
326 #undef JSON_HEDLEY_PGI_VERSION_CHECK
327#endif
328#if defined(JSON_HEDLEY_PGI_VERSION)
329 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
330#else
331 #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
332#endif
333
334#if defined(JSON_HEDLEY_SUNPRO_VERSION)
335 #undef JSON_HEDLEY_SUNPRO_VERSION
336#endif
337#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
338 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10)
339#elif defined(__SUNPRO_C)
340 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
341#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
342 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10)
343#elif defined(__SUNPRO_CC)
344 #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
345#endif
346
347#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
348 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
349#endif
350#if defined(JSON_HEDLEY_SUNPRO_VERSION)
351 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
352#else
353 #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
354#endif
355
356#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
357 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
358#endif
359#if defined(__EMSCRIPTEN__)
360 #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
361#endif
362
363#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
364 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
365#endif
366#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
367 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
368#else
369 #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
370#endif
371
372#if defined(JSON_HEDLEY_ARM_VERSION)
373 #undef JSON_HEDLEY_ARM_VERSION
374#endif
375#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
376 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
377#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
378 #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
379#endif
380
381#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
382 #undef JSON_HEDLEY_ARM_VERSION_CHECK
383#endif
384#if defined(JSON_HEDLEY_ARM_VERSION)
385 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
386#else
387 #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
388#endif
389
390#if defined(JSON_HEDLEY_IBM_VERSION)
391 #undef JSON_HEDLEY_IBM_VERSION
392#endif
393#if defined(__ibmxl__)
394 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
395#elif defined(__xlC__) && defined(__xlC_ver__)
396 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
397#elif defined(__xlC__)
398 #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
399#endif
400
401#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
402 #undef JSON_HEDLEY_IBM_VERSION_CHECK
403#endif
404#if defined(JSON_HEDLEY_IBM_VERSION)
405 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
406#else
407 #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
408#endif
409
410#if defined(JSON_HEDLEY_TI_VERSION)
411 #undef JSON_HEDLEY_TI_VERSION
412#endif
413#if \
414 defined(__TI_COMPILER_VERSION__) && \
415 ( \
416 defined(__TMS470__) || defined(__TI_ARM__) || \
417 defined(__MSP430__) || \
418 defined(__TMS320C2000__) \
419 )
420#if (__TI_COMPILER_VERSION__ >= 16000000)
421 #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
422#endif
423#endif
424
425#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
426 #undef JSON_HEDLEY_TI_VERSION_CHECK
427#endif
428#if defined(JSON_HEDLEY_TI_VERSION)
429 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
430#else
431 #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
432#endif
433
434#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
435 #undef JSON_HEDLEY_TI_CL2000_VERSION
436#endif
437#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
438 #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
439#endif
440
441#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
442 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
443#endif
444#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
445 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
446#else
447 #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
448#endif
449
450#if defined(JSON_HEDLEY_TI_CL430_VERSION)
451 #undef JSON_HEDLEY_TI_CL430_VERSION
452#endif
453#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
454 #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
455#endif
456
457#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
458 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
459#endif
460#if defined(JSON_HEDLEY_TI_CL430_VERSION)
461 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
462#else
463 #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
464#endif
465
466#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
467 #undef JSON_HEDLEY_TI_ARMCL_VERSION
468#endif
469#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
470 #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
471#endif
472
473#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
474 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
475#endif
476#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
477 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
478#else
479 #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
480#endif
481
482#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
483 #undef JSON_HEDLEY_TI_CL6X_VERSION
484#endif
485#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
486 #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
487#endif
488
489#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
490 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
491#endif
492#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
493 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
494#else
495 #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
496#endif
497
498#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
499 #undef JSON_HEDLEY_TI_CL7X_VERSION
500#endif
501#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
502 #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
503#endif
504
505#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
506 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
507#endif
508#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
509 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
510#else
511 #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
512#endif
513
514#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
515 #undef JSON_HEDLEY_TI_CLPRU_VERSION
516#endif
517#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
518 #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
519#endif
520
521#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
522 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
523#endif
524#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
525 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
526#else
527 #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
528#endif
529
530#if defined(JSON_HEDLEY_CRAY_VERSION)
531 #undef JSON_HEDLEY_CRAY_VERSION
532#endif
533#if defined(_CRAYC)
534 #if defined(_RELEASE_PATCHLEVEL)
535 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
536 #else
537 #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
538 #endif
539#endif
540
541#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
542 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
543#endif
544#if defined(JSON_HEDLEY_CRAY_VERSION)
545 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
546#else
547 #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
548#endif
549
550#if defined(JSON_HEDLEY_IAR_VERSION)
551 #undef JSON_HEDLEY_IAR_VERSION
552#endif
553#if defined(__IAR_SYSTEMS_ICC__)
554 #if __VER__ > 1000
555 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
556 #else
557 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
558 #endif
559#endif
560
561#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
562 #undef JSON_HEDLEY_IAR_VERSION_CHECK
563#endif
564#if defined(JSON_HEDLEY_IAR_VERSION)
565 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
566#else
567 #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
568#endif
569
570#if defined(JSON_HEDLEY_TINYC_VERSION)
571 #undef JSON_HEDLEY_TINYC_VERSION
572#endif
573#if defined(__TINYC__)
574 #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
575#endif
576
577#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
578 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
579#endif
580#if defined(JSON_HEDLEY_TINYC_VERSION)
581 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
582#else
583 #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
584#endif
585
586#if defined(JSON_HEDLEY_DMC_VERSION)
587 #undef JSON_HEDLEY_DMC_VERSION
588#endif
589#if defined(__DMC__)
590 #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
591#endif
592
593#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
594 #undef JSON_HEDLEY_DMC_VERSION_CHECK
595#endif
596#if defined(JSON_HEDLEY_DMC_VERSION)
597 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
598#else
599 #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
600#endif
601
602#if defined(JSON_HEDLEY_COMPCERT_VERSION)
603 #undef JSON_HEDLEY_COMPCERT_VERSION
604#endif
605#if defined(__COMPCERT_VERSION__)
606 #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
607#endif
608
609#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
610 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
611#endif
612#if defined(JSON_HEDLEY_COMPCERT_VERSION)
613 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
614#else
615 #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
616#endif
617
618#if defined(JSON_HEDLEY_PELLES_VERSION)
619 #undef JSON_HEDLEY_PELLES_VERSION
620#endif
621#if defined(__POCC__)
622 #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
623#endif
624
625#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
626 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
627#endif
628#if defined(JSON_HEDLEY_PELLES_VERSION)
629 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
630#else
631 #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
632#endif
633
634#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
635 #undef JSON_HEDLEY_MCST_LCC_VERSION
636#endif
637#if defined(__LCC__) && defined(__LCC_MINOR__)
638 #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
639#endif
640
641#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
642 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
643#endif
644#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
645 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
646#else
647 #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
648#endif
649
650#if defined(JSON_HEDLEY_GCC_VERSION)
651 #undef JSON_HEDLEY_GCC_VERSION
652#endif
653#if \
654 defined(JSON_HEDLEY_GNUC_VERSION) && \
655 !defined(__clang__) && \
656 !defined(JSON_HEDLEY_INTEL_VERSION) && \
657 !defined(JSON_HEDLEY_PGI_VERSION) && \
658 !defined(JSON_HEDLEY_ARM_VERSION) && \
659 !defined(JSON_HEDLEY_CRAY_VERSION) && \
660 !defined(JSON_HEDLEY_TI_VERSION) && \
661 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
662 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
663 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
664 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
665 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
666 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
667 !defined(__COMPCERT__) && \
668 !defined(JSON_HEDLEY_MCST_LCC_VERSION)
669 #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
670#endif
671
672#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
673 #undef JSON_HEDLEY_GCC_VERSION_CHECK
674#endif
675#if defined(JSON_HEDLEY_GCC_VERSION)
676 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
677#else
678 #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
679#endif
680
681#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
682 #undef JSON_HEDLEY_HAS_ATTRIBUTE
683#endif
684#if \
685 defined(__has_attribute) && \
686 ( \
687 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
688 )
689# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
690#else
691# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
692#endif
693
694#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
695 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
696#endif
697#if defined(__has_attribute)
698 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
699#else
700 #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
701#endif
702
703#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
704 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
705#endif
706#if defined(__has_attribute)
707 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
708#else
709 #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
710#endif
711
712#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
713 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
714#endif
715#if \
716 defined(__has_cpp_attribute) && \
717 defined(__cplusplus) && \
718 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
719 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
720#else
721 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
722#endif
723
724#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
725 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
726#endif
727#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
728 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
729#elif \
730 !defined(JSON_HEDLEY_PGI_VERSION) && \
731 !defined(JSON_HEDLEY_IAR_VERSION) && \
732 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
733 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
734 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
735#else
736 #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
737#endif
738
739#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
740 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
741#endif
742#if defined(__has_cpp_attribute) && defined(__cplusplus)
743 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
744#else
745 #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
746#endif
747
748#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
749 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
750#endif
751#if defined(__has_cpp_attribute) && defined(__cplusplus)
752 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
753#else
754 #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
755#endif
756
757#if defined(JSON_HEDLEY_HAS_BUILTIN)
758 #undef JSON_HEDLEY_HAS_BUILTIN
759#endif
760#if defined(__has_builtin)
761 #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
762#else
763 #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
764#endif
765
766#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
767 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
768#endif
769#if defined(__has_builtin)
770 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
771#else
772 #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
773#endif
774
775#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
776 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
777#endif
778#if defined(__has_builtin)
779 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
780#else
781 #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
782#endif
783
784#if defined(JSON_HEDLEY_HAS_FEATURE)
785 #undef JSON_HEDLEY_HAS_FEATURE
786#endif
787#if defined(__has_feature)
788 #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
789#else
790 #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
791#endif
792
793#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
794 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
795#endif
796#if defined(__has_feature)
797 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
798#else
799 #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
800#endif
801
802#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
803 #undef JSON_HEDLEY_GCC_HAS_FEATURE
804#endif
805#if defined(__has_feature)
806 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
807#else
808 #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
809#endif
810
811#if defined(JSON_HEDLEY_HAS_EXTENSION)
812 #undef JSON_HEDLEY_HAS_EXTENSION
813#endif
814#if defined(__has_extension)
815 #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
816#else
817 #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
818#endif
819
820#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
821 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
822#endif
823#if defined(__has_extension)
824 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
825#else
826 #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
827#endif
828
829#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
830 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
831#endif
832#if defined(__has_extension)
833 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
834#else
835 #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
836#endif
837
838#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
839 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
840#endif
841#if defined(__has_declspec_attribute)
842 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
843#else
844 #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
845#endif
846
847#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
848 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
849#endif
850#if defined(__has_declspec_attribute)
851 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
852#else
853 #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
854#endif
855
856#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
857 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
858#endif
859#if defined(__has_declspec_attribute)
860 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
861#else
862 #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
863#endif
864
865#if defined(JSON_HEDLEY_HAS_WARNING)
866 #undef JSON_HEDLEY_HAS_WARNING
867#endif
868#if defined(__has_warning)
869 #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
870#else
871 #define JSON_HEDLEY_HAS_WARNING(warning) (0)
872#endif
873
874#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
875 #undef JSON_HEDLEY_GNUC_HAS_WARNING
876#endif
877#if defined(__has_warning)
878 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
879#else
880 #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
881#endif
882
883#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
884 #undef JSON_HEDLEY_GCC_HAS_WARNING
885#endif
886#if defined(__has_warning)
887 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
888#else
889 #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
890#endif
891
892#if \
893 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
894 defined(__clang__) || \
895 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
896 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
897 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
898 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
899 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
900 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
901 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
902 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
903 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
904 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
905 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
906 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
907 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
908 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
909 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
910 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
911 #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
912#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
913 #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
914#else
915 #define JSON_HEDLEY_PRAGMA(value)
916#endif
917
918#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
919 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
920#endif
921#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
922 #undef JSON_HEDLEY_DIAGNOSTIC_POP
923#endif
924#if defined(__clang__)
925 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
926 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
927#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
928 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
929 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
930#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
931 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
932 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
933#elif \
934 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
935 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
936 #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
937 #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
938#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
939 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
940 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
941#elif \
942 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
943 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
944 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
945 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
946 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
947 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
948 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
949 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
950#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
951 #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
952 #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
953#else
954 #define JSON_HEDLEY_DIAGNOSTIC_PUSH
955 #define JSON_HEDLEY_DIAGNOSTIC_POP
956#endif
957
958/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
959 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
960#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
961 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
962#endif
963#if defined(__cplusplus)
964# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
965# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
966# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
967# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
968 JSON_HEDLEY_DIAGNOSTIC_PUSH \
969 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
970 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
971 _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
972 xpr \
973 JSON_HEDLEY_DIAGNOSTIC_POP
974# else
975# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
976 JSON_HEDLEY_DIAGNOSTIC_PUSH \
977 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
978 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
979 xpr \
980 JSON_HEDLEY_DIAGNOSTIC_POP
981# endif
982# else
983# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
984 JSON_HEDLEY_DIAGNOSTIC_PUSH \
985 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
986 xpr \
987 JSON_HEDLEY_DIAGNOSTIC_POP
988# endif
989# endif
990#endif
991#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
992 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
993#endif
994
995#if defined(JSON_HEDLEY_CONST_CAST)
996 #undef JSON_HEDLEY_CONST_CAST
997#endif
998#if defined(__cplusplus)
999# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
1000#elif \
1001 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1002 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1003 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1004# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1005 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1006 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1007 ((T) (expr)); \
1008 JSON_HEDLEY_DIAGNOSTIC_POP \
1009 }))
1010#else
1011# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1012#endif
1013
1014#if defined(JSON_HEDLEY_REINTERPRET_CAST)
1015 #undef JSON_HEDLEY_REINTERPRET_CAST
1016#endif
1017#if defined(__cplusplus)
1018 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1019#else
1020 #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1021#endif
1022
1023#if defined(JSON_HEDLEY_STATIC_CAST)
1024 #undef JSON_HEDLEY_STATIC_CAST
1025#endif
1026#if defined(__cplusplus)
1027 #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1028#else
1029 #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1030#endif
1031
1032#if defined(JSON_HEDLEY_CPP_CAST)
1033 #undef JSON_HEDLEY_CPP_CAST
1034#endif
1035#if defined(__cplusplus)
1036# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1037# define JSON_HEDLEY_CPP_CAST(T, expr) \
1038 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1039 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1040 ((T) (expr)) \
1041 JSON_HEDLEY_DIAGNOSTIC_POP
1042# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1043# define JSON_HEDLEY_CPP_CAST(T, expr) \
1044 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1045 _Pragma("diag_suppress=Pe137") \
1046 JSON_HEDLEY_DIAGNOSTIC_POP
1047# else
1048# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1049# endif
1050#else
1051# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1052#endif
1053
1054#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1055 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1056#endif
1057#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1058 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1059#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1060 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1061#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1062 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1063#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1064 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1065#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1066 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1067#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1068 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1069#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1070 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1071#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1072 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1073#elif \
1074 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1075 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1076 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1077 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1078 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1079 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1080 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1081 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1082 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1083 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1084 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1085 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1086#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1087 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1088#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1089 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1090#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1091 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1092#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1093 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1094#else
1095 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1096#endif
1097
1098#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1099 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1100#endif
1101#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1102 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1103#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1104 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1105#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1106 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1107#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1108 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1109#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1110 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1111#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1112 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1113#elif \
1114 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1115 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1116 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1117 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1118 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1119#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1120 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1121#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1122 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1123#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1124 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1125#else
1126 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1127#endif
1128
1129#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1130 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1131#endif
1132#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1133 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1134#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1135 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1136#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1137 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1138#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1139 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1140#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1141 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1142#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1143 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1144#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1145 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1146#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1147 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1148#elif \
1149 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1150 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1151 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1152 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1153#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1154 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1155#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1156 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1157#else
1158 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1159#endif
1160
1161#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1162 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1163#endif
1164#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1165 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1166#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1167 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1168#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1169 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1170#else
1171 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1172#endif
1173
1174#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1175 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1176#endif
1177#if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1178 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1179#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1180 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1181#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1182 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1183#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1184 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1185#else
1186 #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1187#endif
1188
1189#if defined(JSON_HEDLEY_DEPRECATED)
1190 #undef JSON_HEDLEY_DEPRECATED
1191#endif
1192#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1193 #undef JSON_HEDLEY_DEPRECATED_FOR
1194#endif
1195#if \
1196 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1197 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1198 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1199 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1200#elif \
1201 (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1202 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1203 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1204 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1205 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1206 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1207 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1208 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1209 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1210 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1211 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1212 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1213 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1214 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1215#elif defined(__cplusplus) && (__cplusplus >= 201402L)
1216 #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1217 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1218#elif \
1219 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1220 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1221 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1222 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1223 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1224 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1225 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1226 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1227 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1228 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1229 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1230 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1231 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1232 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1233 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1234 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1235 #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1236 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1237#elif \
1238 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1239 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1240 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1241 #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1242 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1243#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1244 #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1245 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1246#else
1247 #define JSON_HEDLEY_DEPRECATED(since)
1248 #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1249#endif
1250
1251#if defined(JSON_HEDLEY_UNAVAILABLE)
1252 #undef JSON_HEDLEY_UNAVAILABLE
1253#endif
1254#if \
1255 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1256 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1257 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1258 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1259 #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1260#else
1261 #define JSON_HEDLEY_UNAVAILABLE(available_since)
1262#endif
1263
1264#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1265 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1266#endif
1267#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1268 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1269#endif
1270#if \
1271 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1272 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1273 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1274 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1275 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1276 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1277 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1278 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1279 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1280 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1281 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1282 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1283 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1284 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1285 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1286 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1287 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1288 #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1289 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1290#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1291 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1292 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1293#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1294 #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1295 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1296#elif defined(_Check_return_) /* SAL */
1297 #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1298 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1299#else
1300 #define JSON_HEDLEY_WARN_UNUSED_RESULT
1301 #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1302#endif
1303
1304#if defined(JSON_HEDLEY_SENTINEL)
1305 #undef JSON_HEDLEY_SENTINEL
1306#endif
1307#if \
1308 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1309 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1310 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1311 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1312 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1313 #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1314#else
1315 #define JSON_HEDLEY_SENTINEL(position)
1316#endif
1317
1318#if defined(JSON_HEDLEY_NO_RETURN)
1319 #undef JSON_HEDLEY_NO_RETURN
1320#endif
1321#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1322 #define JSON_HEDLEY_NO_RETURN __noreturn
1323#elif \
1324 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1325 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1326 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1327#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1328 #define JSON_HEDLEY_NO_RETURN _Noreturn
1329#elif defined(__cplusplus) && (__cplusplus >= 201103L)
1330 #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1331#elif \
1332 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1333 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1334 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1335 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1336 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1337 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1338 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1339 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1340 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1341 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1342 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1343 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1344 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1345 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1346 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1347 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1348 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1349 #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1350#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1351 #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1352#elif \
1353 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1354 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1355 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1356#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1357 #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1358#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1359 #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1360#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1361 #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1362#else
1363 #define JSON_HEDLEY_NO_RETURN
1364#endif
1365
1366#if defined(JSON_HEDLEY_NO_ESCAPE)
1367 #undef JSON_HEDLEY_NO_ESCAPE
1368#endif
1369#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1370 #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1371#else
1372 #define JSON_HEDLEY_NO_ESCAPE
1373#endif
1374
1375#if defined(JSON_HEDLEY_UNREACHABLE)
1376 #undef JSON_HEDLEY_UNREACHABLE
1377#endif
1378#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1379 #undef JSON_HEDLEY_UNREACHABLE_RETURN
1380#endif
1381#if defined(JSON_HEDLEY_ASSUME)
1382 #undef JSON_HEDLEY_ASSUME
1383#endif
1384#if \
1385 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1386 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1387 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1388 #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1389#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1390 #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1391#elif \
1392 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1393 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1394 #if defined(__cplusplus)
1395 #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1396 #else
1397 #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1398 #endif
1399#endif
1400#if \
1401 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1402 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1403 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1404 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1405 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1406 JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1407 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1408 #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1409#elif defined(JSON_HEDLEY_ASSUME)
1410 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1411#endif
1412#if !defined(JSON_HEDLEY_ASSUME)
1413 #if defined(JSON_HEDLEY_UNREACHABLE)
1414 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1415 #else
1416 #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1417 #endif
1418#endif
1419#if defined(JSON_HEDLEY_UNREACHABLE)
1420 #if \
1421 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1422 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1423 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1424 #else
1425 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1426 #endif
1427#else
1428 #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1429#endif
1430#if !defined(JSON_HEDLEY_UNREACHABLE)
1431 #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1432#endif
1433
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
1461
1462#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1463 #undef JSON_HEDLEY_PRINTF_FORMAT
1464#endif
1465#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1466 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1467#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1468 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1469#elif \
1470 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1471 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1472 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1473 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1474 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1475 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1476 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1477 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1478 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1479 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1480 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1481 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1482 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1483 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1484 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1485 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1486 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1487 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1488#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1489 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1490#else
1491 #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1492#endif
1493
1494#if defined(JSON_HEDLEY_CONSTEXPR)
1495 #undef JSON_HEDLEY_CONSTEXPR
1496#endif
1497#if defined(__cplusplus)
1498 #if __cplusplus >= 201103L
1499 #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1500 #endif
1501#endif
1502#if !defined(JSON_HEDLEY_CONSTEXPR)
1503 #define JSON_HEDLEY_CONSTEXPR
1504#endif
1505
1506#if defined(JSON_HEDLEY_PREDICT)
1507 #undef JSON_HEDLEY_PREDICT
1508#endif
1509#if defined(JSON_HEDLEY_LIKELY)
1510 #undef JSON_HEDLEY_LIKELY
1511#endif
1512#if defined(JSON_HEDLEY_UNLIKELY)
1513 #undef JSON_HEDLEY_UNLIKELY
1514#endif
1515#if defined(JSON_HEDLEY_UNPREDICTABLE)
1516 #undef JSON_HEDLEY_UNPREDICTABLE
1517#endif
1518#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1519 #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1520#endif
1521#if \
1522 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1523 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1524 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1525# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1526# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1527# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1528# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1529# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1530#elif \
1531 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1532 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1533 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1534 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1535 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1536 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1537 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1538 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1539 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1540 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1541 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1542 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1543 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1544 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1545 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1546 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1547# define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1548 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1549# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1550 (__extension__ ({ \
1551 double hedley_probability_ = (probability); \
1552 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1553 }))
1554# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1555 (__extension__ ({ \
1556 double hedley_probability_ = (probability); \
1557 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1558 }))
1559# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1560# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1561#else
1562# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1563# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1564# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1565# define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1566# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1567#endif
1568#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1569 #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1570#endif
1571
1572#if defined(JSON_HEDLEY_MALLOC)
1573 #undef JSON_HEDLEY_MALLOC
1574#endif
1575#if \
1576 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1577 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1578 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1579 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1580 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1581 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1582 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1583 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1584 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1585 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1586 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1587 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1588 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1589 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1590 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1591 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1592 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1593 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1594 #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1595#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1596 #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1597#elif \
1598 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1599 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1600 #define JSON_HEDLEY_MALLOC __declspec(restrict)
1601#else
1602 #define JSON_HEDLEY_MALLOC
1603#endif
1604
1605#if defined(JSON_HEDLEY_PURE)
1606 #undef JSON_HEDLEY_PURE
1607#endif
1608#if \
1609 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1610 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1611 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1612 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1613 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1614 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1615 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1616 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1617 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1618 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1619 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1620 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1621 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1622 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1623 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1624 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1625 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1626 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1627 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1628# define JSON_HEDLEY_PURE __attribute__((__pure__))
1629#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1630# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1631#elif defined(__cplusplus) && \
1632 ( \
1633 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1634 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1635 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1636 )
1637# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1638#else
1639# define JSON_HEDLEY_PURE
1640#endif
1641
1642#if defined(JSON_HEDLEY_CONST)
1643 #undef JSON_HEDLEY_CONST
1644#endif
1645#if \
1646 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1647 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1648 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1649 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1650 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1651 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1652 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1653 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1654 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1655 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1656 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1657 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1658 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1659 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1660 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1661 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1662 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1663 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1664 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1665 #define JSON_HEDLEY_CONST __attribute__((__const__))
1666#elif \
1667 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1668 #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1669#else
1670 #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1671#endif
1672
1673#if defined(JSON_HEDLEY_RESTRICT)
1674 #undef JSON_HEDLEY_RESTRICT
1675#endif
1676#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1677 #define JSON_HEDLEY_RESTRICT restrict
1678#elif \
1679 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1680 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1681 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1682 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1683 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1684 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1685 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1686 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1687 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1688 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1689 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1690 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1691 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1692 defined(__clang__) || \
1693 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1694 #define JSON_HEDLEY_RESTRICT __restrict
1695#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1696 #define JSON_HEDLEY_RESTRICT _Restrict
1697#else
1698 #define JSON_HEDLEY_RESTRICT
1699#endif
1700
1701#if defined(JSON_HEDLEY_INLINE)
1702 #undef JSON_HEDLEY_INLINE
1703#endif
1704#if \
1705 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1706 (defined(__cplusplus) && (__cplusplus >= 199711L))
1707 #define JSON_HEDLEY_INLINE inline
1708#elif \
1709 defined(JSON_HEDLEY_GCC_VERSION) || \
1710 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1711 #define JSON_HEDLEY_INLINE __inline__
1712#elif \
1713 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1714 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1715 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1716 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1717 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1718 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1719 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1720 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1721 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1722 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1723 #define JSON_HEDLEY_INLINE __inline
1724#else
1725 #define JSON_HEDLEY_INLINE
1726#endif
1727
1728#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1729 #undef JSON_HEDLEY_ALWAYS_INLINE
1730#endif
1731#if \
1732 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1733 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1734 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1735 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1736 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1737 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1738 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1739 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1740 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1741 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1742 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1743 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1744 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1745 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1746 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1747 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1748 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1749 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1750 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1751# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1752#elif \
1753 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1754 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1755# define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1756#elif defined(__cplusplus) && \
1757 ( \
1758 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1759 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1760 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1761 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1762 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1763 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1764 )
1765# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1766#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1767# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1768#else
1769# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1770#endif
1771
1772#if defined(JSON_HEDLEY_NEVER_INLINE)
1773 #undef JSON_HEDLEY_NEVER_INLINE
1774#endif
1775#if \
1776 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1777 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1778 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1779 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1780 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1781 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1782 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1783 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1784 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1785 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1786 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1787 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1788 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1789 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1790 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1791 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1792 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1793 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1794 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1795 #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1796#elif \
1797 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1798 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1799 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1800#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1801 #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1802#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1803 #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1804#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1805 #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1806#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1807 #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1808#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1809 #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1810#else
1811 #define JSON_HEDLEY_NEVER_INLINE
1812#endif
1813
1814#if defined(JSON_HEDLEY_PRIVATE)
1815 #undef JSON_HEDLEY_PRIVATE
1816#endif
1817#if defined(JSON_HEDLEY_PUBLIC)
1818 #undef JSON_HEDLEY_PUBLIC
1819#endif
1820#if defined(JSON_HEDLEY_IMPORT)
1821 #undef JSON_HEDLEY_IMPORT
1822#endif
1823#if defined(_WIN32) || defined(__CYGWIN__)
1824# define JSON_HEDLEY_PRIVATE
1825# define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1826# define JSON_HEDLEY_IMPORT __declspec(dllimport)
1827#else
1828# if \
1829 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1830 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1831 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1832 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1833 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1834 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1835 ( \
1836 defined(__TI_EABI__) && \
1837 ( \
1838 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1839 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1840 ) \
1841 ) || \
1842 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1843# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1844# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1845# else
1846# define JSON_HEDLEY_PRIVATE
1847# define JSON_HEDLEY_PUBLIC
1848# endif
1849# define JSON_HEDLEY_IMPORT extern
1850#endif
1851
1852#if defined(JSON_HEDLEY_NO_THROW)
1853 #undef JSON_HEDLEY_NO_THROW
1854#endif
1855#if \
1856 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1857 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1858 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1859 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1860 #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1861#elif \
1862 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1863 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1864 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1865 #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1866#else
1867 #define JSON_HEDLEY_NO_THROW
1868#endif
1869
1870#if defined(JSON_HEDLEY_FALL_THROUGH)
1871 #undef JSON_HEDLEY_FALL_THROUGH
1872#endif
1873#if \
1874 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1875 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
1876 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1877 #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1878#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1879 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1880#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1881 #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1882#elif defined(__fallthrough) /* SAL */
1883 #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1884#else
1885 #define JSON_HEDLEY_FALL_THROUGH
1886#endif
1887
1888#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1889 #undef JSON_HEDLEY_RETURNS_NON_NULL
1890#endif
1891#if \
1892 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1893 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1894 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1895 #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1896#elif defined(_Ret_notnull_) /* SAL */
1897 #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1898#else
1899 #define JSON_HEDLEY_RETURNS_NON_NULL
1900#endif
1901
1902#if defined(JSON_HEDLEY_ARRAY_PARAM)
1903 #undef JSON_HEDLEY_ARRAY_PARAM
1904#endif
1905#if \
1906 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1907 !defined(__STDC_NO_VLA__) && \
1908 !defined(__cplusplus) && \
1909 !defined(JSON_HEDLEY_PGI_VERSION) && \
1910 !defined(JSON_HEDLEY_TINYC_VERSION)
1911 #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1912#else
1913 #define JSON_HEDLEY_ARRAY_PARAM(name)
1914#endif
1915
1916#if defined(JSON_HEDLEY_IS_CONSTANT)
1917 #undef JSON_HEDLEY_IS_CONSTANT
1918#endif
1919#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1920 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1921#endif
1922/* JSON_HEDLEY_IS_CONSTEXPR_ is for
1923 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1924#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1925 #undef JSON_HEDLEY_IS_CONSTEXPR_
1926#endif
1927#if \
1928 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1929 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1930 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1931 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1932 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1933 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1934 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1935 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1936 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1937 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1938 #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1939#endif
1940#if !defined(__cplusplus)
1941# if \
1942 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1943 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1944 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1945 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1946 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1947 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1948 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1949#if defined(__INTPTR_TYPE__)
1950 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1951#else
1952 #include <stdint.h>
1953 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1954#endif
1955# elif \
1956 ( \
1957 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1958 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1959 !defined(JSON_HEDLEY_PGI_VERSION) && \
1960 !defined(JSON_HEDLEY_IAR_VERSION)) || \
1961 (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1962 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1963 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1964 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1965 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1966#if defined(__INTPTR_TYPE__)
1967 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1968#else
1969 #include <stdint.h>
1970 #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1971#endif
1972# elif \
1973 defined(JSON_HEDLEY_GCC_VERSION) || \
1974 defined(JSON_HEDLEY_INTEL_VERSION) || \
1975 defined(JSON_HEDLEY_TINYC_VERSION) || \
1976 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1977 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1978 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1979 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1980 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1981 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1982 defined(__clang__)
1983# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1984 sizeof(void) != \
1985 sizeof(*( \
1986 1 ? \
1987 ((void*) ((expr) * 0L) ) : \
1988((struct { char v[sizeof(void) * 2]; } *) 1) \
1989 ) \
1990 ) \
1991 )
1992# endif
1993#endif
1994#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1995 #if !defined(JSON_HEDLEY_IS_CONSTANT)
1996 #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1997 #endif
1998 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1999#else
2000 #if !defined(JSON_HEDLEY_IS_CONSTANT)
2001 #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2002 #endif
2003 #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2004#endif
2005
2006#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2007 #undef JSON_HEDLEY_BEGIN_C_DECLS
2008#endif
2009#if defined(JSON_HEDLEY_END_C_DECLS)
2010 #undef JSON_HEDLEY_END_C_DECLS
2011#endif
2012#if defined(JSON_HEDLEY_C_DECL)
2013 #undef JSON_HEDLEY_C_DECL
2014#endif
2015#if defined(__cplusplus)
2016 #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2017 #define JSON_HEDLEY_END_C_DECLS }
2018 #define JSON_HEDLEY_C_DECL extern "C"
2019#else
2020 #define JSON_HEDLEY_BEGIN_C_DECLS
2021 #define JSON_HEDLEY_END_C_DECLS
2022 #define JSON_HEDLEY_C_DECL
2023#endif
2024
2025#if defined(JSON_HEDLEY_STATIC_ASSERT)
2026 #undef JSON_HEDLEY_STATIC_ASSERT
2027#endif
2028#if \
2029 !defined(__cplusplus) && ( \
2030 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2031 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2032 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2033 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2034 defined(_Static_assert) \
2035 )
2036# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2037#elif \
2038 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2039 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2040 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2041# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2042#else
2043# define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2044#endif
2045
2046#if defined(JSON_HEDLEY_NULL)
2047 #undef JSON_HEDLEY_NULL
2048#endif
2049#if defined(__cplusplus)
2050 #if __cplusplus >= 201103L
2051 #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2052 #elif defined(NULL)
2053 #define JSON_HEDLEY_NULL NULL
2054 #else
2055 #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2056 #endif
2057#elif defined(NULL)
2058 #define JSON_HEDLEY_NULL NULL
2059#else
2060 #define JSON_HEDLEY_NULL ((void*) 0)
2061#endif
2062
2063#if defined(JSON_HEDLEY_MESSAGE)
2064 #undef JSON_HEDLEY_MESSAGE
2065#endif
2066#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2067# define JSON_HEDLEY_MESSAGE(msg) \
2068 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2069 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2070 JSON_HEDLEY_PRAGMA(message msg) \
2071 JSON_HEDLEY_DIAGNOSTIC_POP
2072#elif \
2073 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2074 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2075# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2076#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2077# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2078#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2079# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2080#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2081# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2082#else
2083# define JSON_HEDLEY_MESSAGE(msg)
2084#endif
2085
2086#if defined(JSON_HEDLEY_WARNING)
2087 #undef JSON_HEDLEY_WARNING
2088#endif
2089#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2090# define JSON_HEDLEY_WARNING(msg) \
2091 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2092 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2093 JSON_HEDLEY_PRAGMA(clang warning msg) \
2094 JSON_HEDLEY_DIAGNOSTIC_POP
2095#elif \
2096 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2097 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2098 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2099# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2100#elif \
2101 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2102 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2103# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2104#else
2105# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2106#endif
2107
2108#if defined(JSON_HEDLEY_REQUIRE)
2109 #undef JSON_HEDLEY_REQUIRE
2110#endif
2111#if defined(JSON_HEDLEY_REQUIRE_MSG)
2112 #undef JSON_HEDLEY_REQUIRE_MSG
2113#endif
2114#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2115# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2116# define JSON_HEDLEY_REQUIRE(expr) \
2117 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2118 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2119 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2120 JSON_HEDLEY_DIAGNOSTIC_POP
2121# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2122 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2123 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2124 __attribute__((diagnose_if(!(expr), msg, "error"))) \
2125 JSON_HEDLEY_DIAGNOSTIC_POP
2126# else
2127# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2128# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2129# endif
2130#else
2131# define JSON_HEDLEY_REQUIRE(expr)
2132# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2133#endif
2134
2135#if defined(JSON_HEDLEY_FLAGS)
2136 #undef JSON_HEDLEY_FLAGS
2137#endif
2138#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2139 #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2140#else
2141 #define JSON_HEDLEY_FLAGS
2142#endif
2143
2144#if defined(JSON_HEDLEY_FLAGS_CAST)
2145 #undef JSON_HEDLEY_FLAGS_CAST
2146#endif
2147#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2148# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2149 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2150 _Pragma("warning(disable:188)") \
2151 ((T) (expr)); \
2152 JSON_HEDLEY_DIAGNOSTIC_POP \
2153 }))
2154#else
2155# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2156#endif
2157
2158#if defined(JSON_HEDLEY_EMPTY_BASES)
2159 #undef JSON_HEDLEY_EMPTY_BASES
2160#endif
2161#if \
2162 (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2163 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2164 #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2165#else
2166 #define JSON_HEDLEY_EMPTY_BASES
2167#endif
2168
2169/* Remaining macros are deprecated. */
2170
2171#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2172 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2173#endif
2174#if defined(__clang__)
2175 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2176#else
2177 #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2178#endif
2179
2180#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2181 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2182#endif
2183#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2184
2185#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2186 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2187#endif
2188#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2189
2190#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2191 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2192#endif
2193#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2194
2195#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2196 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2197#endif
2198#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2199
2200#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2201 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2202#endif
2203#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2204
2205#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2206 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2207#endif
2208#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2209
2210#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2211 #undef JSON_HEDLEY_CLANG_HAS_WARNING
2212#endif
2213#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2214
2215#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2216
2217
2218// This file contains all internal macro definitions
2219// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2220
2221// exclude unsupported compilers
2222#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2223 #if defined(__clang__)
2224 #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2225 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2226 #endif
2227 #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2228 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2229 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2230 #endif
2231 #endif
2232#endif
2233
2234// C++ language standard detection
2235// if the user manually specified the used c++ version this is skipped
2236#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2237 #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2238 #define JSON_HAS_CPP_20
2239 #define JSON_HAS_CPP_17
2240 #define JSON_HAS_CPP_14
2241 #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2242 #define JSON_HAS_CPP_17
2243 #define JSON_HAS_CPP_14
2244 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2245 #define JSON_HAS_CPP_14
2246 #endif
2247 // the cpp 11 flag is always specified because it is the minimal required version
2248 #define JSON_HAS_CPP_11
2249#endif
2250
2251// disable documentation warnings on clang
2252#if defined(__clang__)
2253 #pragma clang diagnostic push
2254 #pragma clang diagnostic ignored "-Wdocumentation"
2255 #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2256#endif
2257
2258// allow to disable exceptions
2259#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2260 #define JSON_THROW(exception) throw exception
2261 #define JSON_TRY try
2262 #define JSON_CATCH(exception) catch(exception)
2263 #define JSON_INTERNAL_CATCH(exception) catch(exception)
2264#else
2265 #include <cstdlib>
2266 #define JSON_THROW(exception) std::abort()
2267 #define JSON_TRY if(true)
2268 #define JSON_CATCH(exception) if(false)
2269 #define JSON_INTERNAL_CATCH(exception) if(false)
2270#endif
2271
2272// override exception macros
2273#if defined(JSON_THROW_USER)
2274 #undef JSON_THROW
2275 #define JSON_THROW JSON_THROW_USER
2276#endif
2277#if defined(JSON_TRY_USER)
2278 #undef JSON_TRY
2279 #define JSON_TRY JSON_TRY_USER
2280#endif
2281#if defined(JSON_CATCH_USER)
2282 #undef JSON_CATCH
2283 #define JSON_CATCH JSON_CATCH_USER
2284 #undef JSON_INTERNAL_CATCH
2285 #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2286#endif
2287#if defined(JSON_INTERNAL_CATCH_USER)
2288 #undef JSON_INTERNAL_CATCH
2289 #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2290#endif
2291
2292// allow to override assert
2293#if !defined(JSON_ASSERT)
2294 #include <cassert> // assert
2295 #define JSON_ASSERT(x) assert(x)
2296#endif
2297
2298// allow to access some private functions (needed by the test suite)
2299#if defined(JSON_TESTS_PRIVATE)
2300 #define JSON_PRIVATE_UNLESS_TESTED public
2301#else
2302 #define JSON_PRIVATE_UNLESS_TESTED private
2303#endif
2304
2310#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2311 template<typename BasicJsonType> \
2312 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2313 { \
2314 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2315 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2316 auto it = std::find_if(std::begin(m), std::end(m), \
2317 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2318 { \
2319 return ej_pair.first == e; \
2320 }); \
2321 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2322 } \
2323 template<typename BasicJsonType> \
2324 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2325 { \
2326 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2327 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2328 auto it = std::find_if(std::begin(m), std::end(m), \
2329 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2330 { \
2331 return ej_pair.second == j; \
2332 }); \
2333 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2334 }
2335
2336// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2337// may be removed in the future once the class is split.
2338
2339#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2340 template<template<typename, typename, typename...> class ObjectType, \
2341 template<typename, typename...> class ArrayType, \
2342 class StringType, class BooleanType, class NumberIntegerType, \
2343 class NumberUnsignedType, class NumberFloatType, \
2344 template<typename> class AllocatorType, \
2345 template<typename, typename = void> class JSONSerializer, \
2346 class BinaryType>
2347
2348#define NLOHMANN_BASIC_JSON_TPL \
2349 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2350 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2351 AllocatorType, JSONSerializer, BinaryType>
2352
2353// Macros to simplify conversion from/to types
2354
2355#define NLOHMANN_JSON_EXPAND( x ) x
2356#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME
2357#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2358 NLOHMANN_JSON_PASTE64, \
2359 NLOHMANN_JSON_PASTE63, \
2360 NLOHMANN_JSON_PASTE62, \
2361 NLOHMANN_JSON_PASTE61, \
2362 NLOHMANN_JSON_PASTE60, \
2363 NLOHMANN_JSON_PASTE59, \
2364 NLOHMANN_JSON_PASTE58, \
2365 NLOHMANN_JSON_PASTE57, \
2366 NLOHMANN_JSON_PASTE56, \
2367 NLOHMANN_JSON_PASTE55, \
2368 NLOHMANN_JSON_PASTE54, \
2369 NLOHMANN_JSON_PASTE53, \
2370 NLOHMANN_JSON_PASTE52, \
2371 NLOHMANN_JSON_PASTE51, \
2372 NLOHMANN_JSON_PASTE50, \
2373 NLOHMANN_JSON_PASTE49, \
2374 NLOHMANN_JSON_PASTE48, \
2375 NLOHMANN_JSON_PASTE47, \
2376 NLOHMANN_JSON_PASTE46, \
2377 NLOHMANN_JSON_PASTE45, \
2378 NLOHMANN_JSON_PASTE44, \
2379 NLOHMANN_JSON_PASTE43, \
2380 NLOHMANN_JSON_PASTE42, \
2381 NLOHMANN_JSON_PASTE41, \
2382 NLOHMANN_JSON_PASTE40, \
2383 NLOHMANN_JSON_PASTE39, \
2384 NLOHMANN_JSON_PASTE38, \
2385 NLOHMANN_JSON_PASTE37, \
2386 NLOHMANN_JSON_PASTE36, \
2387 NLOHMANN_JSON_PASTE35, \
2388 NLOHMANN_JSON_PASTE34, \
2389 NLOHMANN_JSON_PASTE33, \
2390 NLOHMANN_JSON_PASTE32, \
2391 NLOHMANN_JSON_PASTE31, \
2392 NLOHMANN_JSON_PASTE30, \
2393 NLOHMANN_JSON_PASTE29, \
2394 NLOHMANN_JSON_PASTE28, \
2395 NLOHMANN_JSON_PASTE27, \
2396 NLOHMANN_JSON_PASTE26, \
2397 NLOHMANN_JSON_PASTE25, \
2398 NLOHMANN_JSON_PASTE24, \
2399 NLOHMANN_JSON_PASTE23, \
2400 NLOHMANN_JSON_PASTE22, \
2401 NLOHMANN_JSON_PASTE21, \
2402 NLOHMANN_JSON_PASTE20, \
2403 NLOHMANN_JSON_PASTE19, \
2404 NLOHMANN_JSON_PASTE18, \
2405 NLOHMANN_JSON_PASTE17, \
2406 NLOHMANN_JSON_PASTE16, \
2407 NLOHMANN_JSON_PASTE15, \
2408 NLOHMANN_JSON_PASTE14, \
2409 NLOHMANN_JSON_PASTE13, \
2410 NLOHMANN_JSON_PASTE12, \
2411 NLOHMANN_JSON_PASTE11, \
2412 NLOHMANN_JSON_PASTE10, \
2413 NLOHMANN_JSON_PASTE9, \
2414 NLOHMANN_JSON_PASTE8, \
2415 NLOHMANN_JSON_PASTE7, \
2416 NLOHMANN_JSON_PASTE6, \
2417 NLOHMANN_JSON_PASTE5, \
2418 NLOHMANN_JSON_PASTE4, \
2419 NLOHMANN_JSON_PASTE3, \
2420 NLOHMANN_JSON_PASTE2, \
2421 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2422#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2423#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2424#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2425#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2426#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2427#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6)
2428#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7)
2429#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8)
2430#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9)
2431#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10)
2432#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
2433#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
2434#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
2435#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
2436#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
2437#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
2438#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
2439#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
2440#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
2441#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
2442#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
2443#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
2444#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
2445#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24)
2446#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25)
2447#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26)
2448#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27)
2449#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28)
2450#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29)
2451#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30)
2452#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31)
2453#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32)
2454#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33)
2455#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34)
2456#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35)
2457#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36)
2458#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37)
2459#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38)
2460#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39)
2461#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40)
2462#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41)
2463#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42)
2464#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43)
2465#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44)
2466#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45)
2467#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46)
2468#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47)
2469#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48)
2470#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49)
2471#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50)
2472#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51)
2473#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52)
2474#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53)
2475#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54)
2476#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55)
2477#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56)
2478#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57)
2479#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58)
2480#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59)
2481#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60)
2482#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61)
2483#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62)
2484#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63)
2485
2486#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2487#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2488
2494#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2495 friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2496 friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2497
2503#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2504 inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \
2505 inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) }
2506
2507#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2508 #define JSON_USE_IMPLICIT_CONVERSIONS 1
2509#endif
2510
2511#if JSON_USE_IMPLICIT_CONVERSIONS
2512 #define JSON_EXPLICIT
2513#else
2514 #define JSON_EXPLICIT explicit
2515#endif
2516
2517#ifndef JSON_DIAGNOSTICS
2518 #define JSON_DIAGNOSTICS 0
2519#endif
2520
2521
2522namespace nlohmann
2523{
2524namespace detail
2525{
2526
2540inline void replace_substring(std::string& s, const std::string& f,
2541 const std::string& t)
2542{
2543 JSON_ASSERT(!f.empty());
2544 for (auto pos = s.find(f); // find first occurrence of f
2545 pos != std::string::npos; // make sure f was found
2546 s.replace(pos, f.size(), t), // replace with t, and
2547 pos = s.find(f, pos + t.size())) // find next occurrence of f
2548 {}
2549}
2550
2558inline std::string escape(std::string s)
2559{
2560 replace_substring(s, "~", "~0");
2561 replace_substring(s, "/", "~1");
2562 return s;
2563}
2564
2572static void unescape(std::string& s)
2573{
2574 replace_substring(s, "~1", "/");
2575 replace_substring(s, "~0", "~");
2576}
2577
2578} // namespace detail
2579} // namespace nlohmann
2580
2581// #include <nlohmann/detail/input/position_t.hpp>
2582
2583
2584#include <cstddef> // size_t
2585
2586namespace nlohmann
2587{
2588namespace detail
2589{
2592{
2594 std::size_t chars_read_total = 0;
2598 std::size_t lines_read = 0;
2599
2601 constexpr operator size_t() const
2602 {
2603 return chars_read_total;
2604 }
2605};
2606
2607} // namespace detail
2608} // namespace nlohmann
2609
2610// #include <nlohmann/detail/macro_scope.hpp>
2611
2612
2613namespace nlohmann
2614{
2615namespace detail
2616{
2618// exceptions //
2620
2649class exception : public std::exception
2650{
2651 public:
2653 const char* what() const noexcept override
2654 {
2655 return m.what();
2656 }
2657
2659 const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
2660
2661 protected:
2663 exception(int id_, const char* what_arg) : id(id_), m(what_arg) {}
2664
2665 static std::string name(const std::string& ename, int id_)
2666 {
2667 return "[json.exception." + ename + "." + std::to_string(id_) + "] ";
2668 }
2669
2670 template<typename BasicJsonType>
2671 static std::string diagnostics(const BasicJsonType& leaf_element)
2672 {
2673#if JSON_DIAGNOSTICS
2674 std::vector<std::string> tokens;
2675 for (const auto* current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
2676 {
2677 switch (current->m_parent->type())
2678 {
2679 case value_t::array:
2680 {
2681 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
2682 {
2683 if (&current->m_parent->m_value.array->operator[](i) == current)
2684 {
2685 tokens.emplace_back(std::to_string(i));
2686 break;
2687 }
2688 }
2689 break;
2690 }
2691
2692 case value_t::object:
2693 {
2694 for (const auto& element : *current->m_parent->m_value.object)
2695 {
2696 if (&element.second == current)
2697 {
2698 tokens.emplace_back(element.first.c_str());
2699 break;
2700 }
2701 }
2702 break;
2703 }
2704
2705 case value_t::null: // LCOV_EXCL_LINE
2706 case value_t::string: // LCOV_EXCL_LINE
2707 case value_t::boolean: // LCOV_EXCL_LINE
2708 case value_t::number_integer: // LCOV_EXCL_LINE
2709 case value_t::number_unsigned: // LCOV_EXCL_LINE
2710 case value_t::number_float: // LCOV_EXCL_LINE
2711 case value_t::binary: // LCOV_EXCL_LINE
2712 case value_t::discarded: // LCOV_EXCL_LINE
2713 default: // LCOV_EXCL_LINE
2714 break; // LCOV_EXCL_LINE
2715 }
2716 }
2717
2718 if (tokens.empty())
2719 {
2720 return "";
2721 }
2722
2723 return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
2724 [](const std::string & a, const std::string & b)
2725 {
2726 return a + "/" + detail::escape(b);
2727 }) + ") ";
2728#else
2729 static_cast<void>(leaf_element);
2730 return "";
2731#endif
2732 }
2733
2734 private:
2736 std::runtime_error m;
2737};
2738
2785{
2786 public:
2796 template<typename BasicJsonType>
2797 static parse_error create(int id_, const position_t& pos, const std::string& what_arg, const BasicJsonType& context)
2798 {
2799 std::string w = exception::name("parse_error", id_) + "parse error" +
2800 position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
2801 return parse_error(id_, pos.chars_read_total, w.c_str());
2802 }
2803
2804 template<typename BasicJsonType>
2805 static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, const BasicJsonType& context)
2806 {
2807 std::string w = exception::name("parse_error", id_) + "parse error" +
2808 (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2809 ": " + exception::diagnostics(context) + what_arg;
2810 return parse_error(id_, byte_, w.c_str());
2811 }
2812
2822 const std::size_t byte;
2823
2824 private:
2825 parse_error(int id_, std::size_t byte_, const char* what_arg)
2826 : exception(id_, what_arg), byte(byte_) {}
2827
2828 static std::string position_string(const position_t& pos)
2829 {
2830 return " at line " + std::to_string(pos.lines_read + 1) +
2831 ", column " + std::to_string(pos.chars_read_current_line);
2832 }
2833};
2834
2873{
2874 public:
2875 template<typename BasicJsonType>
2876 static invalid_iterator create(int id_, const std::string& what_arg, const BasicJsonType& context)
2877 {
2878 std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
2879 return invalid_iterator(id_, w.c_str());
2880 }
2881
2882 private:
2884 invalid_iterator(int id_, const char* what_arg)
2885 : exception(id_, what_arg) {}
2886};
2887
2927class type_error : public exception
2928{
2929 public:
2930 template<typename BasicJsonType>
2931 static type_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
2932 {
2933 std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
2934 return type_error(id_, w.c_str());
2935 }
2936
2937 private:
2939 type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
2940};
2941
2976{
2977 public:
2978 template<typename BasicJsonType>
2979 static out_of_range create(int id_, const std::string& what_arg, const BasicJsonType& context)
2980 {
2981 std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
2982 return out_of_range(id_, w.c_str());
2983 }
2984
2985 private:
2987 out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
2988};
2989
3015{
3016 public:
3017 template<typename BasicJsonType>
3018 static other_error create(int id_, const std::string& what_arg, const BasicJsonType& context)
3019 {
3020 std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
3021 return other_error(id_, w.c_str());
3022 }
3023
3024 private:
3026 other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
3027};
3028} // namespace detail
3029} // namespace nlohmann
3030
3031// #include <nlohmann/detail/macro_scope.hpp>
3032
3033// #include <nlohmann/detail/meta/cpp_future.hpp>
3034
3035
3036#include <cstddef> // size_t
3037#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3038#include <utility> // index_sequence, make_index_sequence, index_sequence_for
3039
3040// #include <nlohmann/detail/macro_scope.hpp>
3041
3042
3043namespace nlohmann
3044{
3045namespace detail
3046{
3047
3048template<typename T>
3049using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3050
3051#ifdef JSON_HAS_CPP_14
3052
3053// the following utilities are natively available in C++14
3054using std::enable_if_t;
3055using std::index_sequence;
3056using std::make_index_sequence;
3057using std::index_sequence_for;
3058
3059#else
3060
3061// alias templates to reduce boilerplate
3062template<bool B, typename T = void>
3063using enable_if_t = typename std::enable_if<B, T>::type;
3064
3065// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3066// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3067
3069
3070// integer_sequence
3071//
3072// Class template representing a compile-time integer sequence. An instantiation
3073// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3074// type through its template arguments (which is a common need when
3075// working with C++11 variadic templates). `absl::integer_sequence` is designed
3076// to be a drop-in replacement for C++14's `std::integer_sequence`.
3077//
3078// Example:
3079//
3080// template< class T, T... Ints >
3081// void user_function(integer_sequence<T, Ints...>);
3082//
3083// int main()
3084// {
3085// // user_function's `T` will be deduced to `int` and `Ints...`
3086// // will be deduced to `0, 1, 2, 3, 4`.
3087// user_function(make_integer_sequence<int, 5>());
3088// }
3089template <typename T, T... Ints>
3091{
3092 using value_type = T;
3093 static constexpr std::size_t size() noexcept
3094 {
3095 return sizeof...(Ints);
3096 }
3097};
3098
3099// index_sequence
3100//
3101// A helper template for an `integer_sequence` of `size_t`,
3102// `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3103// `std::index_sequence`.
3104template <size_t... Ints>
3105using index_sequence = integer_sequence<size_t, Ints...>;
3106
3107namespace utility_internal
3108{
3109
3110template <typename Seq, size_t SeqSize, size_t Rem>
3111struct Extend;
3112
3113// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3114template <typename T, T... Ints, size_t SeqSize>
3115struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3116{
3117 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3118};
3119
3120template <typename T, T... Ints, size_t SeqSize>
3121struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3122{
3123 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3124};
3125
3126// Recursion helper for 'make_integer_sequence<T, N>'.
3127// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3128template <typename T, size_t N>
3129struct Gen
3130{
3131 using type =
3132 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3133};
3134
3135template <typename T>
3136struct Gen<T, 0>
3137{
3139};
3140
3141} // namespace utility_internal
3142
3143// Compile-time sequences of integers
3144
3145// make_integer_sequence
3146//
3147// This template alias is equivalent to
3148// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3149// replacement for C++14's `std::make_integer_sequence`.
3150template <typename T, T N>
3152
3153// make_index_sequence
3154//
3155// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3156// and is designed to be a drop-in replacement for C++14's
3157// `std::make_index_sequence`.
3158template <size_t N>
3160
3161// index_sequence_for
3162//
3163// Converts a typename pack into an index sequence of the same length, and
3164// is designed to be a drop-in replacement for C++14's
3165// `std::index_sequence_for()`
3166template <typename... Ts>
3168
3170
3171#endif
3172
3173// dispatch utility (taken from ranges-v3)
3174template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3175template<> struct priority_tag<0> {};
3176
3177// taken from ranges-v3
3178template<typename T>
3180{
3181 static constexpr T value{};
3182};
3183
3184template<typename T>
3185constexpr T static_const<T>::value;
3186
3187} // namespace detail
3188} // namespace nlohmann
3189
3190// #include <nlohmann/detail/meta/identity_tag.hpp>
3191
3192
3193namespace nlohmann
3194{
3195namespace detail
3196{
3197// dispatching helper struct
3198template <class T> struct identity_tag {};
3199} // namespace detail
3200} // namespace nlohmann
3201
3202// #include <nlohmann/detail/meta/type_traits.hpp>
3203
3204
3205#include <limits> // numeric_limits
3206#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3207#include <utility> // declval
3208#include <tuple> // tuple
3209
3210// #include <nlohmann/detail/iterators/iterator_traits.hpp>
3211
3212
3213#include <iterator> // random_access_iterator_tag
3214
3215// #include <nlohmann/detail/meta/void_t.hpp>
3216
3217
3218namespace nlohmann
3219{
3220namespace detail
3221{
3222template<typename ...Ts> struct make_void
3223{
3224 using type = void;
3225};
3226template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
3227} // namespace detail
3228} // namespace nlohmann
3229
3230// #include <nlohmann/detail/meta/cpp_future.hpp>
3231
3232
3233namespace nlohmann
3234{
3235namespace detail
3236{
3237template<typename It, typename = void>
3239
3240template<typename It>
3242 It,
3243 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3244 typename It::reference, typename It::iterator_category >>
3245{
3246 using difference_type = typename It::difference_type;
3247 using value_type = typename It::value_type;
3248 using pointer = typename It::pointer;
3249 using reference = typename It::reference;
3250 using iterator_category = typename It::iterator_category;
3251};
3252
3253// This is required as some compilers implement std::iterator_traits in a way that
3254// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3255template<typename T, typename = void>
3257{
3258};
3259
3260template<typename T>
3261struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3262 : iterator_types<T>
3263{
3264};
3265
3266template<typename T>
3268{
3269 using iterator_category = std::random_access_iterator_tag;
3270 using value_type = T;
3271 using difference_type = ptrdiff_t;
3272 using pointer = T*;
3273 using reference = T&;
3274};
3275} // namespace detail
3276} // namespace nlohmann
3277
3278// #include <nlohmann/detail/macro_scope.hpp>
3279
3280// #include <nlohmann/detail/meta/cpp_future.hpp>
3281
3282// #include <nlohmann/detail/meta/detected.hpp>
3283
3284
3285#include <type_traits>
3286
3287// #include <nlohmann/detail/meta/void_t.hpp>
3288
3289
3290// https://en.cppreference.com/w/cpp/experimental/is_detected
3291namespace nlohmann
3292{
3293namespace detail
3294{
3296{
3297 nonesuch() = delete;
3298 ~nonesuch() = delete;
3299 nonesuch(nonesuch const&) = delete;
3300 nonesuch(nonesuch const&&) = delete;
3301 void operator=(nonesuch const&) = delete;
3302 void operator=(nonesuch&&) = delete;
3303};
3304
3305template<class Default,
3306 class AlwaysVoid,
3307 template<class...> class Op,
3308 class... Args>
3310{
3311 using value_t = std::false_type;
3312 using type = Default;
3313};
3314
3315template<class Default, template<class...> class Op, class... Args>
3316struct detector<Default, void_t<Op<Args...>>, Op, Args...>
3317{
3318 using value_t = std::true_type;
3319 using type = Op<Args...>;
3320};
3321
3322template<template<class...> class Op, class... Args>
3323using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
3324
3325template<template<class...> class Op, class... Args>
3326struct is_detected_lazy : is_detected<Op, Args...> { };
3327
3328template<template<class...> class Op, class... Args>
3329using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
3330
3331template<class Default, template<class...> class Op, class... Args>
3332using detected_or = detector<Default, void, Op, Args...>;
3333
3334template<class Default, template<class...> class Op, class... Args>
3335using detected_or_t = typename detected_or<Default, Op, Args...>::type;
3336
3337template<class Expected, template<class...> class Op, class... Args>
3338using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
3339
3340template<class To, template<class...> class Op, class... Args>
3342 std::is_convertible<detected_t<Op, Args...>, To>;
3343} // namespace detail
3344} // namespace nlohmann
3345
3346// #include <nlohmann/json_fwd.hpp>
3347#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3348#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3349
3350#include <cstdint> // int64_t, uint64_t
3351#include <map> // map
3352#include <memory> // allocator
3353#include <string> // string
3354#include <vector> // vector
3355
3361namespace nlohmann
3362{
3370template<typename T = void, typename SFINAE = void>
3371struct adl_serializer;
3372
3373template<template<typename U, typename V, typename... Args> class ObjectType =
3374 std::map,
3375 template<typename U, typename... Args> class ArrayType = std::vector,
3376 class StringType = std::string, class BooleanType = bool,
3377 class NumberIntegerType = std::int64_t,
3378 class NumberUnsignedType = std::uint64_t,
3379 class NumberFloatType = double,
3380 template<typename U> class AllocatorType = std::allocator,
3381 template<typename T, typename SFINAE = void> class JSONSerializer =
3382 adl_serializer,
3383 class BinaryType = std::vector<std::uint8_t>>
3384class basic_json;
3385
3397template<typename BasicJsonType>
3398class json_pointer;
3399
3409
3410template<class Key, class T, class IgnoredLess, class Allocator>
3411struct ordered_map;
3412
3421
3422} // namespace nlohmann
3423
3424#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3425
3426
3427namespace nlohmann
3428{
3437namespace detail
3438{
3440// helpers //
3442
3443// Note to maintainers:
3444//
3445// Every trait in this file expects a non CV-qualified type.
3446// The only exceptions are in the 'aliases for detected' section
3447// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3448//
3449// In this case, T has to be properly CV-qualified to constraint the function arguments
3450// (e.g. to_json(BasicJsonType&, const T&))
3451
3452template<typename> struct is_basic_json : std::false_type {};
3453
3455struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3456
3458// json_ref helpers //
3460
3461template<typename>
3462class json_ref;
3463
3464template<typename>
3465struct is_json_ref : std::false_type {};
3466
3467template<typename T>
3468struct is_json_ref<json_ref<T>> : std::true_type {};
3469
3471// aliases for detected //
3473
3474template<typename T>
3475using mapped_type_t = typename T::mapped_type;
3476
3477template<typename T>
3478using key_type_t = typename T::key_type;
3479
3480template<typename T>
3481using value_type_t = typename T::value_type;
3482
3483template<typename T>
3484using difference_type_t = typename T::difference_type;
3485
3486template<typename T>
3487using pointer_t = typename T::pointer;
3488
3489template<typename T>
3490using reference_t = typename T::reference;
3491
3492template<typename T>
3493using iterator_category_t = typename T::iterator_category;
3494
3495template<typename T>
3496using iterator_t = typename T::iterator;
3497
3498template<typename T, typename... Args>
3499using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3500
3501template<typename T, typename... Args>
3502using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3503
3504template<typename T, typename U>
3505using get_template_function = decltype(std::declval<T>().template get<U>());
3506
3507// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3508template<typename BasicJsonType, typename T, typename = void>
3509struct has_from_json : std::false_type {};
3510
3511// trait checking if j.get<T> is valid
3512// use this trait instead of std::is_constructible or std::is_convertible,
3513// both rely on, or make use of implicit conversions, and thus fail when T
3514// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3515template <typename BasicJsonType, typename T>
3520
3521template<typename BasicJsonType, typename T>
3522struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3523{
3524 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3525
3526 static constexpr bool value =
3528 const BasicJsonType&, T&>::value;
3529};
3530
3531// This trait checks if JSONSerializer<T>::from_json(json const&) exists
3532// this overload is used for non-default-constructible user-defined-types
3533template<typename BasicJsonType, typename T, typename = void>
3534struct has_non_default_from_json : std::false_type {};
3535
3536template<typename BasicJsonType, typename T>
3537struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3538{
3539 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3540
3541 static constexpr bool value =
3543 const BasicJsonType&>::value;
3544};
3545
3546// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3547// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3548template<typename BasicJsonType, typename T, typename = void>
3549struct has_to_json : std::false_type {};
3550
3551template<typename BasicJsonType, typename T>
3552struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3553{
3554 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3555
3556 static constexpr bool value =
3557 is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3558 T>::value;
3559};
3560
3561
3563// is_ functions //
3565
3566// https://en.cppreference.com/w/cpp/types/conjunction
3567template<class...> struct conjunction : std::true_type { };
3568template<class B1> struct conjunction<B1> : B1 { };
3569template<class B1, class... Bn>
3570struct conjunction<B1, Bn...>
3571: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3572
3573// https://en.cppreference.com/w/cpp/types/negation
3574template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3575
3576// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3577// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3578// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3579template <typename T>
3580struct is_default_constructible : std::is_default_constructible<T> {};
3581
3582template <typename T1, typename T2>
3583struct is_default_constructible<std::pair<T1, T2>>
3584 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3585
3586template <typename T1, typename T2>
3587struct is_default_constructible<const std::pair<T1, T2>>
3588 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3589
3590template <typename... Ts>
3591struct is_default_constructible<std::tuple<Ts...>>
3592 : conjunction<is_default_constructible<Ts>...> {};
3593
3594template <typename... Ts>
3595struct is_default_constructible<const std::tuple<Ts...>>
3596 : conjunction<is_default_constructible<Ts>...> {};
3597
3598
3599template <typename T, typename... Args>
3600struct is_constructible : std::is_constructible<T, Args...> {};
3601
3602template <typename T1, typename T2>
3603struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3604
3605template <typename T1, typename T2>
3606struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3607
3608template <typename... Ts>
3609struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3610
3611template <typename... Ts>
3612struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3613
3614
3615template<typename T, typename = void>
3616struct is_iterator_traits : std::false_type {};
3617
3618template<typename T>
3632
3633// The following implementation of is_complete_type is taken from
3634// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3635// and is written by Xiang Fan who agreed to using it in this library.
3636
3637template<typename T, typename = void>
3638struct is_complete_type : std::false_type {};
3639
3640template<typename T>
3641struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3642
3643template<typename BasicJsonType, typename CompatibleObjectType,
3644 typename = void>
3645struct is_compatible_object_type_impl : std::false_type {};
3646
3647template<typename BasicJsonType, typename CompatibleObjectType>
3649 BasicJsonType, CompatibleObjectType,
3650 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3651 is_detected<key_type_t, CompatibleObjectType>::value >>
3652{
3653 using object_t = typename BasicJsonType::object_t;
3654
3655 // macOS's is_constructible does not play well with nonesuch...
3656 static constexpr bool value =
3657 is_constructible<typename object_t::key_type,
3658 typename CompatibleObjectType::key_type>::value &&
3659 is_constructible<typename object_t::mapped_type,
3660 typename CompatibleObjectType::mapped_type>::value;
3661};
3662
3663template<typename BasicJsonType, typename CompatibleObjectType>
3665 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3666
3667template<typename BasicJsonType, typename ConstructibleObjectType,
3668 typename = void>
3669struct is_constructible_object_type_impl : std::false_type {};
3670
3671template<typename BasicJsonType, typename ConstructibleObjectType>
3673 BasicJsonType, ConstructibleObjectType,
3674 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3675 is_detected<key_type_t, ConstructibleObjectType>::value >>
3676{
3677 using object_t = typename BasicJsonType::object_t;
3678
3679 static constexpr bool value =
3681 (std::is_move_assignable<ConstructibleObjectType>::value ||
3682 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3683 (is_constructible<typename ConstructibleObjectType::key_type,
3684 typename object_t::key_type>::value &&
3685 std::is_same <
3686 typename object_t::mapped_type,
3687 typename ConstructibleObjectType::mapped_type >::value)) ||
3688 (has_from_json<BasicJsonType,
3689 typename ConstructibleObjectType::mapped_type>::value ||
3691 BasicJsonType,
3692 typename ConstructibleObjectType::mapped_type >::value);
3693};
3694
3695template<typename BasicJsonType, typename ConstructibleObjectType>
3697 : is_constructible_object_type_impl<BasicJsonType,
3698 ConstructibleObjectType> {};
3699
3700template<typename BasicJsonType, typename CompatibleStringType,
3701 typename = void>
3702struct is_compatible_string_type_impl : std::false_type {};
3703
3704template<typename BasicJsonType, typename CompatibleStringType>
3706 BasicJsonType, CompatibleStringType,
3707 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3708 value_type_t, CompatibleStringType>::value >>
3709{
3710 static constexpr auto value =
3712};
3713
3714template<typename BasicJsonType, typename ConstructibleStringType>
3716 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3717
3718template<typename BasicJsonType, typename ConstructibleStringType,
3719 typename = void>
3720struct is_constructible_string_type_impl : std::false_type {};
3721
3722template<typename BasicJsonType, typename ConstructibleStringType>
3724 BasicJsonType, ConstructibleStringType,
3725 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3726 value_type_t, ConstructibleStringType>::value >>
3727{
3728 static constexpr auto value =
3729 is_constructible<ConstructibleStringType,
3730 typename BasicJsonType::string_t>::value;
3731};
3732
3733template<typename BasicJsonType, typename ConstructibleStringType>
3735 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3736
3737template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3738struct is_compatible_array_type_impl : std::false_type {};
3739
3740template<typename BasicJsonType, typename CompatibleArrayType>
3742 BasicJsonType, CompatibleArrayType,
3743 enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value&&
3744 is_detected<iterator_t, CompatibleArrayType>::value&&
3745// This is needed because json_reverse_iterator has a ::iterator type...
3746// Therefore it is detected as a CompatibleArrayType.
3747// The real fix would be to have an Iterable concept.
3749 iterator_traits<CompatibleArrayType >>::value >>
3750{
3751 static constexpr bool value =
3752 is_constructible<BasicJsonType,
3753 typename CompatibleArrayType::value_type>::value;
3754};
3755
3756template<typename BasicJsonType, typename CompatibleArrayType>
3758 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3759
3760template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3761struct is_constructible_array_type_impl : std::false_type {};
3762
3763template<typename BasicJsonType, typename ConstructibleArrayType>
3765 BasicJsonType, ConstructibleArrayType,
3766 enable_if_t<std::is_same<ConstructibleArrayType,
3767 typename BasicJsonType::value_type>::value >>
3768 : std::true_type {};
3769
3770template<typename BasicJsonType, typename ConstructibleArrayType>
3772 BasicJsonType, ConstructibleArrayType,
3773 enable_if_t < !std::is_same<ConstructibleArrayType,
3774 typename BasicJsonType::value_type>::value&&
3775 is_default_constructible<ConstructibleArrayType>::value&&
3776(std::is_move_assignable<ConstructibleArrayType>::value ||
3777 std::is_copy_assignable<ConstructibleArrayType>::value)&&
3778is_detected<value_type_t, ConstructibleArrayType>::value&&
3779is_detected<iterator_t, ConstructibleArrayType>::value&&
3781detected_t<value_type_t, ConstructibleArrayType >>::value >>
3782{
3783 static constexpr bool value =
3784 // This is needed because json_reverse_iterator has a ::iterator type,
3785 // furthermore, std::back_insert_iterator (and other iterators) have a
3786 // base class `iterator`... Therefore it is detected as a
3787 // ConstructibleArrayType. The real fix would be to have an Iterable
3788 // concept.
3790
3791 (std::is_same<typename ConstructibleArrayType::value_type,
3792 typename BasicJsonType::array_t::value_type>::value ||
3793 has_from_json<BasicJsonType,
3794 typename ConstructibleArrayType::value_type>::value ||
3796 BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3797};
3798
3799template<typename BasicJsonType, typename ConstructibleArrayType>
3801 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3802
3803template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3804 typename = void>
3805struct is_compatible_integer_type_impl : std::false_type {};
3806
3807template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3809 RealIntegerType, CompatibleNumberIntegerType,
3810 enable_if_t < std::is_integral<RealIntegerType>::value&&
3811 std::is_integral<CompatibleNumberIntegerType>::value&&
3812 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3813{
3814 // is there an assert somewhere on overflows?
3815 using RealLimits = std::numeric_limits<RealIntegerType>;
3816 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3817
3818 static constexpr auto value =
3819 is_constructible<RealIntegerType,
3820 CompatibleNumberIntegerType>::value &&
3821 CompatibleLimits::is_integer &&
3822 RealLimits::is_signed == CompatibleLimits::is_signed;
3823};
3824
3825template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3827 : is_compatible_integer_type_impl<RealIntegerType,
3828 CompatibleNumberIntegerType> {};
3829
3830template<typename BasicJsonType, typename CompatibleType, typename = void>
3831struct is_compatible_type_impl: std::false_type {};
3832
3833template<typename BasicJsonType, typename CompatibleType>
3835 BasicJsonType, CompatibleType,
3836 enable_if_t<is_complete_type<CompatibleType>::value >>
3837{
3838 static constexpr bool value =
3840};
3841
3842template<typename BasicJsonType, typename CompatibleType>
3844 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3845
3846template<typename T1, typename T2>
3847struct is_constructible_tuple : std::false_type {};
3848
3849template<typename T1, typename... Args>
3850struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3851
3852// a naive helper to check if a type is an ordered_map (exploits the fact that
3853// ordered_map inherits capacity() from std::vector)
3854template <typename T>
3856{
3857 using one = char;
3858
3859 struct two
3860 {
3861 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3862 };
3863
3864 template <typename C> static one test( decltype(&C::capacity) ) ;
3865 template <typename C> static two test(...);
3866
3867 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3868};
3869
3870// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3871template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3873{
3874 return static_cast<T>(value);
3875}
3876
3877template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3879{
3880 return value;
3881}
3882
3883} // namespace detail
3884} // namespace nlohmann
3885
3886// #include <nlohmann/detail/value_t.hpp>
3887
3888
3889namespace nlohmann
3890{
3891namespace detail
3892{
3893template<typename BasicJsonType>
3894void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
3895{
3896 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3897 {
3898 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
3899 }
3900 n = nullptr;
3901}
3902
3903// overloads for basic_json template parameters
3904template < typename BasicJsonType, typename ArithmeticType,
3905 enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
3906 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3907 int > = 0 >
3908void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
3909{
3910 switch (static_cast<value_t>(j))
3911 {
3913 {
3914 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
3915 break;
3916 }
3918 {
3919 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
3920 break;
3921 }
3923 {
3924 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
3925 break;
3926 }
3927
3928 case value_t::null:
3929 case value_t::object:
3930 case value_t::array:
3931 case value_t::string:
3932 case value_t::boolean:
3933 case value_t::binary:
3934 case value_t::discarded:
3935 default:
3936 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
3937 }
3938}
3939
3940template<typename BasicJsonType>
3941void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
3942{
3943 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3944 {
3945 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
3946 }
3947 b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
3948}
3949
3950template<typename BasicJsonType>
3951void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
3952{
3953 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3954 {
3955 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3956 }
3957 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3958}
3959
3960template <
3961 typename BasicJsonType, typename ConstructibleStringType,
3962 enable_if_t <
3963 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value&&
3964 !std::is_same<typename BasicJsonType::string_t,
3965 ConstructibleStringType>::value,
3966 int > = 0 >
3967void from_json(const BasicJsonType& j, ConstructibleStringType& s)
3968{
3969 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3970 {
3971 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3972 }
3973
3974 s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
3975}
3976
3977template<typename BasicJsonType>
3978void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
3979{
3980 get_arithmetic_value(j, val);
3981}
3982
3983template<typename BasicJsonType>
3984void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
3985{
3986 get_arithmetic_value(j, val);
3987}
3988
3989template<typename BasicJsonType>
3990void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
3991{
3992 get_arithmetic_value(j, val);
3993}
3994
3995template<typename BasicJsonType, typename EnumType,
3996 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
3997void from_json(const BasicJsonType& j, EnumType& e)
3998{
3999 typename std::underlying_type<EnumType>::type val;
4000 get_arithmetic_value(j, val);
4001 e = static_cast<EnumType>(val);
4002}
4003
4004// forward_list doesn't have an insert method
4005template<typename BasicJsonType, typename T, typename Allocator,
4006 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4007void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4008{
4009 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4010 {
4011 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4012 }
4013 l.clear();
4014 std::transform(j.rbegin(), j.rend(),
4015 std::front_inserter(l), [](const BasicJsonType & i)
4016 {
4017 return i.template get<T>();
4018 });
4019}
4020
4021// valarray doesn't have an insert method
4022template<typename BasicJsonType, typename T,
4023 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4024void from_json(const BasicJsonType& j, std::valarray<T>& l)
4025{
4026 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4027 {
4028 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4029 }
4030 l.resize(j.size());
4031 std::transform(j.begin(), j.end(), std::begin(l),
4032 [](const BasicJsonType & elem)
4033 {
4034 return elem.template get<T>();
4035 });
4036}
4037
4038template<typename BasicJsonType, typename T, std::size_t N>
4039auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4040-> decltype(j.template get<T>(), void())
4041{
4042 for (std::size_t i = 0; i < N; ++i)
4043 {
4044 arr[i] = j.at(i).template get<T>();
4045 }
4046}
4047
4048template<typename BasicJsonType>
4049void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4050{
4051 arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4052}
4053
4054template<typename BasicJsonType, typename T, std::size_t N>
4055auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4056 priority_tag<2> /*unused*/)
4057-> decltype(j.template get<T>(), void())
4058{
4059 for (std::size_t i = 0; i < N; ++i)
4060 {
4061 arr[i] = j.at(i).template get<T>();
4062 }
4063}
4064
4065template<typename BasicJsonType, typename ConstructibleArrayType,
4067 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4068 int> = 0>
4069auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4070-> decltype(
4071 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4072 j.template get<typename ConstructibleArrayType::value_type>(),
4073 void())
4074{
4075 using std::end;
4076
4077 ConstructibleArrayType ret;
4078 ret.reserve(j.size());
4079 std::transform(j.begin(), j.end(),
4080 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4081 {
4082 // get<BasicJsonType>() returns *this, this won't call a from_json
4083 // method when value_type is BasicJsonType
4084 return i.template get<typename ConstructibleArrayType::value_type>();
4085 });
4086 arr = std::move(ret);
4087}
4088
4089template<typename BasicJsonType, typename ConstructibleArrayType,
4091 std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4092 int> = 0>
4093void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4094 priority_tag<0> /*unused*/)
4095{
4096 using std::end;
4097
4098 ConstructibleArrayType ret;
4099 std::transform(
4100 j.begin(), j.end(), std::inserter(ret, end(ret)),
4101 [](const BasicJsonType & i)
4102 {
4103 // get<BasicJsonType>() returns *this, this won't call a from_json
4104 // method when value_type is BasicJsonType
4105 return i.template get<typename ConstructibleArrayType::value_type>();
4106 });
4107 arr = std::move(ret);
4108}
4109
4110template < typename BasicJsonType, typename ConstructibleArrayType,
4111 enable_if_t <
4112 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4113 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4114 !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
4115 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4116 !is_basic_json<ConstructibleArrayType>::value,
4117 int > = 0 >
4118auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4119-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4120j.template get<typename ConstructibleArrayType::value_type>(),
4121void())
4122{
4123 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4124 {
4125 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4126 }
4127
4128 from_json_array_impl(j, arr, priority_tag<3> {});
4129}
4130
4131template < typename BasicJsonType, typename T, std::size_t... Idx >
4132std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4133 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4134{
4135 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4136}
4137
4138template < typename BasicJsonType, typename T, std::size_t N >
4139auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4140-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4141{
4142 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4143 {
4144 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4145 }
4146
4147 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4148}
4149
4150template<typename BasicJsonType>
4151void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4152{
4153 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4154 {
4155 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
4156 }
4157
4158 bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4159}
4160
4161template<typename BasicJsonType, typename ConstructibleObjectType,
4162 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4163void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4164{
4165 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4166 {
4167 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
4168 }
4169
4170 ConstructibleObjectType ret;
4171 const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4172 using value_type = typename ConstructibleObjectType::value_type;
4173 std::transform(
4174 inner_object->begin(), inner_object->end(),
4175 std::inserter(ret, ret.begin()),
4176 [](typename BasicJsonType::object_t::value_type const & p)
4177 {
4178 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4179 });
4180 obj = std::move(ret);
4181}
4182
4183// overload for arithmetic types, not chosen for basic_json template arguments
4184// (BooleanType, etc..); note: Is it really necessary to provide explicit
4185// overloads for boolean_t etc. in case of a custom BooleanType which is not
4186// an arithmetic type?
4187template < typename BasicJsonType, typename ArithmeticType,
4188 enable_if_t <
4189 std::is_arithmetic<ArithmeticType>::value&&
4190 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4191 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4192 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4193 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4194 int > = 0 >
4195void from_json(const BasicJsonType& j, ArithmeticType& val)
4196{
4197 switch (static_cast<value_t>(j))
4198 {
4200 {
4201 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4202 break;
4203 }
4205 {
4206 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4207 break;
4208 }
4210 {
4211 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4212 break;
4213 }
4214 case value_t::boolean:
4215 {
4216 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4217 break;
4218 }
4219
4220 case value_t::null:
4221 case value_t::object:
4222 case value_t::array:
4223 case value_t::string:
4224 case value_t::binary:
4225 case value_t::discarded:
4226 default:
4227 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4228 }
4229}
4230
4231template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4232std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4233{
4234 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4235}
4236
4237template < typename BasicJsonType, class A1, class A2 >
4238std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4239{
4240 return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4241 std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4242}
4243
4244template<typename BasicJsonType, typename A1, typename A2>
4245void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4246{
4247 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4248}
4249
4250template<typename BasicJsonType, typename... Args>
4251std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4252{
4253 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4254}
4255
4256template<typename BasicJsonType, typename... Args>
4257void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4258{
4259 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4260}
4261
4262template<typename BasicJsonType, typename TupleRelated>
4263auto from_json(BasicJsonType&& j, TupleRelated&& t)
4264-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4265{
4266 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4267 {
4268 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4269 }
4270
4271 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4272}
4273
4274template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4275 typename = enable_if_t < !std::is_constructible <
4276 typename BasicJsonType::string_t, Key >::value >>
4277void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4278{
4279 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4280 {
4281 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4282 }
4283 m.clear();
4284 for (const auto& p : j)
4285 {
4286 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4287 {
4288 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4289 }
4290 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4291 }
4292}
4293
4294template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4295 typename = enable_if_t < !std::is_constructible <
4296 typename BasicJsonType::string_t, Key >::value >>
4297void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4298{
4299 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4300 {
4301 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4302 }
4303 m.clear();
4304 for (const auto& p : j)
4305 {
4306 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4307 {
4308 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4309 }
4310 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4311 }
4312}
4313
4315{
4316 template<typename BasicJsonType, typename T>
4317 auto operator()(const BasicJsonType& j, T&& val) const
4318 noexcept(noexcept(from_json(j, std::forward<T>(val))))
4319 -> decltype(from_json(j, std::forward<T>(val)))
4320 {
4321 return from_json(j, std::forward<T>(val));
4322 }
4323};
4324} // namespace detail
4325
4329namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4330{
4331constexpr const auto& from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4332} // namespace
4333} // namespace nlohmann
4334
4335// #include <nlohmann/detail/conversions/to_json.hpp>
4336
4337
4338#include <algorithm> // copy
4339#include <iterator> // begin, end
4340#include <string> // string
4341#include <tuple> // tuple, get
4342#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4343#include <utility> // move, forward, declval, pair
4344#include <valarray> // valarray
4345#include <vector> // vector
4346
4347// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4348
4349
4350#include <cstddef> // size_t
4351#include <iterator> // input_iterator_tag
4352#include <string> // string, to_string
4353#include <tuple> // tuple_size, get, tuple_element
4354#include <utility> // move
4355
4356// #include <nlohmann/detail/meta/type_traits.hpp>
4357
4358// #include <nlohmann/detail/value_t.hpp>
4359
4360
4361namespace nlohmann
4362{
4363namespace detail
4364{
4365template<typename string_type>
4366void int_to_string( string_type& target, std::size_t value )
4367{
4368 // For ADL
4369 using std::to_string;
4370 target = to_string(value);
4371}
4372template<typename IteratorType> class iteration_proxy_value
4373{
4374 public:
4375 using difference_type = std::ptrdiff_t;
4379 using iterator_category = std::input_iterator_tag;
4380 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4381
4382 private:
4384 IteratorType anchor;
4386 std::size_t array_index = 0;
4388 mutable std::size_t array_index_last = 0;
4393
4394 public:
4395 explicit iteration_proxy_value(IteratorType it) noexcept
4396 : anchor(std::move(it))
4397 {}
4398
4401 {
4402 return *this;
4403 }
4404
4407 {
4408 ++anchor;
4409 ++array_index;
4410
4411 return *this;
4412 }
4413
4416 {
4417 return anchor == o.anchor;
4418 }
4419
4422 {
4423 return anchor != o.anchor;
4424 }
4425
4427 const string_type& key() const
4428 {
4429 JSON_ASSERT(anchor.m_object != nullptr);
4430
4431 switch (anchor.m_object->type())
4432 {
4433 // use integer array index as key
4434 case value_t::array:
4435 {
4437 {
4440 }
4441 return array_index_str;
4442 }
4443
4444 // use key from the object
4445 case value_t::object:
4446 return anchor.key();
4447
4448 // use an empty key for all primitive types
4449 case value_t::null:
4450 case value_t::string:
4451 case value_t::boolean:
4455 case value_t::binary:
4456 case value_t::discarded:
4457 default:
4458 return empty_str;
4459 }
4460 }
4461
4463 typename IteratorType::reference value() const
4464 {
4465 return anchor.value();
4466 }
4467};
4468
4470template<typename IteratorType> class iteration_proxy
4471{
4472 private:
4474 typename IteratorType::reference container;
4475
4476 public:
4478 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4479 : container(cont) {}
4480
4486
4492};
4493// Structured Bindings Support
4494// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4495// And see https://github.com/nlohmann/json/pull/1391
4496template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4498{
4499 return i.key();
4500}
4501// Structured Bindings Support
4502// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4503// And see https://github.com/nlohmann/json/pull/1391
4504template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4505auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4506{
4507 return i.value();
4508}
4509} // namespace detail
4510} // namespace nlohmann
4511
4512// The Addition to the STD Namespace is required to add
4513// Structured Bindings Support to the iteration_proxy_value class
4514// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4515// And see https://github.com/nlohmann/json/pull/1391
4516namespace std
4517{
4518#if defined(__clang__)
4519 // Fix: https://github.com/nlohmann/json/issues/1401
4520 #pragma clang diagnostic push
4521 #pragma clang diagnostic ignored "-Wmismatched-tags"
4522#endif
4523template<typename IteratorType>
4524class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4525 : public std::integral_constant<std::size_t, 2> {};
4526
4527template<std::size_t N, typename IteratorType>
4528class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4529{
4530 public:
4531 using type = decltype(
4532 get<N>(std::declval <
4534};
4535#if defined(__clang__)
4536 #pragma clang diagnostic pop
4537#endif
4538} // namespace std
4539
4540// #include <nlohmann/detail/meta/cpp_future.hpp>
4541
4542// #include <nlohmann/detail/meta/type_traits.hpp>
4543
4544// #include <nlohmann/detail/value_t.hpp>
4545
4546
4547namespace nlohmann
4548{
4549namespace detail
4550{
4552// constructors //
4554
4555/*
4556 * Note all external_constructor<>::construct functions need to call
4557 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4558 * allocated value (e.g., a string). See bug issue
4559 * https://github.com/nlohmann/json/issues/2865 for more information.
4560 */
4561
4562template<value_t> struct external_constructor;
4563
4564template<>
4566{
4567 template<typename BasicJsonType>
4568 static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
4569 {
4570 j.m_value.destroy(j.m_type);
4571 j.m_type = value_t::boolean;
4572 j.m_value = b;
4573 j.assert_invariant();
4574 }
4575};
4576
4577template<>
4579{
4580 template<typename BasicJsonType>
4581 static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
4582 {
4583 j.m_value.destroy(j.m_type);
4584 j.m_type = value_t::string;
4585 j.m_value = s;
4586 j.assert_invariant();
4587 }
4588
4589 template<typename BasicJsonType>
4590 static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4591 {
4592 j.m_value.destroy(j.m_type);
4593 j.m_type = value_t::string;
4594 j.m_value = std::move(s);
4595 j.assert_invariant();
4596 }
4597
4598 template < typename BasicJsonType, typename CompatibleStringType,
4599 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4600 int > = 0 >
4601 static void construct(BasicJsonType& j, const CompatibleStringType& str)
4602 {
4603 j.m_value.destroy(j.m_type);
4604 j.m_type = value_t::string;
4605 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4606 j.assert_invariant();
4607 }
4608};
4609
4610template<>
4612{
4613 template<typename BasicJsonType>
4614 static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
4615 {
4616 j.m_value.destroy(j.m_type);
4617 j.m_type = value_t::binary;
4618 j.m_value = typename BasicJsonType::binary_t(b);
4619 j.assert_invariant();
4620 }
4621
4622 template<typename BasicJsonType>
4623 static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
4624 {
4625 j.m_value.destroy(j.m_type);
4626 j.m_type = value_t::binary;
4627 j.m_value = typename BasicJsonType::binary_t(std::move(b));
4628 j.assert_invariant();
4629 }
4630};
4631
4632template<>
4634{
4635 template<typename BasicJsonType>
4636 static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
4637 {
4638 j.m_value.destroy(j.m_type);
4639 j.m_type = value_t::number_float;
4640 j.m_value = val;
4641 j.assert_invariant();
4642 }
4643};
4644
4645template<>
4647{
4648 template<typename BasicJsonType>
4649 static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
4650 {
4651 j.m_value.destroy(j.m_type);
4652 j.m_type = value_t::number_unsigned;
4653 j.m_value = val;
4654 j.assert_invariant();
4655 }
4656};
4657
4658template<>
4660{
4661 template<typename BasicJsonType>
4662 static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
4663 {
4664 j.m_value.destroy(j.m_type);
4665 j.m_type = value_t::number_integer;
4666 j.m_value = val;
4667 j.assert_invariant();
4668 }
4669};
4670
4671template<>
4673{
4674 template<typename BasicJsonType>
4675 static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
4676 {
4677 j.m_value.destroy(j.m_type);
4678 j.m_type = value_t::array;
4679 j.m_value = arr;
4680 j.set_parents();
4681 j.assert_invariant();
4682 }
4683
4684 template<typename BasicJsonType>
4685 static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4686 {
4687 j.m_value.destroy(j.m_type);
4688 j.m_type = value_t::array;
4689 j.m_value = std::move(arr);
4690 j.set_parents();
4691 j.assert_invariant();
4692 }
4693
4694 template < typename BasicJsonType, typename CompatibleArrayType,
4695 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4696 int > = 0 >
4697 static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
4698 {
4699 using std::begin;
4700 using std::end;
4701
4702 j.m_value.destroy(j.m_type);
4703 j.m_type = value_t::array;
4704 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4705 j.set_parents();
4706 j.assert_invariant();
4707 }
4708
4709 template<typename BasicJsonType>
4710 static void construct(BasicJsonType& j, const std::vector<bool>& arr)
4711 {
4712 j.m_value.destroy(j.m_type);
4713 j.m_type = value_t::array;
4714 j.m_value = value_t::array;
4715 j.m_value.array->reserve(arr.size());
4716 for (const bool x : arr)
4717 {
4718 j.m_value.array->push_back(x);
4719 j.set_parent(j.m_value.array->back());
4720 }
4721 j.assert_invariant();
4722 }
4723
4724 template<typename BasicJsonType, typename T,
4726 static void construct(BasicJsonType& j, const std::valarray<T>& arr)
4727 {
4728 j.m_value.destroy(j.m_type);
4729 j.m_type = value_t::array;
4730 j.m_value = value_t::array;
4731 j.m_value.array->resize(arr.size());
4732 if (arr.size() > 0)
4733 {
4734 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4735 }
4736 j.set_parents();
4737 j.assert_invariant();
4738 }
4739};
4740
4741template<>
4743{
4744 template<typename BasicJsonType>
4745 static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
4746 {
4747 j.m_value.destroy(j.m_type);
4748 j.m_type = value_t::object;
4749 j.m_value = obj;
4750 j.set_parents();
4751 j.assert_invariant();
4752 }
4753
4754 template<typename BasicJsonType>
4755 static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4756 {
4757 j.m_value.destroy(j.m_type);
4758 j.m_type = value_t::object;
4759 j.m_value = std::move(obj);
4760 j.set_parents();
4761 j.assert_invariant();
4762 }
4763
4764 template < typename BasicJsonType, typename CompatibleObjectType,
4765 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4766 static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
4767 {
4768 using std::begin;
4769 using std::end;
4770
4771 j.m_value.destroy(j.m_type);
4772 j.m_type = value_t::object;
4773 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4774 j.set_parents();
4775 j.assert_invariant();
4776 }
4777};
4778
4780// to_json //
4782
4783template<typename BasicJsonType, typename T,
4784 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4785void to_json(BasicJsonType& j, T b) noexcept
4786{
4788}
4789
4790template<typename BasicJsonType, typename CompatibleString,
4791 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4792void to_json(BasicJsonType& j, const CompatibleString& s)
4793{
4795}
4796
4797template<typename BasicJsonType>
4798void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
4799{
4801}
4802
4803template<typename BasicJsonType, typename FloatType,
4804 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4805void to_json(BasicJsonType& j, FloatType val) noexcept
4806{
4807 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4808}
4809
4810template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4811 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4812void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
4813{
4814 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4815}
4816
4817template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4818 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4819void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
4820{
4821 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4822}
4823
4824template<typename BasicJsonType, typename EnumType,
4825 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4826void to_json(BasicJsonType& j, EnumType e) noexcept
4827{
4828 using underlying_type = typename std::underlying_type<EnumType>::type;
4829 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4830}
4831
4832template<typename BasicJsonType>
4833void to_json(BasicJsonType& j, const std::vector<bool>& e)
4834{
4836}
4837
4838template < typename BasicJsonType, typename CompatibleArrayType,
4839 enable_if_t < is_compatible_array_type<BasicJsonType,
4840 CompatibleArrayType>::value&&
4841 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
4842 !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value&&
4843 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
4844 !is_basic_json<CompatibleArrayType>::value,
4845 int > = 0 >
4846void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
4847{
4849}
4850
4851template<typename BasicJsonType>
4852void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
4853{
4855}
4856
4857template<typename BasicJsonType, typename T,
4858 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4859void to_json(BasicJsonType& j, const std::valarray<T>& arr)
4860{
4862}
4863
4864template<typename BasicJsonType>
4865void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
4866{
4868}
4869
4870template < typename BasicJsonType, typename CompatibleObjectType,
4871 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4872void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
4873{
4875}
4876
4877template<typename BasicJsonType>
4878void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
4879{
4881}
4882
4883template <
4884 typename BasicJsonType, typename T, std::size_t N,
4885 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4886 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4887 int > = 0 >
4888void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4889{
4891}
4892
4893template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4894void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
4895{
4896 j = { p.first, p.second };
4897}
4898
4899// for https://github.com/nlohmann/json/pull/1134
4900template<typename BasicJsonType, typename T,
4901 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4902void to_json(BasicJsonType& j, const T& b)
4903{
4904 j = { {b.key(), b.value()} };
4905}
4906
4907template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4908void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
4909{
4910 j = { std::get<Idx>(t)... };
4911}
4912
4913template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4914void to_json(BasicJsonType& j, const T& t)
4915{
4916 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4917}
4918
4920{
4921 template<typename BasicJsonType, typename T>
4922 auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4923 -> decltype(to_json(j, std::forward<T>(val)), void())
4924 {
4925 return to_json(j, std::forward<T>(val));
4926 }
4927};
4928} // namespace detail
4929
4933namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4934{
4935constexpr const auto& to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4936} // namespace
4937} // namespace nlohmann
4938
4939// #include <nlohmann/detail/meta/identity_tag.hpp>
4940
4941// #include <nlohmann/detail/meta/type_traits.hpp>
4942
4943
4944namespace nlohmann
4945{
4946
4947template<typename ValueType, typename>
4949{
4961 template<typename BasicJsonType, typename TargetType = ValueType>
4962 static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
4963 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4964 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4965 {
4966 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4967 }
4968
4981 template<typename BasicJsonType, typename TargetType = ValueType>
4982 static auto from_json(BasicJsonType && j) noexcept(
4983 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
4984 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
4985 {
4986 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
4987 }
4988
4998 template<typename BasicJsonType, typename TargetType = ValueType>
4999 static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5000 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5001 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5002 {
5003 ::nlohmann::to_json(j, std::forward<TargetType>(val));
5004 }
5005};
5006} // namespace nlohmann
5007
5008// #include <nlohmann/byte_container_with_subtype.hpp>
5009
5010
5011#include <cstdint> // uint8_t, uint64_t
5012#include <tuple> // tie
5013#include <utility> // move
5014
5015namespace nlohmann
5016{
5017
5031template<typename BinaryType>
5032class byte_container_with_subtype : public BinaryType
5033{
5034 public:
5036 using container_type = BinaryType;
5038 using subtype_type = std::uint64_t;
5039
5041 : container_type()
5042 {}
5043
5045 : container_type(b)
5046 {}
5047
5048 byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5049 : container_type(std::move(b))
5050 {}
5051
5053 : container_type(b)
5054 , m_subtype(subtype_)
5055 , m_has_subtype(true)
5056 {}
5057
5058 byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5059 : container_type(std::move(b))
5060 , m_subtype(subtype_)
5061 , m_has_subtype(true)
5062 {}
5063
5065 {
5066 return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5067 std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5068 }
5069
5071 {
5072 return !(rhs == *this);
5073 }
5074
5093 void set_subtype(subtype_type subtype_) noexcept
5094 {
5095 m_subtype = subtype_;
5096 m_has_subtype = true;
5097 }
5098
5121 constexpr subtype_type subtype() const noexcept
5122 {
5123 return m_has_subtype ? m_subtype : subtype_type(-1);
5124 }
5125
5142 constexpr bool has_subtype() const noexcept
5143 {
5144 return m_has_subtype;
5145 }
5146
5166 void clear_subtype() noexcept
5167 {
5168 m_subtype = 0;
5169 m_has_subtype = false;
5170 }
5171
5172 private:
5174 bool m_has_subtype = false;
5175};
5176
5177} // namespace nlohmann
5178
5179// #include <nlohmann/detail/conversions/from_json.hpp>
5180
5181// #include <nlohmann/detail/conversions/to_json.hpp>
5182
5183// #include <nlohmann/detail/exceptions.hpp>
5184
5185// #include <nlohmann/detail/hash.hpp>
5186
5187
5188#include <cstdint> // uint8_t
5189#include <cstddef> // size_t
5190#include <functional> // hash
5191
5192// #include <nlohmann/detail/macro_scope.hpp>
5193
5194// #include <nlohmann/detail/value_t.hpp>
5195
5196
5197namespace nlohmann
5198{
5199namespace detail
5200{
5201
5202// boost::hash_combine
5203inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5204{
5205 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5206 return seed;
5207}
5208
5220template<typename BasicJsonType>
5221std::size_t hash(const BasicJsonType& j)
5222{
5223 using string_t = typename BasicJsonType::string_t;
5224 using number_integer_t = typename BasicJsonType::number_integer_t;
5225 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5226 using number_float_t = typename BasicJsonType::number_float_t;
5227
5228 const auto type = static_cast<std::size_t>(j.type());
5229 switch (j.type())
5230 {
5231 case BasicJsonType::value_t::null:
5232 case BasicJsonType::value_t::discarded:
5233 {
5234 return combine(type, 0);
5235 }
5236
5237 case BasicJsonType::value_t::object:
5238 {
5239 auto seed = combine(type, j.size());
5240 for (const auto& element : j.items())
5241 {
5242 const auto h = std::hash<string_t> {}(element.key());
5243 seed = combine(seed, h);
5244 seed = combine(seed, hash(element.value()));
5245 }
5246 return seed;
5247 }
5248
5249 case BasicJsonType::value_t::array:
5250 {
5251 auto seed = combine(type, j.size());
5252 for (const auto& element : j)
5253 {
5254 seed = combine(seed, hash(element));
5255 }
5256 return seed;
5257 }
5258
5259 case BasicJsonType::value_t::string:
5260 {
5261 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5262 return combine(type, h);
5263 }
5264
5265 case BasicJsonType::value_t::boolean:
5266 {
5267 const auto h = std::hash<bool> {}(j.template get<bool>());
5268 return combine(type, h);
5269 }
5270
5271 case BasicJsonType::value_t::number_integer:
5272 {
5273 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5274 return combine(type, h);
5275 }
5276
5277 case BasicJsonType::value_t::number_unsigned:
5278 {
5279 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5280 return combine(type, h);
5281 }
5282
5283 case BasicJsonType::value_t::number_float:
5284 {
5285 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5286 return combine(type, h);
5287 }
5288
5289 case BasicJsonType::value_t::binary:
5290 {
5291 auto seed = combine(type, j.get_binary().size());
5292 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5293 seed = combine(seed, h);
5294 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5295 for (const auto byte : j.get_binary())
5296 {
5297 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5298 }
5299 return seed;
5300 }
5301
5302 default: // LCOV_EXCL_LINE
5303 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5304 return 0; // LCOV_EXCL_LINE
5305 }
5306}
5307
5308} // namespace detail
5309} // namespace nlohmann
5310
5311// #include <nlohmann/detail/input/binary_reader.hpp>
5312
5313
5314#include <algorithm> // generate_n
5315#include <array> // array
5316#include <cmath> // ldexp
5317#include <cstddef> // size_t
5318#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5319#include <cstdio> // snprintf
5320#include <cstring> // memcpy
5321#include <iterator> // back_inserter
5322#include <limits> // numeric_limits
5323#include <string> // char_traits, string
5324#include <utility> // make_pair, move
5325#include <vector> // vector
5326
5327// #include <nlohmann/detail/exceptions.hpp>
5328
5329// #include <nlohmann/detail/input/input_adapters.hpp>
5330
5331
5332#include <array> // array
5333#include <cstddef> // size_t
5334#include <cstring> // strlen
5335#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5336#include <memory> // shared_ptr, make_shared, addressof
5337#include <numeric> // accumulate
5338#include <string> // string, char_traits
5339#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5340#include <utility> // pair, declval
5341
5342#ifndef JSON_NO_IO
5343 #include <cstdio> // FILE *
5344 #include <istream> // istream
5345#endif // JSON_NO_IO
5346
5347// #include <nlohmann/detail/iterators/iterator_traits.hpp>
5348
5349// #include <nlohmann/detail/macro_scope.hpp>
5350
5351
5352namespace nlohmann
5353{
5354namespace detail
5355{
5358
5360// input adapters //
5362
5363#ifndef JSON_NO_IO
5369{
5370 public:
5371 using char_type = char;
5372
5374 explicit file_input_adapter(std::FILE* f) noexcept
5375 : m_file(f)
5376 {}
5377
5378 // make class move-only
5381 file_input_adapter& operator=(const file_input_adapter&) = delete;
5384
5385 std::char_traits<char>::int_type get_character() noexcept
5386 {
5387 return std::fgetc(m_file);
5388 }
5389
5390 private:
5392 std::FILE* m_file;
5393};
5394
5395
5406{
5407 public:
5408 using char_type = char;
5409
5411 {
5412 // clear stream flags; we use underlying streambuf I/O, do not
5413 // maintain ifstream flags, except eof
5414 if (is != nullptr)
5415 {
5416 is->clear(is->rdstate() & std::ios::eofbit);
5417 }
5418 }
5419
5420 explicit input_stream_adapter(std::istream& i)
5421 : is(&i), sb(i.rdbuf())
5422 {}
5423
5424 // delete because of pointer members
5428
5430 : is(rhs.is), sb(rhs.sb)
5431 {
5432 rhs.is = nullptr;
5433 rhs.sb = nullptr;
5434 }
5435
5436 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5437 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5438 // end up as the same value, eg. 0xFFFFFFFF.
5439 std::char_traits<char>::int_type get_character()
5440 {
5441 auto res = sb->sbumpc();
5442 // set eof manually, as we don't use the istream interface.
5443 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5444 {
5445 is->clear(is->rdstate() | std::ios::eofbit);
5446 }
5447 return res;
5448 }
5449
5450 private:
5452 std::istream* is = nullptr;
5453 std::streambuf* sb = nullptr;
5454};
5455#endif // JSON_NO_IO
5456
5457// General-purpose iterator-based adapter. It might not be as fast as
5458// theoretically possible for some containers, but it is extremely versatile.
5459template<typename IteratorType>
5461{
5462 public:
5463 using char_type = typename std::iterator_traits<IteratorType>::value_type;
5464
5465 iterator_input_adapter(IteratorType first, IteratorType last)
5466 : current(std::move(first)), end(std::move(last))
5467 {}
5468
5469 typename std::char_traits<char_type>::int_type get_character()
5470 {
5472 {
5473 auto result = std::char_traits<char_type>::to_int_type(*current);
5474 std::advance(current, 1);
5475 return result;
5476 }
5477
5478 return std::char_traits<char_type>::eof();
5479 }
5480
5481 private:
5482 IteratorType current;
5483 IteratorType end;
5484
5485 template<typename BaseInputAdapter, size_t T>
5487
5488 bool empty() const
5489 {
5490 return current == end;
5491 }
5492};
5493
5494
5495template<typename BaseInputAdapter, size_t T>
5497
5498template<typename BaseInputAdapter>
5499struct wide_string_input_helper<BaseInputAdapter, 4>
5500{
5501 // UTF-32
5502 static void fill_buffer(BaseInputAdapter& input,
5503 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5504 size_t& utf8_bytes_index,
5505 size_t& utf8_bytes_filled)
5506 {
5507 utf8_bytes_index = 0;
5508
5509 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5510 {
5511 utf8_bytes[0] = std::char_traits<char>::eof();
5512 utf8_bytes_filled = 1;
5513 }
5514 else
5515 {
5516 // get the current character
5517 const auto wc = input.get_character();
5518
5519 // UTF-32 to UTF-8 encoding
5520 if (wc < 0x80)
5521 {
5522 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5523 utf8_bytes_filled = 1;
5524 }
5525 else if (wc <= 0x7FF)
5526 {
5527 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5528 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5529 utf8_bytes_filled = 2;
5530 }
5531 else if (wc <= 0xFFFF)
5532 {
5533 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5534 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5535 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5536 utf8_bytes_filled = 3;
5537 }
5538 else if (wc <= 0x10FFFF)
5539 {
5540 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5541 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5542 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5543 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5544 utf8_bytes_filled = 4;
5545 }
5546 else
5547 {
5548 // unknown character
5549 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5550 utf8_bytes_filled = 1;
5551 }
5552 }
5553 }
5554};
5555
5556template<typename BaseInputAdapter>
5557struct wide_string_input_helper<BaseInputAdapter, 2>
5558{
5559 // UTF-16
5560 static void fill_buffer(BaseInputAdapter& input,
5561 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5562 size_t& utf8_bytes_index,
5563 size_t& utf8_bytes_filled)
5564 {
5565 utf8_bytes_index = 0;
5566
5567 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5568 {
5569 utf8_bytes[0] = std::char_traits<char>::eof();
5570 utf8_bytes_filled = 1;
5571 }
5572 else
5573 {
5574 // get the current character
5575 const auto wc = input.get_character();
5576
5577 // UTF-16 to UTF-8 encoding
5578 if (wc < 0x80)
5579 {
5580 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5581 utf8_bytes_filled = 1;
5582 }
5583 else if (wc <= 0x7FF)
5584 {
5585 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5586 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5587 utf8_bytes_filled = 2;
5588 }
5589 else if (0xD800 > wc || wc >= 0xE000)
5590 {
5591 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5592 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5593 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5594 utf8_bytes_filled = 3;
5595 }
5596 else
5597 {
5598 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5599 {
5600 const auto wc2 = static_cast<unsigned int>(input.get_character());
5601 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5602 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5603 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5604 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5605 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5606 utf8_bytes_filled = 4;
5607 }
5608 else
5609 {
5610 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5611 utf8_bytes_filled = 1;
5612 }
5613 }
5614 }
5615 }
5616};
5617
5618// Wraps another input apdater to convert wide character types into individual bytes.
5619template<typename BaseInputAdapter, typename WideCharType>
5621{
5622 public:
5623 using char_type = char;
5624
5625 wide_string_input_adapter(BaseInputAdapter base)
5626 : base_adapter(base) {}
5627
5628 typename std::char_traits<char>::int_type get_character() noexcept
5629 {
5630 // check if buffer needs to be filled
5632 {
5633 fill_buffer<sizeof(WideCharType)>();
5634
5637 }
5638
5639 // use buffer
5642 return utf8_bytes[utf8_bytes_index++];
5643 }
5644
5645 private:
5646 BaseInputAdapter base_adapter;
5647
5648 template<size_t T>
5653
5655 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5656
5658 std::size_t utf8_bytes_index = 0;
5660 std::size_t utf8_bytes_filled = 0;
5661};
5662
5663
5664template<typename IteratorType, typename Enable = void>
5666{
5667 using iterator_type = IteratorType;
5668 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5670
5671 static adapter_type create(IteratorType first, IteratorType last)
5672 {
5673 return adapter_type(std::move(first), std::move(last));
5674 }
5675};
5676
5677template<typename T>
5679{
5680 using value_type = typename std::iterator_traits<T>::value_type;
5681 enum
5682 {
5683 value = sizeof(value_type) > 1
5684 };
5685};
5686
5687template<typename IteratorType>
5689{
5690 using iterator_type = IteratorType;
5691 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5694
5695 static adapter_type create(IteratorType first, IteratorType last)
5696 {
5697 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5698 }
5699};
5700
5701// General purpose iterator-based input
5702template<typename IteratorType>
5704{
5706 return factory_type::create(first, last);
5707}
5708
5709// Convenience shorthand from container to iterator
5710// Enables ADL on begin(container) and end(container)
5711// Encloses the using declarations in namespace for not to leak them to outside scope
5712
5713namespace container_input_adapter_factory_impl
5714{
5715
5716using std::begin;
5717using std::end;
5718
5719template<typename ContainerType, typename Enable = void>
5721
5722template<typename ContainerType>
5724 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5725 {
5726 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5727
5728 static adapter_type create(const ContainerType& container)
5729{
5730 return input_adapter(begin(container), end(container));
5731}
5732 };
5733
5734} // namespace container_input_adapter_factory_impl
5735
5736template<typename ContainerType>
5741
5742#ifndef JSON_NO_IO
5743// Special cases with fast paths
5744inline file_input_adapter input_adapter(std::FILE* file)
5745{
5746 return file_input_adapter(file);
5747}
5748
5749inline input_stream_adapter input_adapter(std::istream& stream)
5750{
5751 return input_stream_adapter(stream);
5752}
5753
5754inline input_stream_adapter input_adapter(std::istream&& stream)
5755{
5756 return input_stream_adapter(stream);
5757}
5758#endif // JSON_NO_IO
5759
5760using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
5761
5762// Null-delimited strings, and the like.
5763template < typename CharT,
5764 typename std::enable_if <
5765 std::is_pointer<CharT>::value&&
5766 !std::is_array<CharT>::value&&
5767 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5768 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5769 int >::type = 0 >
5771{
5772 auto length = std::strlen(reinterpret_cast<const char*>(b));
5773 const auto* ptr = reinterpret_cast<const char*>(b);
5774 return input_adapter(ptr, ptr + length);
5775}
5776
5777template<typename T, std::size_t N>
5778auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5779{
5780 return input_adapter(array, array + N);
5781}
5782
5783// This class only handles inputs of input_buffer_adapter type.
5784// It's required so that expressions like {ptr, len} can be implicitely casted
5785// to the correct adapter.
5787{
5788 public:
5789 template < typename CharT,
5790 typename std::enable_if <
5791 std::is_pointer<CharT>::value&&
5792 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
5793 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5794 int >::type = 0 >
5795 span_input_adapter(CharT b, std::size_t l)
5796 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
5797
5798 template<class IteratorType,
5799 typename std::enable_if<
5800 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5801 int>::type = 0>
5802 span_input_adapter(IteratorType first, IteratorType last)
5803 : ia(input_adapter(first, last)) {}
5804
5806 {
5807 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5808 }
5809
5810 private:
5812};
5813} // namespace detail
5814} // namespace nlohmann
5815
5816// #include <nlohmann/detail/input/json_sax.hpp>
5817
5818
5819#include <cstddef>
5820#include <string> // string
5821#include <utility> // move
5822#include <vector> // vector
5823
5824// #include <nlohmann/detail/exceptions.hpp>
5825
5826// #include <nlohmann/detail/macro_scope.hpp>
5827
5828
5829namespace nlohmann
5830{
5831
5840template<typename BasicJsonType>
5842{
5843 using number_integer_t = typename BasicJsonType::number_integer_t;
5844 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5845 using number_float_t = typename BasicJsonType::number_float_t;
5846 using string_t = typename BasicJsonType::string_t;
5847 using binary_t = typename BasicJsonType::binary_t;
5848
5853 virtual bool null() = 0;
5854
5860 virtual bool boolean(bool val) = 0;
5861
5867 virtual bool number_integer(number_integer_t val) = 0;
5868
5874 virtual bool number_unsigned(number_unsigned_t val) = 0;
5875
5882 virtual bool number_float(number_float_t val, const string_t& s) = 0;
5883
5890 virtual bool string(string_t& val) = 0;
5891
5898 virtual bool binary(binary_t& val) = 0;
5899
5906 virtual bool start_object(std::size_t elements) = 0;
5907
5914 virtual bool key(string_t& val) = 0;
5915
5920 virtual bool end_object() = 0;
5921
5928 virtual bool start_array(std::size_t elements) = 0;
5929
5934 virtual bool end_array() = 0;
5935
5943 virtual bool parse_error(std::size_t position,
5944 const std::string& last_token,
5945 const detail::exception& ex) = 0;
5946
5947 json_sax() = default;
5948 json_sax(const json_sax&) = default;
5949 json_sax(json_sax&&) noexcept = default;
5950 json_sax& operator=(const json_sax&) = default;
5951 json_sax& operator=(json_sax&&) noexcept = default;
5952 virtual ~json_sax() = default;
5953};
5954
5955
5956namespace detail
5957{
5971template<typename BasicJsonType>
5973{
5974 public:
5975 using number_integer_t = typename BasicJsonType::number_integer_t;
5976 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5977 using number_float_t = typename BasicJsonType::number_float_t;
5978 using string_t = typename BasicJsonType::string_t;
5979 using binary_t = typename BasicJsonType::binary_t;
5980
5986 explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
5987 : root(r), allow_exceptions(allow_exceptions_)
5988 {}
5989
5990 // make class move-only
5992 json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5994 json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
5996
5997 bool null()
5998 {
5999 handle_value(nullptr);
6000 return true;
6001 }
6002
6003 bool boolean(bool val)
6004 {
6005 handle_value(val);
6006 return true;
6007 }
6008
6010 {
6011 handle_value(val);
6012 return true;
6013 }
6014
6016 {
6017 handle_value(val);
6018 return true;
6019 }
6020
6021 bool number_float(number_float_t val, const string_t& /*unused*/)
6022 {
6023 handle_value(val);
6024 return true;
6025 }
6026
6027 bool string(string_t& val)
6028 {
6029 handle_value(val);
6030 return true;
6031 }
6032
6033 bool binary(binary_t& val)
6034 {
6035 handle_value(std::move(val));
6036 return true;
6037 }
6038
6039 bool start_object(std::size_t len)
6040 {
6041 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6042
6043 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6044 {
6045 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6046 }
6047
6048 return true;
6049 }
6050
6051 bool key(string_t& val)
6052 {
6053 // add null at given key and store the reference for later
6054 object_element = &(ref_stack.back()->m_value.object->operator[](val));
6055 return true;
6056 }
6057
6059 {
6060 ref_stack.back()->set_parents();
6061 ref_stack.pop_back();
6062 return true;
6063 }
6064
6065 bool start_array(std::size_t len)
6066 {
6067 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6068
6069 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6070 {
6071 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6072 }
6073
6074 return true;
6075 }
6076
6078 {
6079 ref_stack.back()->set_parents();
6080 ref_stack.pop_back();
6081 return true;
6082 }
6083
6084 template<class Exception>
6085 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6086 const Exception& ex)
6087 {
6088 errored = true;
6089 static_cast<void>(ex);
6090 if (allow_exceptions)
6091 {
6092 JSON_THROW(ex);
6093 }
6094 return false;
6095 }
6096
6097 constexpr bool is_errored() const
6098 {
6099 return errored;
6100 }
6101
6102 private:
6109 template<typename Value>
6111 BasicJsonType* handle_value(Value&& v)
6112 {
6113 if (ref_stack.empty())
6114 {
6115 root = BasicJsonType(std::forward<Value>(v));
6116 return &root;
6117 }
6118
6119 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6120
6121 if (ref_stack.back()->is_array())
6122 {
6123 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6124 return &(ref_stack.back()->m_value.array->back());
6125 }
6126
6127 JSON_ASSERT(ref_stack.back()->is_object());
6128 JSON_ASSERT(object_element);
6129 *object_element = BasicJsonType(std::forward<Value>(v));
6130 return object_element;
6131 }
6132
6134 BasicJsonType& root;
6136 std::vector<BasicJsonType*> ref_stack {};
6138 BasicJsonType* object_element = nullptr;
6140 bool errored = false;
6142 const bool allow_exceptions = true;
6143};
6144
6145template<typename BasicJsonType>
6147{
6148 public:
6149 using number_integer_t = typename BasicJsonType::number_integer_t;
6150 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6151 using number_float_t = typename BasicJsonType::number_float_t;
6152 using string_t = typename BasicJsonType::string_t;
6153 using binary_t = typename BasicJsonType::binary_t;
6154 using parser_callback_t = typename BasicJsonType::parser_callback_t;
6155 using parse_event_t = typename BasicJsonType::parse_event_t;
6156
6158 const parser_callback_t cb,
6159 const bool allow_exceptions_ = true)
6160 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6161 {
6162 keep_stack.push_back(true);
6163 }
6164
6165 // make class move-only
6167 json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6169 json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6171
6172 bool null()
6173 {
6174 handle_value(nullptr);
6175 return true;
6176 }
6177
6178 bool boolean(bool val)
6179 {
6180 handle_value(val);
6181 return true;
6182 }
6183
6185 {
6186 handle_value(val);
6187 return true;
6188 }
6189
6191 {
6192 handle_value(val);
6193 return true;
6194 }
6195
6196 bool number_float(number_float_t val, const string_t& /*unused*/)
6197 {
6198 handle_value(val);
6199 return true;
6200 }
6201
6202 bool string(string_t& val)
6203 {
6204 handle_value(val);
6205 return true;
6206 }
6207
6208 bool binary(binary_t& val)
6209 {
6210 handle_value(std::move(val));
6211 return true;
6212 }
6213
6214 bool start_object(std::size_t len)
6215 {
6216 // check callback for object start
6217 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6218 keep_stack.push_back(keep);
6219
6220 auto val = handle_value(BasicJsonType::value_t::object, true);
6221 ref_stack.push_back(val.second);
6222
6223 // check object limit
6224 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6225 {
6226 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6227 }
6228
6229 return true;
6230 }
6231
6232 bool key(string_t& val)
6233 {
6234 BasicJsonType k = BasicJsonType(val);
6235
6236 // check callback for key
6237 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6238 key_keep_stack.push_back(keep);
6239
6240 // add discarded value at given key and store the reference for later
6241 if (keep && ref_stack.back())
6242 {
6243 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6244 }
6245
6246 return true;
6247 }
6248
6250 {
6251 if (ref_stack.back())
6252 {
6253 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6254 {
6255 // discard object
6256 *ref_stack.back() = discarded;
6257 }
6258 else
6259 {
6260 ref_stack.back()->set_parents();
6261 }
6262 }
6263
6264 JSON_ASSERT(!ref_stack.empty());
6265 JSON_ASSERT(!keep_stack.empty());
6266 ref_stack.pop_back();
6267 keep_stack.pop_back();
6268
6269 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6270 {
6271 // remove discarded value
6272 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6273 {
6274 if (it->is_discarded())
6275 {
6276 ref_stack.back()->erase(it);
6277 break;
6278 }
6279 }
6280 }
6281
6282 return true;
6283 }
6284
6285 bool start_array(std::size_t len)
6286 {
6287 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6288 keep_stack.push_back(keep);
6289
6290 auto val = handle_value(BasicJsonType::value_t::array, true);
6291 ref_stack.push_back(val.second);
6292
6293 // check array limit
6294 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6295 {
6296 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6297 }
6298
6299 return true;
6300 }
6301
6303 {
6304 bool keep = true;
6305
6306 if (ref_stack.back())
6307 {
6308 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6309 if (keep)
6310 {
6311 ref_stack.back()->set_parents();
6312 }
6313 else
6314 {
6315 // discard array
6316 *ref_stack.back() = discarded;
6317 }
6318 }
6319
6320 JSON_ASSERT(!ref_stack.empty());
6321 JSON_ASSERT(!keep_stack.empty());
6322 ref_stack.pop_back();
6323 keep_stack.pop_back();
6324
6325 // remove discarded value
6326 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6327 {
6328 ref_stack.back()->m_value.array->pop_back();
6329 }
6330
6331 return true;
6332 }
6333
6334 template<class Exception>
6335 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6336 const Exception& ex)
6337 {
6338 errored = true;
6339 static_cast<void>(ex);
6340 if (allow_exceptions)
6341 {
6342 JSON_THROW(ex);
6343 }
6344 return false;
6345 }
6346
6347 constexpr bool is_errored() const
6348 {
6349 return errored;
6350 }
6351
6352 private:
6368 template<typename Value>
6369 std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6370 {
6371 JSON_ASSERT(!keep_stack.empty());
6372
6373 // do not handle this value if we know it would be added to a discarded
6374 // container
6375 if (!keep_stack.back())
6376 {
6377 return {false, nullptr};
6378 }
6379
6380 // create value
6381 auto value = BasicJsonType(std::forward<Value>(v));
6382
6383 // check callback
6384 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6385
6386 // do not handle this value if we just learnt it shall be discarded
6387 if (!keep)
6388 {
6389 return {false, nullptr};
6390 }
6391
6392 if (ref_stack.empty())
6393 {
6394 root = std::move(value);
6395 return {true, &root};
6396 }
6397
6398 // skip this value if we already decided to skip the parent
6399 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6400 if (!ref_stack.back())
6401 {
6402 return {false, nullptr};
6403 }
6404
6405 // we now only expect arrays and objects
6406 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6407
6408 // array
6409 if (ref_stack.back()->is_array())
6410 {
6411 ref_stack.back()->m_value.array->emplace_back(std::move(value));
6412 return {true, &(ref_stack.back()->m_value.array->back())};
6413 }
6414
6415 // object
6416 JSON_ASSERT(ref_stack.back()->is_object());
6417 // check if we should store an element for the current key
6418 JSON_ASSERT(!key_keep_stack.empty());
6419 const bool store_element = key_keep_stack.back();
6420 key_keep_stack.pop_back();
6421
6422 if (!store_element)
6423 {
6424 return {false, nullptr};
6425 }
6426
6427 JSON_ASSERT(object_element);
6428 *object_element = std::move(value);
6429 return {true, object_element};
6430 }
6431
6433 BasicJsonType& root;
6435 std::vector<BasicJsonType*> ref_stack {};
6437 std::vector<bool> keep_stack {};
6439 std::vector<bool> key_keep_stack {};
6441 BasicJsonType* object_element = nullptr;
6443 bool errored = false;
6445 const parser_callback_t callback = nullptr;
6447 const bool allow_exceptions = true;
6449 BasicJsonType discarded = BasicJsonType::value_t::discarded;
6450};
6451
6452template<typename BasicJsonType>
6454{
6455 public:
6456 using number_integer_t = typename BasicJsonType::number_integer_t;
6457 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6458 using number_float_t = typename BasicJsonType::number_float_t;
6459 using string_t = typename BasicJsonType::string_t;
6460 using binary_t = typename BasicJsonType::binary_t;
6461
6462 bool null()
6463 {
6464 return true;
6465 }
6466
6467 bool boolean(bool /*unused*/)
6468 {
6469 return true;
6470 }
6471
6473 {
6474 return true;
6475 }
6476
6478 {
6479 return true;
6480 }
6481
6482 bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6483 {
6484 return true;
6485 }
6486
6487 bool string(string_t& /*unused*/)
6488 {
6489 return true;
6490 }
6491
6492 bool binary(binary_t& /*unused*/)
6493 {
6494 return true;
6495 }
6496
6497 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
6498 {
6499 return true;
6500 }
6501
6502 bool key(string_t& /*unused*/)
6503 {
6504 return true;
6505 }
6506
6508 {
6509 return true;
6510 }
6511
6512 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
6513 {
6514 return true;
6515 }
6516
6518 {
6519 return true;
6520 }
6521
6522 bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6523 {
6524 return false;
6525 }
6526};
6527} // namespace detail
6528
6529} // namespace nlohmann
6530
6531// #include <nlohmann/detail/input/lexer.hpp>
6532
6533
6534#include <array> // array
6535#include <clocale> // localeconv
6536#include <cstddef> // size_t
6537#include <cstdio> // snprintf
6538#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6539#include <initializer_list> // initializer_list
6540#include <string> // char_traits, string
6541#include <utility> // move
6542#include <vector> // vector
6543
6544// #include <nlohmann/detail/input/input_adapters.hpp>
6545
6546// #include <nlohmann/detail/input/position_t.hpp>
6547
6548// #include <nlohmann/detail/macro_scope.hpp>
6549
6550
6551namespace nlohmann
6552{
6553namespace detail
6554{
6556// lexer //
6558
6559template<typename BasicJsonType>
6561{
6562 public:
6584
6588 static const char* token_type_name(const token_type t) noexcept
6589 {
6590 switch (t)
6591 {
6593 return "<uninitialized>";
6595 return "true literal";
6597 return "false literal";
6599 return "null literal";
6601 return "string literal";
6605 return "number literal";
6607 return "'['";
6609 return "'{'";
6611 return "']'";
6613 return "'}'";
6615 return "':'";
6617 return "','";
6619 return "<parse error>";
6621 return "end of input";
6623 return "'[', '{', or a literal";
6624 // LCOV_EXCL_START
6625 default: // catch non-enum values
6626 return "unknown token";
6627 // LCOV_EXCL_STOP
6628 }
6629 }
6630};
6636template<typename BasicJsonType, typename InputAdapterType>
6637class lexer : public lexer_base<BasicJsonType>
6638{
6639 using number_integer_t = typename BasicJsonType::number_integer_t;
6640 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6641 using number_float_t = typename BasicJsonType::number_float_t;
6642 using string_t = typename BasicJsonType::string_t;
6643 using char_type = typename InputAdapterType::char_type;
6644 using char_int_type = typename std::char_traits<char_type>::int_type;
6645
6646 public:
6648
6649 explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
6650 : ia(std::move(adapter))
6651 , ignore_comments(ignore_comments_)
6653 {}
6654
6655 // delete because of pointer members
6656 lexer(const lexer&) = delete;
6657 lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6658 lexer& operator=(lexer&) = delete;
6659 lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6660 ~lexer() = default;
6661
6662 private:
6664 // locales
6666
6669 static char get_decimal_point() noexcept
6670 {
6671 const auto* loc = localeconv();
6672 JSON_ASSERT(loc != nullptr);
6673 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6674 }
6675
6677 // scan functions
6679
6696 {
6697 // this function only makes sense after reading `\u`
6698 JSON_ASSERT(current == 'u');
6699 int codepoint = 0;
6700
6701 const auto factors = { 12u, 8u, 4u, 0u };
6702 for (const auto factor : factors)
6703 {
6704 get();
6705
6706 if (current >= '0' && current <= '9')
6707 {
6708 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6709 }
6710 else if (current >= 'A' && current <= 'F')
6711 {
6712 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6713 }
6714 else if (current >= 'a' && current <= 'f')
6715 {
6716 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6717 }
6718 else
6719 {
6720 return -1;
6721 }
6722 }
6723
6724 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6725 return codepoint;
6726 }
6727
6743 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6744 {
6745 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6746 add(current);
6747
6748 for (auto range = ranges.begin(); range != ranges.end(); ++range)
6749 {
6750 get();
6751 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6752 {
6753 add(current);
6754 }
6755 else
6756 {
6757 error_message = "invalid string: ill-formed UTF-8 byte";
6758 return false;
6759 }
6760 }
6761
6762 return true;
6763 }
6764
6781 {
6782 // reset token_buffer (ignore opening quote)
6783 reset();
6784
6785 // we entered the function by reading an open quote
6786 JSON_ASSERT(current == '\"');
6787
6788 while (true)
6789 {
6790 // get next character
6791 switch (get())
6792 {
6793 // end of file while parsing string
6794 case std::char_traits<char_type>::eof():
6795 {
6796 error_message = "invalid string: missing closing quote";
6797 return token_type::parse_error;
6798 }
6799
6800 // closing quote
6801 case '\"':
6802 {
6803 return token_type::value_string;
6804 }
6805
6806 // escapes
6807 case '\\':
6808 {
6809 switch (get())
6810 {
6811 // quotation mark
6812 case '\"':
6813 add('\"');
6814 break;
6815 // reverse solidus
6816 case '\\':
6817 add('\\');
6818 break;
6819 // solidus
6820 case '/':
6821 add('/');
6822 break;
6823 // backspace
6824 case 'b':
6825 add('\b');
6826 break;
6827 // form feed
6828 case 'f':
6829 add('\f');
6830 break;
6831 // line feed
6832 case 'n':
6833 add('\n');
6834 break;
6835 // carriage return
6836 case 'r':
6837 add('\r');
6838 break;
6839 // tab
6840 case 't':
6841 add('\t');
6842 break;
6843
6844 // unicode escapes
6845 case 'u':
6846 {
6847 const int codepoint1 = get_codepoint();
6848 int codepoint = codepoint1; // start with codepoint1
6849
6850 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6851 {
6852 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6853 return token_type::parse_error;
6854 }
6855
6856 // check if code point is a high surrogate
6857 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6858 {
6859 // expect next \uxxxx entry
6860 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6861 {
6862 const int codepoint2 = get_codepoint();
6863
6864 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6865 {
6866 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6867 return token_type::parse_error;
6868 }
6869
6870 // check if codepoint2 is a low surrogate
6871 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6872 {
6873 // overwrite codepoint
6874 codepoint = static_cast<int>(
6875 // high surrogate occupies the most significant 22 bits
6876 (static_cast<unsigned int>(codepoint1) << 10u)
6877 // low surrogate occupies the least significant 15 bits
6878 + static_cast<unsigned int>(codepoint2)
6879 // there is still the 0xD800, 0xDC00 and 0x10000 noise
6880 // in the result so we have to subtract with:
6881 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6882 - 0x35FDC00u);
6883 }
6884 else
6885 {
6886 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6887 return token_type::parse_error;
6888 }
6889 }
6890 else
6891 {
6892 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6893 return token_type::parse_error;
6894 }
6895 }
6896 else
6897 {
6898 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6899 {
6900 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6901 return token_type::parse_error;
6902 }
6903 }
6904
6905 // result of the above calculation yields a proper codepoint
6906 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6907
6908 // translate codepoint into bytes
6909 if (codepoint < 0x80)
6910 {
6911 // 1-byte characters: 0xxxxxxx (ASCII)
6912 add(static_cast<char_int_type>(codepoint));
6913 }
6914 else if (codepoint <= 0x7FF)
6915 {
6916 // 2-byte characters: 110xxxxx 10xxxxxx
6917 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6918 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6919 }
6920 else if (codepoint <= 0xFFFF)
6921 {
6922 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6923 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6924 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6925 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6926 }
6927 else
6928 {
6929 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
6930 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
6931 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
6932 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6933 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6934 }
6935
6936 break;
6937 }
6938
6939 // other characters after escape
6940 default:
6941 error_message = "invalid string: forbidden character after backslash";
6942 return token_type::parse_error;
6943 }
6944
6945 break;
6946 }
6947
6948 // invalid control characters
6949 case 0x00:
6950 {
6951 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
6952 return token_type::parse_error;
6953 }
6954
6955 case 0x01:
6956 {
6957 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
6958 return token_type::parse_error;
6959 }
6960
6961 case 0x02:
6962 {
6963 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
6964 return token_type::parse_error;
6965 }
6966
6967 case 0x03:
6968 {
6969 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
6970 return token_type::parse_error;
6971 }
6972
6973 case 0x04:
6974 {
6975 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
6976 return token_type::parse_error;
6977 }
6978
6979 case 0x05:
6980 {
6981 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
6982 return token_type::parse_error;
6983 }
6984
6985 case 0x06:
6986 {
6987 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
6988 return token_type::parse_error;
6989 }
6990
6991 case 0x07:
6992 {
6993 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
6994 return token_type::parse_error;
6995 }
6996
6997 case 0x08:
6998 {
6999 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7000 return token_type::parse_error;
7001 }
7002
7003 case 0x09:
7004 {
7005 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7006 return token_type::parse_error;
7007 }
7008
7009 case 0x0A:
7010 {
7011 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7012 return token_type::parse_error;
7013 }
7014
7015 case 0x0B:
7016 {
7017 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7018 return token_type::parse_error;
7019 }
7020
7021 case 0x0C:
7022 {
7023 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7024 return token_type::parse_error;
7025 }
7026
7027 case 0x0D:
7028 {
7029 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7030 return token_type::parse_error;
7031 }
7032
7033 case 0x0E:
7034 {
7035 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7036 return token_type::parse_error;
7037 }
7038
7039 case 0x0F:
7040 {
7041 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7042 return token_type::parse_error;
7043 }
7044
7045 case 0x10:
7046 {
7047 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7048 return token_type::parse_error;
7049 }
7050
7051 case 0x11:
7052 {
7053 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7054 return token_type::parse_error;
7055 }
7056
7057 case 0x12:
7058 {
7059 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7060 return token_type::parse_error;
7061 }
7062
7063 case 0x13:
7064 {
7065 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7066 return token_type::parse_error;
7067 }
7068
7069 case 0x14:
7070 {
7071 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7072 return token_type::parse_error;
7073 }
7074
7075 case 0x15:
7076 {
7077 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7078 return token_type::parse_error;
7079 }
7080
7081 case 0x16:
7082 {
7083 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7084 return token_type::parse_error;
7085 }
7086
7087 case 0x17:
7088 {
7089 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7090 return token_type::parse_error;
7091 }
7092
7093 case 0x18:
7094 {
7095 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7096 return token_type::parse_error;
7097 }
7098
7099 case 0x19:
7100 {
7101 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7102 return token_type::parse_error;
7103 }
7104
7105 case 0x1A:
7106 {
7107 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7108 return token_type::parse_error;
7109 }
7110
7111 case 0x1B:
7112 {
7113 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7114 return token_type::parse_error;
7115 }
7116
7117 case 0x1C:
7118 {
7119 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7120 return token_type::parse_error;
7121 }
7122
7123 case 0x1D:
7124 {
7125 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7126 return token_type::parse_error;
7127 }
7128
7129 case 0x1E:
7130 {
7131 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7132 return token_type::parse_error;
7133 }
7134
7135 case 0x1F:
7136 {
7137 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7138 return token_type::parse_error;
7139 }
7140
7141 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7142 case 0x20:
7143 case 0x21:
7144 case 0x23:
7145 case 0x24:
7146 case 0x25:
7147 case 0x26:
7148 case 0x27:
7149 case 0x28:
7150 case 0x29:
7151 case 0x2A:
7152 case 0x2B:
7153 case 0x2C:
7154 case 0x2D:
7155 case 0x2E:
7156 case 0x2F:
7157 case 0x30:
7158 case 0x31:
7159 case 0x32:
7160 case 0x33:
7161 case 0x34:
7162 case 0x35:
7163 case 0x36:
7164 case 0x37:
7165 case 0x38:
7166 case 0x39:
7167 case 0x3A:
7168 case 0x3B:
7169 case 0x3C:
7170 case 0x3D:
7171 case 0x3E:
7172 case 0x3F:
7173 case 0x40:
7174 case 0x41:
7175 case 0x42:
7176 case 0x43:
7177 case 0x44:
7178 case 0x45:
7179 case 0x46:
7180 case 0x47:
7181 case 0x48:
7182 case 0x49:
7183 case 0x4A:
7184 case 0x4B:
7185 case 0x4C:
7186 case 0x4D:
7187 case 0x4E:
7188 case 0x4F:
7189 case 0x50:
7190 case 0x51:
7191 case 0x52:
7192 case 0x53:
7193 case 0x54:
7194 case 0x55:
7195 case 0x56:
7196 case 0x57:
7197 case 0x58:
7198 case 0x59:
7199 case 0x5A:
7200 case 0x5B:
7201 case 0x5D:
7202 case 0x5E:
7203 case 0x5F:
7204 case 0x60:
7205 case 0x61:
7206 case 0x62:
7207 case 0x63:
7208 case 0x64:
7209 case 0x65:
7210 case 0x66:
7211 case 0x67:
7212 case 0x68:
7213 case 0x69:
7214 case 0x6A:
7215 case 0x6B:
7216 case 0x6C:
7217 case 0x6D:
7218 case 0x6E:
7219 case 0x6F:
7220 case 0x70:
7221 case 0x71:
7222 case 0x72:
7223 case 0x73:
7224 case 0x74:
7225 case 0x75:
7226 case 0x76:
7227 case 0x77:
7228 case 0x78:
7229 case 0x79:
7230 case 0x7A:
7231 case 0x7B:
7232 case 0x7C:
7233 case 0x7D:
7234 case 0x7E:
7235 case 0x7F:
7236 {
7237 add(current);
7238 break;
7239 }
7240
7241 // U+0080..U+07FF: bytes C2..DF 80..BF
7242 case 0xC2:
7243 case 0xC3:
7244 case 0xC4:
7245 case 0xC5:
7246 case 0xC6:
7247 case 0xC7:
7248 case 0xC8:
7249 case 0xC9:
7250 case 0xCA:
7251 case 0xCB:
7252 case 0xCC:
7253 case 0xCD:
7254 case 0xCE:
7255 case 0xCF:
7256 case 0xD0:
7257 case 0xD1:
7258 case 0xD2:
7259 case 0xD3:
7260 case 0xD4:
7261 case 0xD5:
7262 case 0xD6:
7263 case 0xD7:
7264 case 0xD8:
7265 case 0xD9:
7266 case 0xDA:
7267 case 0xDB:
7268 case 0xDC:
7269 case 0xDD:
7270 case 0xDE:
7271 case 0xDF:
7272 {
7273 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7274 {
7275 return token_type::parse_error;
7276 }
7277 break;
7278 }
7279
7280 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7281 case 0xE0:
7282 {
7283 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7284 {
7285 return token_type::parse_error;
7286 }
7287 break;
7288 }
7289
7290 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7291 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7292 case 0xE1:
7293 case 0xE2:
7294 case 0xE3:
7295 case 0xE4:
7296 case 0xE5:
7297 case 0xE6:
7298 case 0xE7:
7299 case 0xE8:
7300 case 0xE9:
7301 case 0xEA:
7302 case 0xEB:
7303 case 0xEC:
7304 case 0xEE:
7305 case 0xEF:
7306 {
7307 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7308 {
7309 return token_type::parse_error;
7310 }
7311 break;
7312 }
7313
7314 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7315 case 0xED:
7316 {
7317 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7318 {
7319 return token_type::parse_error;
7320 }
7321 break;
7322 }
7323
7324 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7325 case 0xF0:
7326 {
7327 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7328 {
7329 return token_type::parse_error;
7330 }
7331 break;
7332 }
7333
7334 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7335 case 0xF1:
7336 case 0xF2:
7337 case 0xF3:
7338 {
7339 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7340 {
7341 return token_type::parse_error;
7342 }
7343 break;
7344 }
7345
7346 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7347 case 0xF4:
7348 {
7349 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7350 {
7351 return token_type::parse_error;
7352 }
7353 break;
7354 }
7355
7356 // remaining bytes (80..C1 and F5..FF) are ill-formed
7357 default:
7358 {
7359 error_message = "invalid string: ill-formed UTF-8 byte";
7360 return token_type::parse_error;
7361 }
7362 }
7363 }
7364 }
7365
7371 {
7372 switch (get())
7373 {
7374 // single-line comments skip input until a newline or EOF is read
7375 case '/':
7376 {
7377 while (true)
7378 {
7379 switch (get())
7380 {
7381 case '\n':
7382 case '\r':
7383 case std::char_traits<char_type>::eof():
7384 case '\0':
7385 return true;
7386
7387 default:
7388 break;
7389 }
7390 }
7391 }
7392
7393 // multi-line comments skip input until */ is read
7394 case '*':
7395 {
7396 while (true)
7397 {
7398 switch (get())
7399 {
7400 case std::char_traits<char_type>::eof():
7401 case '\0':
7402 {
7403 error_message = "invalid comment; missing closing '*/'";
7404 return false;
7405 }
7406
7407 case '*':
7408 {
7409 switch (get())
7410 {
7411 case '/':
7412 return true;
7413
7414 default:
7415 {
7416 unget();
7417 continue;
7418 }
7419 }
7420 }
7421
7422 default:
7423 continue;
7424 }
7425 }
7426 }
7427
7428 // unexpected character after reading '/'
7429 default:
7430 {
7431 error_message = "invalid comment; expecting '/' or '*' after '/'";
7432 return false;
7433 }
7434 }
7435 }
7436
7438 static void strtof(float& f, const char* str, char** endptr) noexcept
7439 {
7440 f = std::strtof(str, endptr);
7441 }
7442
7444 static void strtof(double& f, const char* str, char** endptr) noexcept
7445 {
7446 f = std::strtod(str, endptr);
7447 }
7448
7450 static void strtof(long double& f, const char* str, char** endptr) noexcept
7451 {
7452 f = std::strtold(str, endptr);
7453 }
7454
7495 token_type scan_number() // lgtm [cpp/use-of-goto]
7496 {
7497 // reset token_buffer to store the number's bytes
7498 reset();
7499
7500 // the type of the parsed number; initially set to unsigned; will be
7501 // changed if minus sign, decimal point or exponent is read
7502 token_type number_type = token_type::value_unsigned;
7503
7504 // state (init): we just found out we need to scan a number
7505 switch (current)
7506 {
7507 case '-':
7508 {
7509 add(current);
7510 goto scan_number_minus;
7511 }
7512
7513 case '0':
7514 {
7515 add(current);
7516 goto scan_number_zero;
7517 }
7518
7519 case '1':
7520 case '2':
7521 case '3':
7522 case '4':
7523 case '5':
7524 case '6':
7525 case '7':
7526 case '8':
7527 case '9':
7528 {
7529 add(current);
7530 goto scan_number_any1;
7531 }
7532
7533 // all other characters are rejected outside scan_number()
7534 default: // LCOV_EXCL_LINE
7535 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7536 }
7537
7538scan_number_minus:
7539 // state: we just parsed a leading minus sign
7540 number_type = token_type::value_integer;
7541 switch (get())
7542 {
7543 case '0':
7544 {
7545 add(current);
7546 goto scan_number_zero;
7547 }
7548
7549 case '1':
7550 case '2':
7551 case '3':
7552 case '4':
7553 case '5':
7554 case '6':
7555 case '7':
7556 case '8':
7557 case '9':
7558 {
7559 add(current);
7560 goto scan_number_any1;
7561 }
7562
7563 default:
7564 {
7565 error_message = "invalid number; expected digit after '-'";
7566 return token_type::parse_error;
7567 }
7568 }
7569
7570scan_number_zero:
7571 // state: we just parse a zero (maybe with a leading minus sign)
7572 switch (get())
7573 {
7574 case '.':
7575 {
7577 goto scan_number_decimal1;
7578 }
7579
7580 case 'e':
7581 case 'E':
7582 {
7583 add(current);
7584 goto scan_number_exponent;
7585 }
7586
7587 default:
7588 goto scan_number_done;
7589 }
7590
7591scan_number_any1:
7592 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7593 switch (get())
7594 {
7595 case '0':
7596 case '1':
7597 case '2':
7598 case '3':
7599 case '4':
7600 case '5':
7601 case '6':
7602 case '7':
7603 case '8':
7604 case '9':
7605 {
7606 add(current);
7607 goto scan_number_any1;
7608 }
7609
7610 case '.':
7611 {
7613 goto scan_number_decimal1;
7614 }
7615
7616 case 'e':
7617 case 'E':
7618 {
7619 add(current);
7620 goto scan_number_exponent;
7621 }
7622
7623 default:
7624 goto scan_number_done;
7625 }
7626
7627scan_number_decimal1:
7628 // state: we just parsed a decimal point
7629 number_type = token_type::value_float;
7630 switch (get())
7631 {
7632 case '0':
7633 case '1':
7634 case '2':
7635 case '3':
7636 case '4':
7637 case '5':
7638 case '6':
7639 case '7':
7640 case '8':
7641 case '9':
7642 {
7643 add(current);
7644 goto scan_number_decimal2;
7645 }
7646
7647 default:
7648 {
7649 error_message = "invalid number; expected digit after '.'";
7650 return token_type::parse_error;
7651 }
7652 }
7653
7654scan_number_decimal2:
7655 // we just parsed at least one number after a decimal point
7656 switch (get())
7657 {
7658 case '0':
7659 case '1':
7660 case '2':
7661 case '3':
7662 case '4':
7663 case '5':
7664 case '6':
7665 case '7':
7666 case '8':
7667 case '9':
7668 {
7669 add(current);
7670 goto scan_number_decimal2;
7671 }
7672
7673 case 'e':
7674 case 'E':
7675 {
7676 add(current);
7677 goto scan_number_exponent;
7678 }
7679
7680 default:
7681 goto scan_number_done;
7682 }
7683
7684scan_number_exponent:
7685 // we just parsed an exponent
7686 number_type = token_type::value_float;
7687 switch (get())
7688 {
7689 case '+':
7690 case '-':
7691 {
7692 add(current);
7693 goto scan_number_sign;
7694 }
7695
7696 case '0':
7697 case '1':
7698 case '2':
7699 case '3':
7700 case '4':
7701 case '5':
7702 case '6':
7703 case '7':
7704 case '8':
7705 case '9':
7706 {
7707 add(current);
7708 goto scan_number_any2;
7709 }
7710
7711 default:
7712 {
7714 "invalid number; expected '+', '-', or digit after exponent";
7715 return token_type::parse_error;
7716 }
7717 }
7718
7719scan_number_sign:
7720 // we just parsed an exponent sign
7721 switch (get())
7722 {
7723 case '0':
7724 case '1':
7725 case '2':
7726 case '3':
7727 case '4':
7728 case '5':
7729 case '6':
7730 case '7':
7731 case '8':
7732 case '9':
7733 {
7734 add(current);
7735 goto scan_number_any2;
7736 }
7737
7738 default:
7739 {
7740 error_message = "invalid number; expected digit after exponent sign";
7741 return token_type::parse_error;
7742 }
7743 }
7744
7745scan_number_any2:
7746 // we just parsed a number after the exponent or exponent sign
7747 switch (get())
7748 {
7749 case '0':
7750 case '1':
7751 case '2':
7752 case '3':
7753 case '4':
7754 case '5':
7755 case '6':
7756 case '7':
7757 case '8':
7758 case '9':
7759 {
7760 add(current);
7761 goto scan_number_any2;
7762 }
7763
7764 default:
7765 goto scan_number_done;
7766 }
7767
7768scan_number_done:
7769 // unget the character after the number (we only read it to know that
7770 // we are done scanning a number)
7771 unget();
7772
7773 char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7774 errno = 0;
7775
7776 // try to parse integers first and fall back to floats
7777 if (number_type == token_type::value_unsigned)
7778 {
7779 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7780
7781 // we checked the number format before
7782 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7783
7784 if (errno == 0)
7785 {
7786 value_unsigned = static_cast<number_unsigned_t>(x);
7787 if (value_unsigned == x)
7788 {
7789 return token_type::value_unsigned;
7790 }
7791 }
7792 }
7793 else if (number_type == token_type::value_integer)
7794 {
7795 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7796
7797 // we checked the number format before
7798 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7799
7800 if (errno == 0)
7801 {
7802 value_integer = static_cast<number_integer_t>(x);
7803 if (value_integer == x)
7804 {
7805 return token_type::value_integer;
7806 }
7807 }
7808 }
7809
7810 // this code is reached if we parse a floating-point number or if an
7811 // integer conversion above failed
7812 strtof(value_float, token_buffer.data(), &endptr);
7813
7814 // we checked the number format before
7815 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7816
7817 return token_type::value_float;
7818 }
7819
7826 token_type scan_literal(const char_type* literal_text, const std::size_t length,
7827 token_type return_type)
7828 {
7829 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7830 for (std::size_t i = 1; i < length; ++i)
7831 {
7832 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7833 {
7834 error_message = "invalid literal";
7835 return token_type::parse_error;
7836 }
7837 }
7838 return return_type;
7839 }
7840
7842 // input management
7844
7846 void reset() noexcept
7847 {
7848 token_buffer.clear();
7849 token_string.clear();
7850 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7851 }
7852
7853 /*
7854 @brief get next character from the input
7855
7856 This function provides the interface to the used input adapter. It does
7857 not throw in case the input reached EOF, but returns a
7858 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7859 for use in error messages.
7860
7861 @return character read from the input
7862 */
7864 {
7867
7868 if (next_unget)
7869 {
7870 // just reset the next_unget variable and work with current
7871 next_unget = false;
7872 }
7873 else
7874 {
7875 current = ia.get_character();
7876 }
7877
7878 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7879 {
7880 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7881 }
7882
7883 if (current == '\n')
7884 {
7887 }
7888
7889 return current;
7890 }
7891
7900 void unget()
7901 {
7902 next_unget = true;
7903
7905
7906 // in case we "unget" a newline, we have to also decrement the lines_read
7908 {
7909 if (position.lines_read > 0)
7910 {
7912 }
7913 }
7914 else
7915 {
7917 }
7918
7919 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7920 {
7921 JSON_ASSERT(!token_string.empty());
7922 token_string.pop_back();
7923 }
7924 }
7925
7928 {
7929 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
7930 }
7931
7932 public:
7934 // value getters
7936
7938 constexpr number_integer_t get_number_integer() const noexcept
7939 {
7940 return value_integer;
7941 }
7942
7944 constexpr number_unsigned_t get_number_unsigned() const noexcept
7945 {
7946 return value_unsigned;
7947 }
7948
7950 constexpr number_float_t get_number_float() const noexcept
7951 {
7952 return value_float;
7953 }
7954
7957 {
7958 return token_buffer;
7959 }
7960
7962 // diagnostics
7964
7966 constexpr position_t get_position() const noexcept
7967 {
7968 return position;
7969 }
7970
7974 std::string get_token_string() const
7975 {
7976 // escape control characters
7977 std::string result;
7978 for (const auto c : token_string)
7979 {
7980 if (static_cast<unsigned char>(c) <= '\x1F')
7981 {
7982 // escape control characters
7983 std::array<char, 9> cs{{}};
7984 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7985 result += cs.data();
7986 }
7987 else
7988 {
7989 // add character as is
7990 result.push_back(static_cast<std::string::value_type>(c));
7991 }
7992 }
7993
7994 return result;
7995 }
7996
7999 constexpr const char* get_error_message() const noexcept
8000 {
8001 return error_message;
8002 }
8003
8005 // actual scanner
8007
8013 {
8014 if (get() == 0xEF)
8015 {
8016 // check if we completely parse the BOM
8017 return get() == 0xBB && get() == 0xBF;
8018 }
8019
8020 // the first character is not the beginning of the BOM; unget it to
8021 // process is later
8022 unget();
8023 return true;
8024 }
8025
8027 {
8028 do
8029 {
8030 get();
8031 }
8032 while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8033 }
8034
8036 {
8037 // initially, skip the BOM
8038 if (position.chars_read_total == 0 && !skip_bom())
8039 {
8040 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8041 return token_type::parse_error;
8042 }
8043
8044 // read next character and ignore whitespace
8046
8047 // ignore comments
8048 while (ignore_comments && current == '/')
8049 {
8050 if (!scan_comment())
8051 {
8052 return token_type::parse_error;
8053 }
8054
8055 // skip following whitespace
8057 }
8058
8059 switch (current)
8060 {
8061 // structural characters
8062 case '[':
8063 return token_type::begin_array;
8064 case ']':
8065 return token_type::end_array;
8066 case '{':
8067 return token_type::begin_object;
8068 case '}':
8069 return token_type::end_object;
8070 case ':':
8071 return token_type::name_separator;
8072 case ',':
8073 return token_type::value_separator;
8074
8075 // literals
8076 case 't':
8077 {
8078 std::array<char_type, 4> true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}};
8079 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8080 }
8081 case 'f':
8082 {
8083 std::array<char_type, 5> false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}};
8084 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8085 }
8086 case 'n':
8087 {
8088 std::array<char_type, 4> null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}};
8089 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8090 }
8091
8092 // string
8093 case '\"':
8094 return scan_string();
8095
8096 // number
8097 case '-':
8098 case '0':
8099 case '1':
8100 case '2':
8101 case '3':
8102 case '4':
8103 case '5':
8104 case '6':
8105 case '7':
8106 case '8':
8107 case '9':
8108 return scan_number();
8109
8110 // end of input (the null byte is needed when parsing from
8111 // string literals)
8112 case '\0':
8113 case std::char_traits<char_type>::eof():
8114 return token_type::end_of_input;
8115
8116 // error
8117 default:
8118 error_message = "invalid literal";
8119 return token_type::parse_error;
8120 }
8121 }
8122
8123 private:
8125 InputAdapterType ia;
8126
8128 const bool ignore_comments = false;
8129
8131 char_int_type current = std::char_traits<char_type>::eof();
8132
8134 bool next_unget = false;
8135
8138
8140 std::vector<char_type> token_string {};
8141
8144
8146 const char* error_message = "";
8147
8148 // number values
8152
8155};
8156} // namespace detail
8157} // namespace nlohmann
8158
8159// #include <nlohmann/detail/macro_scope.hpp>
8160
8161// #include <nlohmann/detail/meta/is_sax.hpp>
8162
8163
8164#include <cstdint> // size_t
8165#include <utility> // declval
8166#include <string> // string
8167
8168// #include <nlohmann/detail/meta/detected.hpp>
8169
8170// #include <nlohmann/detail/meta/type_traits.hpp>
8171
8172
8173namespace nlohmann
8174{
8175namespace detail
8176{
8177template<typename T>
8178using null_function_t = decltype(std::declval<T&>().null());
8179
8180template<typename T>
8182 decltype(std::declval<T&>().boolean(std::declval<bool>()));
8183
8184template<typename T, typename Integer>
8186 decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8187
8188template<typename T, typename Unsigned>
8190 decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8191
8192template<typename T, typename Float, typename String>
8193using number_float_function_t = decltype(std::declval<T&>().number_float(
8194 std::declval<Float>(), std::declval<const String&>()));
8195
8196template<typename T, typename String>
8198 decltype(std::declval<T&>().string(std::declval<String&>()));
8199
8200template<typename T, typename Binary>
8202 decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8203
8204template<typename T>
8206 decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8207
8208template<typename T, typename String>
8210 decltype(std::declval<T&>().key(std::declval<String&>()));
8211
8212template<typename T>
8213using end_object_function_t = decltype(std::declval<T&>().end_object());
8214
8215template<typename T>
8217 decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8218
8219template<typename T>
8220using end_array_function_t = decltype(std::declval<T&>().end_array());
8221
8222template<typename T, typename Exception>
8223using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8224 std::declval<std::size_t>(), std::declval<const std::string&>(),
8225 std::declval<const Exception&>()));
8226
8227template<typename SAX, typename BasicJsonType>
8229{
8230 private:
8232 "BasicJsonType must be of type basic_json<...>");
8233
8234 using number_integer_t = typename BasicJsonType::number_integer_t;
8235 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8236 using number_float_t = typename BasicJsonType::number_float_t;
8237 using string_t = typename BasicJsonType::string_t;
8238 using binary_t = typename BasicJsonType::binary_t;
8239 using exception_t = typename BasicJsonType::exception;
8240
8241 public:
8242 static constexpr bool value =
8256};
8257
8258template<typename SAX, typename BasicJsonType>
8260{
8261 private:
8263 "BasicJsonType must be of type basic_json<...>");
8264
8265 using number_integer_t = typename BasicJsonType::number_integer_t;
8266 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8267 using number_float_t = typename BasicJsonType::number_float_t;
8268 using string_t = typename BasicJsonType::string_t;
8269 using binary_t = typename BasicJsonType::binary_t;
8270 using exception_t = typename BasicJsonType::exception;
8271
8272 public:
8274 "Missing/invalid function: bool null()");
8276 "Missing/invalid function: bool boolean(bool)");
8278 "Missing/invalid function: bool boolean(bool)");
8279 static_assert(
8282 "Missing/invalid function: bool number_integer(number_integer_t)");
8283 static_assert(
8286 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8287 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8289 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8290 static_assert(
8292 "Missing/invalid function: bool string(string_t&)");
8293 static_assert(
8295 "Missing/invalid function: bool binary(binary_t&)");
8297 "Missing/invalid function: bool start_object(std::size_t)");
8299 "Missing/invalid function: bool key(string_t&)");
8301 "Missing/invalid function: bool end_object()");
8303 "Missing/invalid function: bool start_array(std::size_t)");
8305 "Missing/invalid function: bool end_array()");
8306 static_assert(
8308 "Missing/invalid function: bool parse_error(std::size_t, const "
8309 "std::string&, const exception&)");
8310};
8311} // namespace detail
8312} // namespace nlohmann
8313
8314// #include <nlohmann/detail/meta/type_traits.hpp>
8315
8316// #include <nlohmann/detail/value_t.hpp>
8317
8318
8319namespace nlohmann
8320{
8321namespace detail
8322{
8323
8326{
8327 error,
8328 ignore,
8329 store
8330};
8331
8339static inline bool little_endianess(int num = 1) noexcept
8340{
8341 return *reinterpret_cast<char*>(&num) == 1;
8342}
8343
8344
8346// binary reader //
8348
8352template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8354{
8355 using number_integer_t = typename BasicJsonType::number_integer_t;
8356 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8357 using number_float_t = typename BasicJsonType::number_float_t;
8358 using string_t = typename BasicJsonType::string_t;
8359 using binary_t = typename BasicJsonType::binary_t;
8360 using json_sax_t = SAX;
8361 using char_type = typename InputAdapterType::char_type;
8362 using char_int_type = typename std::char_traits<char_type>::int_type;
8363
8364 public:
8370 explicit binary_reader(InputAdapterType&& adapter) noexcept : ia(std::move(adapter))
8371 {
8373 }
8374
8375 // make class move-only
8377 binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8379 binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8380 ~binary_reader() = default;
8381
8391 bool sax_parse(const input_format_t format,
8392 json_sax_t* sax_,
8393 const bool strict = true,
8394 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8395 {
8396 sax = sax_;
8397 bool result = false;
8398
8399 switch (format)
8400 {
8402 result = parse_bson_internal();
8403 break;
8404
8406 result = parse_cbor_internal(true, tag_handler);
8407 break;
8408
8410 result = parse_msgpack_internal();
8411 break;
8412
8414 result = parse_ubjson_internal();
8415 break;
8416
8417 case input_format_t::json: // LCOV_EXCL_LINE
8418 default: // LCOV_EXCL_LINE
8419 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8420 }
8421
8422 // strict mode: next byte must be EOF
8423 if (result && strict)
8424 {
8425 if (format == input_format_t::ubjson)
8426 {
8428 }
8429 else
8430 {
8431 get();
8432 }
8433
8434 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8435 {
8436 return sax->parse_error(chars_read, get_token_string(),
8437 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
8438 }
8439 }
8440
8441 return result;
8442 }
8443
8444 private:
8446 // BSON //
8448
8454 {
8455 std::int32_t document_size{};
8456 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8457
8458 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
8459 {
8460 return false;
8461 }
8462
8463 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8464 {
8465 return false;
8466 }
8467
8468 return sax->end_object();
8469 }
8470
8479 {
8480 auto out = std::back_inserter(result);
8481 while (true)
8482 {
8483 get();
8485 {
8486 return false;
8487 }
8488 if (current == 0x00)
8489 {
8490 return true;
8491 }
8492 *out++ = static_cast<typename string_t::value_type>(current);
8493 }
8494 }
8495
8507 template<typename NumberType>
8508 bool get_bson_string(const NumberType len, string_t& result)
8509 {
8510 if (JSON_HEDLEY_UNLIKELY(len < 1))
8511 {
8512 auto last_token = get_token_string();
8513 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "string length must be at least 1, is " + std::to_string(len), "string"), BasicJsonType()));
8514 }
8515
8516 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8517 }
8518
8528 template<typename NumberType>
8529 bool get_bson_binary(const NumberType len, binary_t& result)
8530 {
8531 if (JSON_HEDLEY_UNLIKELY(len < 0))
8532 {
8533 auto last_token = get_token_string();
8534 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::bson, "byte array length cannot be negative, is " + std::to_string(len), "binary"), BasicJsonType()));
8535 }
8536
8537 // All BSON binary values have a subtype
8538 std::uint8_t subtype{};
8539 get_number<std::uint8_t>(input_format_t::bson, subtype);
8540 result.set_subtype(subtype);
8541
8542 return get_binary(input_format_t::bson, len, result);
8543 }
8544
8556 const std::size_t element_type_parse_position)
8557 {
8558 switch (element_type)
8559 {
8560 case 0x01: // double
8561 {
8562 double number{};
8563 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8564 }
8565
8566 case 0x02: // string
8567 {
8568 std::int32_t len{};
8570 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8571 }
8572
8573 case 0x03: // object
8574 {
8575 return parse_bson_internal();
8576 }
8577
8578 case 0x04: // array
8579 {
8580 return parse_bson_array();
8581 }
8582
8583 case 0x05: // binary
8584 {
8585 std::int32_t len{};
8587 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8588 }
8589
8590 case 0x08: // boolean
8591 {
8592 return sax->boolean(get() != 0);
8593 }
8594
8595 case 0x0A: // null
8596 {
8597 return sax->null();
8598 }
8599
8600 case 0x10: // int32
8601 {
8602 std::int32_t value{};
8603 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8604 }
8605
8606 case 0x12: // int64
8607 {
8608 std::int64_t value{};
8609 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8610 }
8611
8612 default: // anything else not supported (yet)
8613 {
8614 std::array<char, 3> cr{{}};
8615 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8616 return sax->parse_error(element_type_parse_position, std::string(cr.data()), parse_error::create(114, element_type_parse_position, "Unsupported BSON record type 0x" + std::string(cr.data()), BasicJsonType()));
8617 }
8618 }
8619 }
8620
8633 bool parse_bson_element_list(const bool is_array)
8634 {
8635 string_t key;
8636
8637 while (auto element_type = get())
8638 {
8640 {
8641 return false;
8642 }
8643
8644 const std::size_t element_type_parse_position = chars_read;
8646 {
8647 return false;
8648 }
8649
8650 if (!is_array && !sax->key(key))
8651 {
8652 return false;
8653 }
8654
8655 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8656 {
8657 return false;
8658 }
8659
8660 // get_bson_cstr only appends
8661 key.clear();
8662 }
8663
8664 return true;
8665 }
8666
8672 {
8673 std::int32_t document_size{};
8674 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8675
8676 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8677 {
8678 return false;
8679 }
8680
8681 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8682 {
8683 return false;
8684 }
8685
8686 return sax->end_array();
8687 }
8688
8690 // CBOR //
8692
8701 bool parse_cbor_internal(const bool get_char,
8702 const cbor_tag_handler_t tag_handler)
8703 {
8704 switch (get_char ? get() : current)
8705 {
8706 // EOF
8707 case std::char_traits<char_type>::eof():
8708 return unexpect_eof(input_format_t::cbor, "value");
8709
8710 // Integer 0x00..0x17 (0..23)
8711 case 0x00:
8712 case 0x01:
8713 case 0x02:
8714 case 0x03:
8715 case 0x04:
8716 case 0x05:
8717 case 0x06:
8718 case 0x07:
8719 case 0x08:
8720 case 0x09:
8721 case 0x0A:
8722 case 0x0B:
8723 case 0x0C:
8724 case 0x0D:
8725 case 0x0E:
8726 case 0x0F:
8727 case 0x10:
8728 case 0x11:
8729 case 0x12:
8730 case 0x13:
8731 case 0x14:
8732 case 0x15:
8733 case 0x16:
8734 case 0x17:
8735 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8736
8737 case 0x18: // Unsigned integer (one-byte uint8_t follows)
8738 {
8739 std::uint8_t number{};
8740 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8741 }
8742
8743 case 0x19: // Unsigned integer (two-byte uint16_t follows)
8744 {
8745 std::uint16_t number{};
8746 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8747 }
8748
8749 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8750 {
8751 std::uint32_t number{};
8752 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8753 }
8754
8755 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8756 {
8757 std::uint64_t number{};
8758 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8759 }
8760
8761 // Negative integer -1-0x00..-1-0x17 (-1..-24)
8762 case 0x20:
8763 case 0x21:
8764 case 0x22:
8765 case 0x23:
8766 case 0x24:
8767 case 0x25:
8768 case 0x26:
8769 case 0x27:
8770 case 0x28:
8771 case 0x29:
8772 case 0x2A:
8773 case 0x2B:
8774 case 0x2C:
8775 case 0x2D:
8776 case 0x2E:
8777 case 0x2F:
8778 case 0x30:
8779 case 0x31:
8780 case 0x32:
8781 case 0x33:
8782 case 0x34:
8783 case 0x35:
8784 case 0x36:
8785 case 0x37:
8786 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8787
8788 case 0x38: // Negative integer (one-byte uint8_t follows)
8789 {
8790 std::uint8_t number{};
8791 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8792 }
8793
8794 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8795 {
8796 std::uint16_t number{};
8797 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8798 }
8799
8800 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8801 {
8802 std::uint32_t number{};
8803 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8804 }
8805
8806 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8807 {
8808 std::uint64_t number{};
8809 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8810 - static_cast<number_integer_t>(number));
8811 }
8812
8813 // Binary data (0x00..0x17 bytes follow)
8814 case 0x40:
8815 case 0x41:
8816 case 0x42:
8817 case 0x43:
8818 case 0x44:
8819 case 0x45:
8820 case 0x46:
8821 case 0x47:
8822 case 0x48:
8823 case 0x49:
8824 case 0x4A:
8825 case 0x4B:
8826 case 0x4C:
8827 case 0x4D:
8828 case 0x4E:
8829 case 0x4F:
8830 case 0x50:
8831 case 0x51:
8832 case 0x52:
8833 case 0x53:
8834 case 0x54:
8835 case 0x55:
8836 case 0x56:
8837 case 0x57:
8838 case 0x58: // Binary data (one-byte uint8_t for n follows)
8839 case 0x59: // Binary data (two-byte uint16_t for n follow)
8840 case 0x5A: // Binary data (four-byte uint32_t for n follow)
8841 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8842 case 0x5F: // Binary data (indefinite length)
8843 {
8844 binary_t b;
8845 return get_cbor_binary(b) && sax->binary(b);
8846 }
8847
8848 // UTF-8 string (0x00..0x17 bytes follow)
8849 case 0x60:
8850 case 0x61:
8851 case 0x62:
8852 case 0x63:
8853 case 0x64:
8854 case 0x65:
8855 case 0x66:
8856 case 0x67:
8857 case 0x68:
8858 case 0x69:
8859 case 0x6A:
8860 case 0x6B:
8861 case 0x6C:
8862 case 0x6D:
8863 case 0x6E:
8864 case 0x6F:
8865 case 0x70:
8866 case 0x71:
8867 case 0x72:
8868 case 0x73:
8869 case 0x74:
8870 case 0x75:
8871 case 0x76:
8872 case 0x77:
8873 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8874 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8875 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8876 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8877 case 0x7F: // UTF-8 string (indefinite length)
8878 {
8879 string_t s;
8880 return get_cbor_string(s) && sax->string(s);
8881 }
8882
8883 // array (0x00..0x17 data items follow)
8884 case 0x80:
8885 case 0x81:
8886 case 0x82:
8887 case 0x83:
8888 case 0x84:
8889 case 0x85:
8890 case 0x86:
8891 case 0x87:
8892 case 0x88:
8893 case 0x89:
8894 case 0x8A:
8895 case 0x8B:
8896 case 0x8C:
8897 case 0x8D:
8898 case 0x8E:
8899 case 0x8F:
8900 case 0x90:
8901 case 0x91:
8902 case 0x92:
8903 case 0x93:
8904 case 0x94:
8905 case 0x95:
8906 case 0x96:
8907 case 0x97:
8908 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8909
8910 case 0x98: // array (one-byte uint8_t for n follows)
8911 {
8912 std::uint8_t len{};
8913 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8914 }
8915
8916 case 0x99: // array (two-byte uint16_t for n follow)
8917 {
8918 std::uint16_t len{};
8919 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8920 }
8921
8922 case 0x9A: // array (four-byte uint32_t for n follow)
8923 {
8924 std::uint32_t len{};
8925 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
8926 }
8927
8928 case 0x9B: // array (eight-byte uint64_t for n follow)
8929 {
8930 std::uint64_t len{};
8931 return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
8932 }
8933
8934 case 0x9F: // array (indefinite length)
8935 return get_cbor_array(std::size_t(-1), tag_handler);
8936
8937 // map (0x00..0x17 pairs of data items follow)
8938 case 0xA0:
8939 case 0xA1:
8940 case 0xA2:
8941 case 0xA3:
8942 case 0xA4:
8943 case 0xA5:
8944 case 0xA6:
8945 case 0xA7:
8946 case 0xA8:
8947 case 0xA9:
8948 case 0xAA:
8949 case 0xAB:
8950 case 0xAC:
8951 case 0xAD:
8952 case 0xAE:
8953 case 0xAF:
8954 case 0xB0:
8955 case 0xB1:
8956 case 0xB2:
8957 case 0xB3:
8958 case 0xB4:
8959 case 0xB5:
8960 case 0xB6:
8961 case 0xB7:
8962 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
8963
8964 case 0xB8: // map (one-byte uint8_t for n follows)
8965 {
8966 std::uint8_t len{};
8967 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8968 }
8969
8970 case 0xB9: // map (two-byte uint16_t for n follow)
8971 {
8972 std::uint16_t len{};
8973 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8974 }
8975
8976 case 0xBA: // map (four-byte uint32_t for n follow)
8977 {
8978 std::uint32_t len{};
8979 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
8980 }
8981
8982 case 0xBB: // map (eight-byte uint64_t for n follow)
8983 {
8984 std::uint64_t len{};
8985 return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
8986 }
8987
8988 case 0xBF: // map (indefinite length)
8989 return get_cbor_object(std::size_t(-1), tag_handler);
8990
8991 case 0xC6: // tagged item
8992 case 0xC7:
8993 case 0xC8:
8994 case 0xC9:
8995 case 0xCA:
8996 case 0xCB:
8997 case 0xCC:
8998 case 0xCD:
8999 case 0xCE:
9000 case 0xCF:
9001 case 0xD0:
9002 case 0xD1:
9003 case 0xD2:
9004 case 0xD3:
9005 case 0xD4:
9006 case 0xD8: // tagged item (1 bytes follow)
9007 case 0xD9: // tagged item (2 bytes follow)
9008 case 0xDA: // tagged item (4 bytes follow)
9009 case 0xDB: // tagged item (8 bytes follow)
9010 {
9011 switch (tag_handler)
9012 {
9014 {
9015 auto last_token = get_token_string();
9016 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9017 }
9018
9020 {
9021 // ignore binary subtype
9022 switch (current)
9023 {
9024 case 0xD8:
9025 {
9026 std::uint8_t subtype_to_ignore{};
9027 get_number(input_format_t::cbor, subtype_to_ignore);
9028 break;
9029 }
9030 case 0xD9:
9031 {
9032 std::uint16_t subtype_to_ignore{};
9033 get_number(input_format_t::cbor, subtype_to_ignore);
9034 break;
9035 }
9036 case 0xDA:
9037 {
9038 std::uint32_t subtype_to_ignore{};
9039 get_number(input_format_t::cbor, subtype_to_ignore);
9040 break;
9041 }
9042 case 0xDB:
9043 {
9044 std::uint64_t subtype_to_ignore{};
9045 get_number(input_format_t::cbor, subtype_to_ignore);
9046 break;
9047 }
9048 default:
9049 break;
9050 }
9051 return parse_cbor_internal(true, tag_handler);
9052 }
9053
9055 {
9056 binary_t b;
9057 // use binary subtype and store in binary container
9058 switch (current)
9059 {
9060 case 0xD8:
9061 {
9062 std::uint8_t subtype{};
9064 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9065 break;
9066 }
9067 case 0xD9:
9068 {
9069 std::uint16_t subtype{};
9071 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9072 break;
9073 }
9074 case 0xDA:
9075 {
9076 std::uint32_t subtype{};
9078 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9079 break;
9080 }
9081 case 0xDB:
9082 {
9083 std::uint64_t subtype{};
9085 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9086 break;
9087 }
9088 default:
9089 return parse_cbor_internal(true, tag_handler);
9090 }
9091 get();
9092 return get_cbor_binary(b) && sax->binary(b);
9093 }
9094
9095 default: // LCOV_EXCL_LINE
9096 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9097 return false; // LCOV_EXCL_LINE
9098 }
9099 }
9100
9101 case 0xF4: // false
9102 return sax->boolean(false);
9103
9104 case 0xF5: // true
9105 return sax->boolean(true);
9106
9107 case 0xF6: // null
9108 return sax->null();
9109
9110 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9111 {
9112 const auto byte1_raw = get();
9114 {
9115 return false;
9116 }
9117 const auto byte2_raw = get();
9119 {
9120 return false;
9121 }
9122
9123 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9124 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9125
9126 // code from RFC 7049, Appendix D, Figure 3:
9127 // As half-precision floating-point numbers were only added
9128 // to IEEE 754 in 2008, today's programming platforms often
9129 // still only have limited support for them. It is very
9130 // easy to include at least decoding support for them even
9131 // without such support. An example of a small decoder for
9132 // half-precision floating-point numbers in the C language
9133 // is shown in Fig. 3.
9134 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9135 const double val = [&half]
9136 {
9137 const int exp = (half >> 10u) & 0x1Fu;
9138 const unsigned int mant = half & 0x3FFu;
9139 JSON_ASSERT(0 <= exp&& exp <= 32);
9140 JSON_ASSERT(mant <= 1024);
9141 switch (exp)
9142 {
9143 case 0:
9144 return std::ldexp(mant, -24);
9145 case 31:
9146 return (mant == 0)
9147 ? std::numeric_limits<double>::infinity()
9148 : std::numeric_limits<double>::quiet_NaN();
9149 default:
9150 return std::ldexp(mant + 1024, exp - 25);
9151 }
9152 }();
9153 return sax->number_float((half & 0x8000u) != 0
9154 ? static_cast<number_float_t>(-val)
9155 : static_cast<number_float_t>(val), "");
9156 }
9157
9158 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9159 {
9160 float number{};
9161 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9162 }
9163
9164 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9165 {
9166 double number{};
9167 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9168 }
9169
9170 default: // anything else (0xFF is handled inside the other types)
9171 {
9172 auto last_token = get_token_string();
9173 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9174 }
9175 }
9176 }
9177
9190 {
9192 {
9193 return false;
9194 }
9195
9196 switch (current)
9197 {
9198 // UTF-8 string (0x00..0x17 bytes follow)
9199 case 0x60:
9200 case 0x61:
9201 case 0x62:
9202 case 0x63:
9203 case 0x64:
9204 case 0x65:
9205 case 0x66:
9206 case 0x67:
9207 case 0x68:
9208 case 0x69:
9209 case 0x6A:
9210 case 0x6B:
9211 case 0x6C:
9212 case 0x6D:
9213 case 0x6E:
9214 case 0x6F:
9215 case 0x70:
9216 case 0x71:
9217 case 0x72:
9218 case 0x73:
9219 case 0x74:
9220 case 0x75:
9221 case 0x76:
9222 case 0x77:
9223 {
9224 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9225 }
9226
9227 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9228 {
9229 std::uint8_t len{};
9230 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9231 }
9232
9233 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9234 {
9235 std::uint16_t len{};
9236 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9237 }
9238
9239 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9240 {
9241 std::uint32_t len{};
9242 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9243 }
9244
9245 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9246 {
9247 std::uint64_t len{};
9248 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9249 }
9250
9251 case 0x7F: // UTF-8 string (indefinite length)
9252 {
9253 while (get() != 0xFF)
9254 {
9255 string_t chunk;
9256 if (!get_cbor_string(chunk))
9257 {
9258 return false;
9259 }
9260 result.append(chunk);
9261 }
9262 return true;
9263 }
9264
9265 default:
9266 {
9267 auto last_token = get_token_string();
9268 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string"), BasicJsonType()));
9269 }
9270 }
9271 }
9272
9285 {
9287 {
9288 return false;
9289 }
9290
9291 switch (current)
9292 {
9293 // Binary data (0x00..0x17 bytes follow)
9294 case 0x40:
9295 case 0x41:
9296 case 0x42:
9297 case 0x43:
9298 case 0x44:
9299 case 0x45:
9300 case 0x46:
9301 case 0x47:
9302 case 0x48:
9303 case 0x49:
9304 case 0x4A:
9305 case 0x4B:
9306 case 0x4C:
9307 case 0x4D:
9308 case 0x4E:
9309 case 0x4F:
9310 case 0x50:
9311 case 0x51:
9312 case 0x52:
9313 case 0x53:
9314 case 0x54:
9315 case 0x55:
9316 case 0x56:
9317 case 0x57:
9318 {
9319 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9320 }
9321
9322 case 0x58: // Binary data (one-byte uint8_t for n follows)
9323 {
9324 std::uint8_t len{};
9325 return get_number(input_format_t::cbor, len) &&
9326 get_binary(input_format_t::cbor, len, result);
9327 }
9328
9329 case 0x59: // Binary data (two-byte uint16_t for n follow)
9330 {
9331 std::uint16_t len{};
9332 return get_number(input_format_t::cbor, len) &&
9333 get_binary(input_format_t::cbor, len, result);
9334 }
9335
9336 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9337 {
9338 std::uint32_t len{};
9339 return get_number(input_format_t::cbor, len) &&
9340 get_binary(input_format_t::cbor, len, result);
9341 }
9342
9343 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9344 {
9345 std::uint64_t len{};
9346 return get_number(input_format_t::cbor, len) &&
9347 get_binary(input_format_t::cbor, len, result);
9348 }
9349
9350 case 0x5F: // Binary data (indefinite length)
9351 {
9352 while (get() != 0xFF)
9353 {
9354 binary_t chunk;
9355 if (!get_cbor_binary(chunk))
9356 {
9357 return false;
9358 }
9359 result.insert(result.end(), chunk.begin(), chunk.end());
9360 }
9361 return true;
9362 }
9363
9364 default:
9365 {
9366 auto last_token = get_token_string();
9367 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x" + last_token, "binary"), BasicJsonType()));
9368 }
9369 }
9370 }
9371
9378 bool get_cbor_array(const std::size_t len,
9379 const cbor_tag_handler_t tag_handler)
9380 {
9381 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9382 {
9383 return false;
9384 }
9385
9386 if (len != std::size_t(-1))
9387 {
9388 for (std::size_t i = 0; i < len; ++i)
9389 {
9390 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9391 {
9392 return false;
9393 }
9394 }
9395 }
9396 else
9397 {
9398 while (get() != 0xFF)
9399 {
9400 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9401 {
9402 return false;
9403 }
9404 }
9405 }
9406
9407 return sax->end_array();
9408 }
9409
9416 bool get_cbor_object(const std::size_t len,
9417 const cbor_tag_handler_t tag_handler)
9418 {
9419 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9420 {
9421 return false;
9422 }
9423
9424 if (len != 0)
9425 {
9426 string_t key;
9427 if (len != std::size_t(-1))
9428 {
9429 for (std::size_t i = 0; i < len; ++i)
9430 {
9431 get();
9433 {
9434 return false;
9435 }
9436
9437 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9438 {
9439 return false;
9440 }
9441 key.clear();
9442 }
9443 }
9444 else
9445 {
9446 while (get() != 0xFF)
9447 {
9449 {
9450 return false;
9451 }
9452
9453 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9454 {
9455 return false;
9456 }
9457 key.clear();
9458 }
9459 }
9460 }
9461
9462 return sax->end_object();
9463 }
9464
9466 // MsgPack //
9468
9473 {
9474 switch (get())
9475 {
9476 // EOF
9477 case std::char_traits<char_type>::eof():
9478 return unexpect_eof(input_format_t::msgpack, "value");
9479
9480 // positive fixint
9481 case 0x00:
9482 case 0x01:
9483 case 0x02:
9484 case 0x03:
9485 case 0x04:
9486 case 0x05:
9487 case 0x06:
9488 case 0x07:
9489 case 0x08:
9490 case 0x09:
9491 case 0x0A:
9492 case 0x0B:
9493 case 0x0C:
9494 case 0x0D:
9495 case 0x0E:
9496 case 0x0F:
9497 case 0x10:
9498 case 0x11:
9499 case 0x12:
9500 case 0x13:
9501 case 0x14:
9502 case 0x15:
9503 case 0x16:
9504 case 0x17:
9505 case 0x18:
9506 case 0x19:
9507 case 0x1A:
9508 case 0x1B:
9509 case 0x1C:
9510 case 0x1D:
9511 case 0x1E:
9512 case 0x1F:
9513 case 0x20:
9514 case 0x21:
9515 case 0x22:
9516 case 0x23:
9517 case 0x24:
9518 case 0x25:
9519 case 0x26:
9520 case 0x27:
9521 case 0x28:
9522 case 0x29:
9523 case 0x2A:
9524 case 0x2B:
9525 case 0x2C:
9526 case 0x2D:
9527 case 0x2E:
9528 case 0x2F:
9529 case 0x30:
9530 case 0x31:
9531 case 0x32:
9532 case 0x33:
9533 case 0x34:
9534 case 0x35:
9535 case 0x36:
9536 case 0x37:
9537 case 0x38:
9538 case 0x39:
9539 case 0x3A:
9540 case 0x3B:
9541 case 0x3C:
9542 case 0x3D:
9543 case 0x3E:
9544 case 0x3F:
9545 case 0x40:
9546 case 0x41:
9547 case 0x42:
9548 case 0x43:
9549 case 0x44:
9550 case 0x45:
9551 case 0x46:
9552 case 0x47:
9553 case 0x48:
9554 case 0x49:
9555 case 0x4A:
9556 case 0x4B:
9557 case 0x4C:
9558 case 0x4D:
9559 case 0x4E:
9560 case 0x4F:
9561 case 0x50:
9562 case 0x51:
9563 case 0x52:
9564 case 0x53:
9565 case 0x54:
9566 case 0x55:
9567 case 0x56:
9568 case 0x57:
9569 case 0x58:
9570 case 0x59:
9571 case 0x5A:
9572 case 0x5B:
9573 case 0x5C:
9574 case 0x5D:
9575 case 0x5E:
9576 case 0x5F:
9577 case 0x60:
9578 case 0x61:
9579 case 0x62:
9580 case 0x63:
9581 case 0x64:
9582 case 0x65:
9583 case 0x66:
9584 case 0x67:
9585 case 0x68:
9586 case 0x69:
9587 case 0x6A:
9588 case 0x6B:
9589 case 0x6C:
9590 case 0x6D:
9591 case 0x6E:
9592 case 0x6F:
9593 case 0x70:
9594 case 0x71:
9595 case 0x72:
9596 case 0x73:
9597 case 0x74:
9598 case 0x75:
9599 case 0x76:
9600 case 0x77:
9601 case 0x78:
9602 case 0x79:
9603 case 0x7A:
9604 case 0x7B:
9605 case 0x7C:
9606 case 0x7D:
9607 case 0x7E:
9608 case 0x7F:
9609 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9610
9611 // fixmap
9612 case 0x80:
9613 case 0x81:
9614 case 0x82:
9615 case 0x83:
9616 case 0x84:
9617 case 0x85:
9618 case 0x86:
9619 case 0x87:
9620 case 0x88:
9621 case 0x89:
9622 case 0x8A:
9623 case 0x8B:
9624 case 0x8C:
9625 case 0x8D:
9626 case 0x8E:
9627 case 0x8F:
9628 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9629
9630 // fixarray
9631 case 0x90:
9632 case 0x91:
9633 case 0x92:
9634 case 0x93:
9635 case 0x94:
9636 case 0x95:
9637 case 0x96:
9638 case 0x97:
9639 case 0x98:
9640 case 0x99:
9641 case 0x9A:
9642 case 0x9B:
9643 case 0x9C:
9644 case 0x9D:
9645 case 0x9E:
9646 case 0x9F:
9647 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9648
9649 // fixstr
9650 case 0xA0:
9651 case 0xA1:
9652 case 0xA2:
9653 case 0xA3:
9654 case 0xA4:
9655 case 0xA5:
9656 case 0xA6:
9657 case 0xA7:
9658 case 0xA8:
9659 case 0xA9:
9660 case 0xAA:
9661 case 0xAB:
9662 case 0xAC:
9663 case 0xAD:
9664 case 0xAE:
9665 case 0xAF:
9666 case 0xB0:
9667 case 0xB1:
9668 case 0xB2:
9669 case 0xB3:
9670 case 0xB4:
9671 case 0xB5:
9672 case 0xB6:
9673 case 0xB7:
9674 case 0xB8:
9675 case 0xB9:
9676 case 0xBA:
9677 case 0xBB:
9678 case 0xBC:
9679 case 0xBD:
9680 case 0xBE:
9681 case 0xBF:
9682 case 0xD9: // str 8
9683 case 0xDA: // str 16
9684 case 0xDB: // str 32
9685 {
9686 string_t s;
9687 return get_msgpack_string(s) && sax->string(s);
9688 }
9689
9690 case 0xC0: // nil
9691 return sax->null();
9692
9693 case 0xC2: // false
9694 return sax->boolean(false);
9695
9696 case 0xC3: // true
9697 return sax->boolean(true);
9698
9699 case 0xC4: // bin 8
9700 case 0xC5: // bin 16
9701 case 0xC6: // bin 32
9702 case 0xC7: // ext 8
9703 case 0xC8: // ext 16
9704 case 0xC9: // ext 32
9705 case 0xD4: // fixext 1
9706 case 0xD5: // fixext 2
9707 case 0xD6: // fixext 4
9708 case 0xD7: // fixext 8
9709 case 0xD8: // fixext 16
9710 {
9711 binary_t b;
9712 return get_msgpack_binary(b) && sax->binary(b);
9713 }
9714
9715 case 0xCA: // float 32
9716 {
9717 float number{};
9718 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9719 }
9720
9721 case 0xCB: // float 64
9722 {
9723 double number{};
9724 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9725 }
9726
9727 case 0xCC: // uint 8
9728 {
9729 std::uint8_t number{};
9730 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9731 }
9732
9733 case 0xCD: // uint 16
9734 {
9735 std::uint16_t number{};
9736 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9737 }
9738
9739 case 0xCE: // uint 32
9740 {
9741 std::uint32_t number{};
9742 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9743 }
9744
9745 case 0xCF: // uint 64
9746 {
9747 std::uint64_t number{};
9748 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9749 }
9750
9751 case 0xD0: // int 8
9752 {
9753 std::int8_t number{};
9754 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9755 }
9756
9757 case 0xD1: // int 16
9758 {
9759 std::int16_t number{};
9760 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9761 }
9762
9763 case 0xD2: // int 32
9764 {
9765 std::int32_t number{};
9766 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9767 }
9768
9769 case 0xD3: // int 64
9770 {
9771 std::int64_t number{};
9772 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9773 }
9774
9775 case 0xDC: // array 16
9776 {
9777 std::uint16_t len{};
9778 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9779 }
9780
9781 case 0xDD: // array 32
9782 {
9783 std::uint32_t len{};
9784 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9785 }
9786
9787 case 0xDE: // map 16
9788 {
9789 std::uint16_t len{};
9790 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9791 }
9792
9793 case 0xDF: // map 32
9794 {
9795 std::uint32_t len{};
9796 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9797 }
9798
9799 // negative fixint
9800 case 0xE0:
9801 case 0xE1:
9802 case 0xE2:
9803 case 0xE3:
9804 case 0xE4:
9805 case 0xE5:
9806 case 0xE6:
9807 case 0xE7:
9808 case 0xE8:
9809 case 0xE9:
9810 case 0xEA:
9811 case 0xEB:
9812 case 0xEC:
9813 case 0xED:
9814 case 0xEE:
9815 case 0xEF:
9816 case 0xF0:
9817 case 0xF1:
9818 case 0xF2:
9819 case 0xF3:
9820 case 0xF4:
9821 case 0xF5:
9822 case 0xF6:
9823 case 0xF7:
9824 case 0xF8:
9825 case 0xF9:
9826 case 0xFA:
9827 case 0xFB:
9828 case 0xFC:
9829 case 0xFD:
9830 case 0xFE:
9831 case 0xFF:
9832 return sax->number_integer(static_cast<std::int8_t>(current));
9833
9834 default: // anything else
9835 {
9836 auto last_token = get_token_string();
9837 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
9838 }
9839 }
9840 }
9841
9853 {
9855 {
9856 return false;
9857 }
9858
9859 switch (current)
9860 {
9861 // fixstr
9862 case 0xA0:
9863 case 0xA1:
9864 case 0xA2:
9865 case 0xA3:
9866 case 0xA4:
9867 case 0xA5:
9868 case 0xA6:
9869 case 0xA7:
9870 case 0xA8:
9871 case 0xA9:
9872 case 0xAA:
9873 case 0xAB:
9874 case 0xAC:
9875 case 0xAD:
9876 case 0xAE:
9877 case 0xAF:
9878 case 0xB0:
9879 case 0xB1:
9880 case 0xB2:
9881 case 0xB3:
9882 case 0xB4:
9883 case 0xB5:
9884 case 0xB6:
9885 case 0xB7:
9886 case 0xB8:
9887 case 0xB9:
9888 case 0xBA:
9889 case 0xBB:
9890 case 0xBC:
9891 case 0xBD:
9892 case 0xBE:
9893 case 0xBF:
9894 {
9895 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
9896 }
9897
9898 case 0xD9: // str 8
9899 {
9900 std::uint8_t len{};
9902 }
9903
9904 case 0xDA: // str 16
9905 {
9906 std::uint16_t len{};
9908 }
9909
9910 case 0xDB: // str 32
9911 {
9912 std::uint32_t len{};
9914 }
9915
9916 default:
9917 {
9918 auto last_token = get_token_string();
9919 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string"), BasicJsonType()));
9920 }
9921 }
9922 }
9923
9935 {
9936 // helper function to set the subtype
9937 auto assign_and_return_true = [&result](std::int8_t subtype)
9938 {
9939 result.set_subtype(static_cast<std::uint8_t>(subtype));
9940 return true;
9941 };
9942
9943 switch (current)
9944 {
9945 case 0xC4: // bin 8
9946 {
9947 std::uint8_t len{};
9948 return get_number(input_format_t::msgpack, len) &&
9949 get_binary(input_format_t::msgpack, len, result);
9950 }
9951
9952 case 0xC5: // bin 16
9953 {
9954 std::uint16_t len{};
9955 return get_number(input_format_t::msgpack, len) &&
9956 get_binary(input_format_t::msgpack, len, result);
9957 }
9958
9959 case 0xC6: // bin 32
9960 {
9961 std::uint32_t len{};
9962 return get_number(input_format_t::msgpack, len) &&
9963 get_binary(input_format_t::msgpack, len, result);
9964 }
9965
9966 case 0xC7: // ext 8
9967 {
9968 std::uint8_t len{};
9969 std::int8_t subtype{};
9970 return get_number(input_format_t::msgpack, len) &&
9972 get_binary(input_format_t::msgpack, len, result) &&
9973 assign_and_return_true(subtype);
9974 }
9975
9976 case 0xC8: // ext 16
9977 {
9978 std::uint16_t len{};
9979 std::int8_t subtype{};
9980 return get_number(input_format_t::msgpack, len) &&
9982 get_binary(input_format_t::msgpack, len, result) &&
9983 assign_and_return_true(subtype);
9984 }
9985
9986 case 0xC9: // ext 32
9987 {
9988 std::uint32_t len{};
9989 std::int8_t subtype{};
9990 return get_number(input_format_t::msgpack, len) &&
9992 get_binary(input_format_t::msgpack, len, result) &&
9993 assign_and_return_true(subtype);
9994 }
9995
9996 case 0xD4: // fixext 1
9997 {
9998 std::int8_t subtype{};
9999 return get_number(input_format_t::msgpack, subtype) &&
10000 get_binary(input_format_t::msgpack, 1, result) &&
10001 assign_and_return_true(subtype);
10002 }
10003
10004 case 0xD5: // fixext 2
10005 {
10006 std::int8_t subtype{};
10007 return get_number(input_format_t::msgpack, subtype) &&
10008 get_binary(input_format_t::msgpack, 2, result) &&
10009 assign_and_return_true(subtype);
10010 }
10011
10012 case 0xD6: // fixext 4
10013 {
10014 std::int8_t subtype{};
10015 return get_number(input_format_t::msgpack, subtype) &&
10016 get_binary(input_format_t::msgpack, 4, result) &&
10017 assign_and_return_true(subtype);
10018 }
10019
10020 case 0xD7: // fixext 8
10021 {
10022 std::int8_t subtype{};
10023 return get_number(input_format_t::msgpack, subtype) &&
10024 get_binary(input_format_t::msgpack, 8, result) &&
10025 assign_and_return_true(subtype);
10026 }
10027
10028 case 0xD8: // fixext 16
10029 {
10030 std::int8_t subtype{};
10031 return get_number(input_format_t::msgpack, subtype) &&
10032 get_binary(input_format_t::msgpack, 16, result) &&
10033 assign_and_return_true(subtype);
10034 }
10035
10036 default: // LCOV_EXCL_LINE
10037 return false; // LCOV_EXCL_LINE
10038 }
10039 }
10040
10045 bool get_msgpack_array(const std::size_t len)
10046 {
10047 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10048 {
10049 return false;
10050 }
10051
10052 for (std::size_t i = 0; i < len; ++i)
10053 {
10055 {
10056 return false;
10057 }
10058 }
10059
10060 return sax->end_array();
10061 }
10062
10067 bool get_msgpack_object(const std::size_t len)
10068 {
10069 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10070 {
10071 return false;
10072 }
10073
10074 string_t key;
10075 for (std::size_t i = 0; i < len; ++i)
10076 {
10077 get();
10079 {
10080 return false;
10081 }
10082
10084 {
10085 return false;
10086 }
10087 key.clear();
10088 }
10089
10090 return sax->end_object();
10091 }
10092
10094 // UBJSON //
10096
10104 bool parse_ubjson_internal(const bool get_char = true)
10105 {
10106 return get_ubjson_value(get_char ? get_ignore_noop() : current);
10107 }
10108
10123 bool get_ubjson_string(string_t& result, const bool get_char = true)
10124 {
10125 if (get_char)
10126 {
10127 get(); // TODO(niels): may we ignore N here?
10128 }
10129
10131 {
10132 return false;
10133 }
10134
10135 switch (current)
10136 {
10137 case 'U':
10138 {
10139 std::uint8_t len{};
10141 }
10142
10143 case 'i':
10144 {
10145 std::int8_t len{};
10147 }
10148
10149 case 'I':
10150 {
10151 std::int16_t len{};
10153 }
10154
10155 case 'l':
10156 {
10157 std::int32_t len{};
10159 }
10160
10161 case 'L':
10162 {
10163 std::int64_t len{};
10165 }
10166
10167 default:
10168 auto last_token = get_token_string();
10169 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string"), BasicJsonType()));
10170 }
10171 }
10172
10177 bool get_ubjson_size_value(std::size_t& result)
10178 {
10179 switch (get_ignore_noop())
10180 {
10181 case 'U':
10182 {
10183 std::uint8_t number{};
10185 {
10186 return false;
10187 }
10188 result = static_cast<std::size_t>(number);
10189 return true;
10190 }
10191
10192 case 'i':
10193 {
10194 std::int8_t number{};
10196 {
10197 return false;
10198 }
10199 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10200 return true;
10201 }
10202
10203 case 'I':
10204 {
10205 std::int16_t number{};
10207 {
10208 return false;
10209 }
10210 result = static_cast<std::size_t>(number);
10211 return true;
10212 }
10213
10214 case 'l':
10215 {
10216 std::int32_t number{};
10218 {
10219 return false;
10220 }
10221 result = static_cast<std::size_t>(number);
10222 return true;
10223 }
10224
10225 case 'L':
10226 {
10227 std::int64_t number{};
10229 {
10230 return false;
10231 }
10232 result = static_cast<std::size_t>(number);
10233 return true;
10234 }
10235
10236 default:
10237 {
10238 auto last_token = get_token_string();
10239 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size"), BasicJsonType()));
10240 }
10241 }
10242 }
10243
10254 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result)
10255 {
10256 result.first = string_t::npos; // size
10257 result.second = 0; // type
10258
10260
10261 if (current == '$')
10262 {
10263 result.second = get(); // must not ignore 'N', because 'N' maybe the type
10265 {
10266 return false;
10267 }
10268
10270 if (JSON_HEDLEY_UNLIKELY(current != '#'))
10271 {
10273 {
10274 return false;
10275 }
10276 auto last_token = get_token_string();
10277 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size"), BasicJsonType()));
10278 }
10279
10280 return get_ubjson_size_value(result.first);
10281 }
10282
10283 if (current == '#')
10284 {
10285 return get_ubjson_size_value(result.first);
10286 }
10287
10288 return true;
10289 }
10290
10296 {
10297 switch (prefix)
10298 {
10299 case std::char_traits<char_type>::eof(): // EOF
10300 return unexpect_eof(input_format_t::ubjson, "value");
10301
10302 case 'T': // true
10303 return sax->boolean(true);
10304 case 'F': // false
10305 return sax->boolean(false);
10306
10307 case 'Z': // null
10308 return sax->null();
10309
10310 case 'U':
10311 {
10312 std::uint8_t number{};
10313 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
10314 }
10315
10316 case 'i':
10317 {
10318 std::int8_t number{};
10319 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10320 }
10321
10322 case 'I':
10323 {
10324 std::int16_t number{};
10325 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10326 }
10327
10328 case 'l':
10329 {
10330 std::int32_t number{};
10331 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10332 }
10333
10334 case 'L':
10335 {
10336 std::int64_t number{};
10337 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10338 }
10339
10340 case 'd':
10341 {
10342 float number{};
10343 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10344 }
10345
10346 case 'D':
10347 {
10348 double number{};
10349 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10350 }
10351
10352 case 'H':
10353 {
10355 }
10356
10357 case 'C': // char
10358 {
10359 get();
10361 {
10362 return false;
10363 }
10364 if (JSON_HEDLEY_UNLIKELY(current > 127))
10365 {
10366 auto last_token = get_token_string();
10367 return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char"), BasicJsonType()));
10368 }
10369 string_t s(1, static_cast<typename string_t::value_type>(current));
10370 return sax->string(s);
10371 }
10372
10373 case 'S': // string
10374 {
10375 string_t s;
10376 return get_ubjson_string(s) && sax->string(s);
10377 }
10378
10379 case '[': // array
10380 return get_ubjson_array();
10381
10382 case '{': // object
10383 return get_ubjson_object();
10384
10385 default: // anything else
10386 {
10387 auto last_token = get_token_string();
10388 return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value"), BasicJsonType()));
10389 }
10390 }
10391 }
10392
10397 {
10398 std::pair<std::size_t, char_int_type> size_and_type;
10399 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10400 {
10401 return false;
10402 }
10403
10404 if (size_and_type.first != string_t::npos)
10405 {
10406 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
10407 {
10408 return false;
10409 }
10410
10411 if (size_and_type.second != 0)
10412 {
10413 if (size_and_type.second != 'N')
10414 {
10415 for (std::size_t i = 0; i < size_and_type.first; ++i)
10416 {
10417 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10418 {
10419 return false;
10420 }
10421 }
10422 }
10423 }
10424 else
10425 {
10426 for (std::size_t i = 0; i < size_and_type.first; ++i)
10427 {
10429 {
10430 return false;
10431 }
10432 }
10433 }
10434 }
10435 else
10436 {
10437 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10438 {
10439 return false;
10440 }
10441
10442 while (current != ']')
10443 {
10445 {
10446 return false;
10447 }
10449 }
10450 }
10451
10452 return sax->end_array();
10453 }
10454
10459 {
10460 std::pair<std::size_t, char_int_type> size_and_type;
10461 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10462 {
10463 return false;
10464 }
10465
10466 string_t key;
10467 if (size_and_type.first != string_t::npos)
10468 {
10469 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
10470 {
10471 return false;
10472 }
10473
10474 if (size_and_type.second != 0)
10475 {
10476 for (std::size_t i = 0; i < size_and_type.first; ++i)
10477 {
10479 {
10480 return false;
10481 }
10482 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10483 {
10484 return false;
10485 }
10486 key.clear();
10487 }
10488 }
10489 else
10490 {
10491 for (std::size_t i = 0; i < size_and_type.first; ++i)
10492 {
10494 {
10495 return false;
10496 }
10498 {
10499 return false;
10500 }
10501 key.clear();
10502 }
10503 }
10504 }
10505 else
10506 {
10507 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10508 {
10509 return false;
10510 }
10511
10512 while (current != '}')
10513 {
10514 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
10515 {
10516 return false;
10517 }
10519 {
10520 return false;
10521 }
10523 key.clear();
10524 }
10525 }
10526
10527 return sax->end_object();
10528 }
10529
10530 // Note, no reader for UBJSON binary types is implemented because they do
10531 // not exist
10532
10534 {
10535 // get size of following number string
10536 std::size_t size{};
10537 auto res = get_ubjson_size_value(size);
10538 if (JSON_HEDLEY_UNLIKELY(!res))
10539 {
10540 return res;
10541 }
10542
10543 // get number string
10544 std::vector<char> number_vector;
10545 for (std::size_t i = 0; i < size; ++i)
10546 {
10547 get();
10549 {
10550 return false;
10551 }
10552 number_vector.push_back(static_cast<char>(current));
10553 }
10554
10555 // parse number string
10556 using ia_type = decltype(detail::input_adapter(number_vector));
10557 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
10558 const auto result_number = number_lexer.scan();
10559 const auto number_string = number_lexer.get_token_string();
10560 const auto result_remainder = number_lexer.scan();
10561
10562 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
10563
10564 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
10565 {
10566 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
10567 }
10568
10569 switch (result_number)
10570 {
10571 case token_type::value_integer:
10572 return sax->number_integer(number_lexer.get_number_integer());
10573 case token_type::value_unsigned:
10574 return sax->number_unsigned(number_lexer.get_number_unsigned());
10575 case token_type::value_float:
10576 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
10577 case token_type::uninitialized:
10578 case token_type::literal_true:
10579 case token_type::literal_false:
10580 case token_type::literal_null:
10581 case token_type::value_string:
10582 case token_type::begin_array:
10583 case token_type::begin_object:
10584 case token_type::end_array:
10585 case token_type::end_object:
10586 case token_type::name_separator:
10587 case token_type::value_separator:
10588 case token_type::parse_error:
10589 case token_type::end_of_input:
10590 case token_type::literal_or_value:
10591 default:
10592 return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read, exception_message(input_format_t::ubjson, "invalid number text: " + number_lexer.get_token_string(), "high-precision number"), BasicJsonType()));
10593 }
10594 }
10595
10597 // Utility functions //
10599
10610 {
10611 ++chars_read;
10612 return current = ia.get_character();
10613 }
10614
10619 {
10620 do
10621 {
10622 get();
10623 }
10624 while (current == 'N');
10625
10626 return current;
10627 }
10628
10629 /*
10630 @brief read a number from the input
10631
10632 @tparam NumberType the type of the number
10633 @param[in] format the current format (for diagnostics)
10634 @param[out] result number of type @a NumberType
10635
10636 @return whether conversion completed
10637
10638 @note This function needs to respect the system's endianess, because
10639 bytes in CBOR, MessagePack, and UBJSON are stored in network order
10640 (big endian) and therefore need reordering on little endian systems.
10641 */
10642 template<typename NumberType, bool InputIsLittleEndian = false>
10643 bool get_number(const input_format_t format, NumberType& result)
10644 {
10645 // step 1: read input into array with system's byte order
10646 std::array<std::uint8_t, sizeof(NumberType)> vec{};
10647 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
10648 {
10649 get();
10650 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10651 {
10652 return false;
10653 }
10654
10655 // reverse byte order prior to conversion if necessary
10656 if (is_little_endian != InputIsLittleEndian)
10657 {
10658 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10659 }
10660 else
10661 {
10662 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10663 }
10664 }
10665
10666 // step 2: convert array into number of type T and return
10667 std::memcpy(&result, vec.data(), sizeof(NumberType));
10668 return true;
10669 }
10670
10685 template<typename NumberType>
10686 bool get_string(const input_format_t format,
10687 const NumberType len,
10688 string_t& result)
10689 {
10690 bool success = true;
10691 for (NumberType i = 0; i < len; i++)
10692 {
10693 get();
10694 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10695 {
10696 success = false;
10697 break;
10698 }
10699 result.push_back(static_cast<typename string_t::value_type>(current));
10700 }
10701 return success;
10702 }
10703
10718 template<typename NumberType>
10719 bool get_binary(const input_format_t format,
10720 const NumberType len,
10721 binary_t& result)
10722 {
10723 bool success = true;
10724 for (NumberType i = 0; i < len; i++)
10725 {
10726 get();
10727 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10728 {
10729 success = false;
10730 break;
10731 }
10732 result.push_back(static_cast<std::uint8_t>(current));
10733 }
10734 return success;
10735 }
10736
10743 bool unexpect_eof(const input_format_t format, const char* context) const
10744 {
10745 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10746 {
10747 return sax->parse_error(chars_read, "<end of file>",
10748 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
10749 }
10750 return true;
10751 }
10752
10756 std::string get_token_string() const
10757 {
10758 std::array<char, 3> cr{{}};
10759 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10760 return std::string{cr.data()};
10761 }
10762
10769 std::string exception_message(const input_format_t format,
10770 const std::string& detail,
10771 const std::string& context) const
10772 {
10773 std::string error_msg = "syntax error while parsing ";
10774
10775 switch (format)
10776 {
10778 error_msg += "CBOR";
10779 break;
10780
10782 error_msg += "MessagePack";
10783 break;
10784
10786 error_msg += "UBJSON";
10787 break;
10788
10790 error_msg += "BSON";
10791 break;
10792
10793 case input_format_t::json: // LCOV_EXCL_LINE
10794 default: // LCOV_EXCL_LINE
10795 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10796 }
10797
10798 return error_msg + " " + context + ": " + detail;
10799 }
10800
10801 private:
10803 InputAdapterType ia;
10804
10806 char_int_type current = std::char_traits<char_type>::eof();
10807
10809 std::size_t chars_read = 0;
10810
10813
10815 json_sax_t* sax = nullptr;
10816};
10817} // namespace detail
10818} // namespace nlohmann
10819
10820// #include <nlohmann/detail/input/input_adapters.hpp>
10821
10822// #include <nlohmann/detail/input/lexer.hpp>
10823
10824// #include <nlohmann/detail/input/parser.hpp>
10825
10826
10827#include <cmath> // isfinite
10828#include <cstdint> // uint8_t
10829#include <functional> // function
10830#include <string> // string
10831#include <utility> // move
10832#include <vector> // vector
10833
10834// #include <nlohmann/detail/exceptions.hpp>
10835
10836// #include <nlohmann/detail/input/input_adapters.hpp>
10837
10838// #include <nlohmann/detail/input/json_sax.hpp>
10839
10840// #include <nlohmann/detail/input/lexer.hpp>
10841
10842// #include <nlohmann/detail/macro_scope.hpp>
10843
10844// #include <nlohmann/detail/meta/is_sax.hpp>
10845
10846// #include <nlohmann/detail/value_t.hpp>
10847
10848
10849namespace nlohmann
10850{
10851namespace detail
10852{
10854// parser //
10856
10857enum class parse_event_t : std::uint8_t
10858{
10862 object_end,
10866 array_end,
10868 key,
10870 value
10871};
10872
10873template<typename BasicJsonType>
10875 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
10876
10882template<typename BasicJsonType, typename InputAdapterType>
10884{
10885 using number_integer_t = typename BasicJsonType::number_integer_t;
10886 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
10887 using number_float_t = typename BasicJsonType::number_float_t;
10888 using string_t = typename BasicJsonType::string_t;
10891
10892 public:
10894 explicit parser(InputAdapterType&& adapter,
10895 const parser_callback_t<BasicJsonType> cb = nullptr,
10896 const bool allow_exceptions_ = true,
10897 const bool skip_comments = false)
10898 : callback(cb)
10899 , m_lexer(std::move(adapter), skip_comments)
10900 , allow_exceptions(allow_exceptions_)
10901 {
10902 // read first token
10903 get_token();
10904 }
10905
10916 void parse(const bool strict, BasicJsonType& result)
10917 {
10918 if (callback)
10919 {
10921 sax_parse_internal(&sdp);
10922
10923 // in strict mode, input must be completely read
10924 if (strict && (get_token() != token_type::end_of_input))
10925 {
10929 exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10930 }
10931
10932 // in case of an error, return discarded value
10933 if (sdp.is_errored())
10934 {
10935 result = value_t::discarded;
10936 return;
10937 }
10938
10939 // set top-level value to null if it was discarded by the callback
10940 // function
10941 if (result.is_discarded())
10942 {
10943 result = nullptr;
10944 }
10945 }
10946 else
10947 {
10949 sax_parse_internal(&sdp);
10950
10951 // in strict mode, input must be completely read
10952 if (strict && (get_token() != token_type::end_of_input))
10953 {
10956 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10957 }
10958
10959 // in case of an error, return discarded value
10960 if (sdp.is_errored())
10961 {
10962 result = value_t::discarded;
10963 return;
10964 }
10965 }
10966
10967 result.assert_invariant();
10968 }
10969
10976 bool accept(const bool strict = true)
10977 {
10979 return sax_parse(&sax_acceptor, strict);
10980 }
10981
10982 template<typename SAX>
10984 bool sax_parse(SAX* sax, const bool strict = true)
10985 {
10987 const bool result = sax_parse_internal(sax);
10988
10989 // strict mode: next byte must be EOF
10990 if (result && strict && (get_token() != token_type::end_of_input))
10991 {
10992 return sax->parse_error(m_lexer.get_position(),
10994 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
10995 }
10996
10997 return result;
10998 }
10999
11000 private:
11001 template<typename SAX>
11003 bool sax_parse_internal(SAX* sax)
11004 {
11005 // stack to remember the hierarchy of structured values we are parsing
11006 // true = array; false = object
11007 std::vector<bool> states;
11008 // value to avoid a goto (see comment where set to true)
11009 bool skip_to_state_evaluation = false;
11010
11011 while (true)
11012 {
11013 if (!skip_to_state_evaluation)
11014 {
11015 // invariant: get_token() was called before each iteration
11016 switch (last_token)
11017 {
11018 case token_type::begin_object:
11019 {
11020 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
11021 {
11022 return false;
11023 }
11024
11025 // closing } -> we are done
11026 if (get_token() == token_type::end_object)
11027 {
11028 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11029 {
11030 return false;
11031 }
11032 break;
11033 }
11034
11035 // parse key
11036 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11037 {
11038 return sax->parse_error(m_lexer.get_position(),
11040 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11041 }
11042 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11043 {
11044 return false;
11045 }
11046
11047 // parse separator (:)
11048 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11049 {
11050 return sax->parse_error(m_lexer.get_position(),
11052 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11053 }
11054
11055 // remember we are now inside an object
11056 states.push_back(false);
11057
11058 // parse values
11059 get_token();
11060 continue;
11061 }
11062
11063 case token_type::begin_array:
11064 {
11065 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
11066 {
11067 return false;
11068 }
11069
11070 // closing ] -> we are done
11071 if (get_token() == token_type::end_array)
11072 {
11073 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11074 {
11075 return false;
11076 }
11077 break;
11078 }
11079
11080 // remember we are now inside an array
11081 states.push_back(true);
11082
11083 // parse values (no need to call get_token)
11084 continue;
11085 }
11086
11087 case token_type::value_float:
11088 {
11089 const auto res = m_lexer.get_number_float();
11090
11091 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11092 {
11093 return sax->parse_error(m_lexer.get_position(),
11095 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
11096 }
11097
11098 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11099 {
11100 return false;
11101 }
11102
11103 break;
11104 }
11105
11106 case token_type::literal_false:
11107 {
11108 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11109 {
11110 return false;
11111 }
11112 break;
11113 }
11114
11115 case token_type::literal_null:
11116 {
11117 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11118 {
11119 return false;
11120 }
11121 break;
11122 }
11123
11124 case token_type::literal_true:
11125 {
11126 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11127 {
11128 return false;
11129 }
11130 break;
11131 }
11132
11133 case token_type::value_integer:
11134 {
11135 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11136 {
11137 return false;
11138 }
11139 break;
11140 }
11141
11142 case token_type::value_string:
11143 {
11144 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11145 {
11146 return false;
11147 }
11148 break;
11149 }
11150
11151 case token_type::value_unsigned:
11152 {
11153 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11154 {
11155 return false;
11156 }
11157 break;
11158 }
11159
11160 case token_type::parse_error:
11161 {
11162 // using "uninitialized" to avoid "expected" message
11163 return sax->parse_error(m_lexer.get_position(),
11165 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
11166 }
11167
11168 case token_type::uninitialized:
11169 case token_type::end_array:
11170 case token_type::end_object:
11171 case token_type::name_separator:
11172 case token_type::value_separator:
11173 case token_type::end_of_input:
11174 case token_type::literal_or_value:
11175 default: // the last token was unexpected
11176 {
11177 return sax->parse_error(m_lexer.get_position(),
11179 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
11180 }
11181 }
11182 }
11183 else
11184 {
11185 skip_to_state_evaluation = false;
11186 }
11187
11188 // we reached this line after we successfully parsed a value
11189 if (states.empty())
11190 {
11191 // empty stack: we reached the end of the hierarchy: done
11192 return true;
11193 }
11194
11195 if (states.back()) // array
11196 {
11197 // comma -> next value
11198 if (get_token() == token_type::value_separator)
11199 {
11200 // parse a new value
11201 get_token();
11202 continue;
11203 }
11204
11205 // closing ]
11206 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11207 {
11208 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11209 {
11210 return false;
11211 }
11212
11213 // We are done with this array. Before we can parse a
11214 // new value, we need to evaluate the new state first.
11215 // By setting skip_to_state_evaluation to false, we
11216 // are effectively jumping to the beginning of this if.
11217 JSON_ASSERT(!states.empty());
11218 states.pop_back();
11219 skip_to_state_evaluation = true;
11220 continue;
11221 }
11222
11223 return sax->parse_error(m_lexer.get_position(),
11225 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11226 }
11227
11228 // states.back() is false -> object
11229
11230 // comma -> next value
11231 if (get_token() == token_type::value_separator)
11232 {
11233 // parse key
11234 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11235 {
11236 return sax->parse_error(m_lexer.get_position(),
11238 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11239 }
11240
11241 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11242 {
11243 return false;
11244 }
11245
11246 // parse separator (:)
11247 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11248 {
11249 return sax->parse_error(m_lexer.get_position(),
11251 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11252 }
11253
11254 // parse values
11255 get_token();
11256 continue;
11257 }
11258
11259 // closing }
11260 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11261 {
11262 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11263 {
11264 return false;
11265 }
11266
11267 // We are done with this object. Before we can parse a
11268 // new value, we need to evaluate the new state first.
11269 // By setting skip_to_state_evaluation to false, we
11270 // are effectively jumping to the beginning of this if.
11271 JSON_ASSERT(!states.empty());
11272 states.pop_back();
11273 skip_to_state_evaluation = true;
11274 continue;
11275 }
11276
11277 return sax->parse_error(m_lexer.get_position(),
11279 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11280 }
11281 }
11282
11285 {
11286 return last_token = m_lexer.scan();
11287 }
11288
11289 std::string exception_message(const token_type expected, const std::string& context)
11290 {
11291 std::string error_msg = "syntax error ";
11292
11293 if (!context.empty())
11294 {
11295 error_msg += "while parsing " + context + " ";
11296 }
11297
11298 error_msg += "- ";
11299
11300 if (last_token == token_type::parse_error)
11301 {
11302 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
11303 m_lexer.get_token_string() + "'";
11304 }
11305 else
11306 {
11307 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
11308 }
11309
11310 if (expected != token_type::uninitialized)
11311 {
11312 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
11313 }
11314
11315 return error_msg;
11316 }
11317
11318 private:
11322 token_type last_token = token_type::uninitialized;
11326 const bool allow_exceptions = true;
11327};
11328
11329} // namespace detail
11330} // namespace nlohmann
11331
11332// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11333
11334
11335// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11336
11337
11338#include <cstddef> // ptrdiff_t
11339#include <limits> // numeric_limits
11340
11341// #include <nlohmann/detail/macro_scope.hpp>
11342
11343
11344namespace nlohmann
11345{
11346namespace detail
11347{
11348/*
11349@brief an iterator for primitive JSON types
11350
11351This class models an iterator for primitive JSON types (boolean, number,
11352string). It's only purpose is to allow the iterator/const_iterator classes
11353to "iterate" over primitive values. Internally, the iterator is modeled by
11354a `difference_type` variable. Value begin_value (`0`) models the begin,
11355end_value (`1`) models past the end.
11356*/
11358{
11359 private:
11360 using difference_type = std::ptrdiff_t;
11361 static constexpr difference_type begin_value = 0;
11362 static constexpr difference_type end_value = begin_value + 1;
11363
11366 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11367
11368 public:
11369 constexpr difference_type get_value() const noexcept
11370 {
11371 return m_it;
11372 }
11373
11375 void set_begin() noexcept
11376 {
11377 m_it = begin_value;
11378 }
11379
11381 void set_end() noexcept
11382 {
11383 m_it = end_value;
11384 }
11385
11387 constexpr bool is_begin() const noexcept
11388 {
11389 return m_it == begin_value;
11390 }
11391
11393 constexpr bool is_end() const noexcept
11394 {
11395 return m_it == end_value;
11396 }
11397
11398 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11399 {
11400 return lhs.m_it == rhs.m_it;
11401 }
11402
11403 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11404 {
11405 return lhs.m_it < rhs.m_it;
11406 }
11407
11409 {
11410 auto result = *this;
11411 result += n;
11412 return result;
11413 }
11414
11416 {
11417 return lhs.m_it - rhs.m_it;
11418 }
11419
11421 {
11422 ++m_it;
11423 return *this;
11424 }
11425
11426 primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
11427 {
11428 auto result = *this;
11429 ++m_it;
11430 return result;
11431 }
11432
11434 {
11435 --m_it;
11436 return *this;
11437 }
11438
11439 primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
11440 {
11441 auto result = *this;
11442 --m_it;
11443 return result;
11444 }
11445
11447 {
11448 m_it += n;
11449 return *this;
11450 }
11451
11453 {
11454 m_it -= n;
11455 return *this;
11456 }
11457};
11458} // namespace detail
11459} // namespace nlohmann
11460
11461
11462namespace nlohmann
11463{
11464namespace detail
11465{
11472template<typename BasicJsonType> struct internal_iterator
11473{
11475 typename BasicJsonType::object_t::iterator object_iterator {};
11477 typename BasicJsonType::array_t::iterator array_iterator {};
11480};
11481} // namespace detail
11482} // namespace nlohmann
11483
11484// #include <nlohmann/detail/iterators/iter_impl.hpp>
11485
11486
11487#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
11488#include <type_traits> // conditional, is_const, remove_const
11489
11490// #include <nlohmann/detail/exceptions.hpp>
11491
11492// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11493
11494// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11495
11496// #include <nlohmann/detail/macro_scope.hpp>
11497
11498// #include <nlohmann/detail/meta/cpp_future.hpp>
11499
11500// #include <nlohmann/detail/meta/type_traits.hpp>
11501
11502// #include <nlohmann/detail/value_t.hpp>
11503
11504
11505namespace nlohmann
11506{
11507namespace detail
11508{
11509// forward declare, to be able to friend it later on
11510template<typename IteratorType> class iteration_proxy;
11511template<typename IteratorType> class iteration_proxy_value;
11512
11529template<typename BasicJsonType>
11531{
11533 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
11539
11540 using object_t = typename BasicJsonType::object_t;
11541 using array_t = typename BasicJsonType::array_t;
11542 // make sure BasicJsonType is basic_json or const basic_json
11544 "iter_impl only accepts (const) basic_json");
11545
11546 public:
11547
11553 using iterator_category = std::bidirectional_iterator_tag;
11554
11556 using value_type = typename BasicJsonType::value_type;
11558 using difference_type = typename BasicJsonType::difference_type;
11560 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
11561 typename BasicJsonType::const_pointer,
11562 typename BasicJsonType::pointer>::type;
11565 typename std::conditional<std::is_const<BasicJsonType>::value,
11566 typename BasicJsonType::const_reference,
11567 typename BasicJsonType::reference>::type;
11568
11569 iter_impl() = default;
11570 ~iter_impl() = default;
11571 iter_impl(iter_impl&&) noexcept = default;
11572 iter_impl& operator=(iter_impl&&) noexcept = default;
11573
11580 explicit iter_impl(pointer object) noexcept : m_object(object)
11581 {
11582 JSON_ASSERT(m_object != nullptr);
11583
11584 switch (m_object->m_type)
11585 {
11586 case value_t::object:
11587 {
11588 m_it.object_iterator = typename object_t::iterator();
11589 break;
11590 }
11591
11592 case value_t::array:
11593 {
11594 m_it.array_iterator = typename array_t::iterator();
11595 break;
11596 }
11597
11598 case value_t::null:
11599 case value_t::string:
11600 case value_t::boolean:
11604 case value_t::binary:
11605 case value_t::discarded:
11606 default:
11607 {
11609 break;
11610 }
11611 }
11612 }
11613
11631 : m_object(other.m_object), m_it(other.m_it)
11632 {}
11633
11641 {
11642 if (&other != this)
11643 {
11644 m_object = other.m_object;
11645 m_it = other.m_it;
11646 }
11647 return *this;
11648 }
11649
11655 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept
11656 : m_object(other.m_object), m_it(other.m_it)
11657 {}
11658
11665 iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
11666 {
11667 m_object = other.m_object;
11668 m_it = other.m_it;
11669 return *this;
11670 }
11671
11677 void set_begin() noexcept
11678 {
11679 JSON_ASSERT(m_object != nullptr);
11680
11681 switch (m_object->m_type)
11682 {
11683 case value_t::object:
11684 {
11685 m_it.object_iterator = m_object->m_value.object->begin();
11686 break;
11687 }
11688
11689 case value_t::array:
11690 {
11691 m_it.array_iterator = m_object->m_value.array->begin();
11692 break;
11693 }
11694
11695 case value_t::null:
11696 {
11697 // set to end so begin()==end() is true: null is empty
11699 break;
11700 }
11701
11702 case value_t::string:
11703 case value_t::boolean:
11707 case value_t::binary:
11708 case value_t::discarded:
11709 default:
11710 {
11712 break;
11713 }
11714 }
11715 }
11716
11721 void set_end() noexcept
11722 {
11723 JSON_ASSERT(m_object != nullptr);
11724
11725 switch (m_object->m_type)
11726 {
11727 case value_t::object:
11728 {
11729 m_it.object_iterator = m_object->m_value.object->end();
11730 break;
11731 }
11732
11733 case value_t::array:
11734 {
11735 m_it.array_iterator = m_object->m_value.array->end();
11736 break;
11737 }
11738
11739 case value_t::null:
11740 case value_t::string:
11741 case value_t::boolean:
11745 case value_t::binary:
11746 case value_t::discarded:
11747 default:
11748 {
11750 break;
11751 }
11752 }
11753 }
11754
11755 public:
11761 {
11762 JSON_ASSERT(m_object != nullptr);
11763
11764 switch (m_object->m_type)
11765 {
11766 case value_t::object:
11767 {
11768 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11769 return m_it.object_iterator->second;
11770 }
11771
11772 case value_t::array:
11773 {
11774 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11775 return *m_it.array_iterator;
11776 }
11777
11778 case value_t::null:
11779 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11780
11781 case value_t::string:
11782 case value_t::boolean:
11786 case value_t::binary:
11787 case value_t::discarded:
11788 default:
11789 {
11791 {
11792 return *m_object;
11793 }
11794
11795 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11796 }
11797 }
11798 }
11799
11805 {
11806 JSON_ASSERT(m_object != nullptr);
11807
11808 switch (m_object->m_type)
11809 {
11810 case value_t::object:
11811 {
11812 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11813 return &(m_it.object_iterator->second);
11814 }
11815
11816 case value_t::array:
11817 {
11818 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11819 return &*m_it.array_iterator;
11820 }
11821
11822 case value_t::null:
11823 case value_t::string:
11824 case value_t::boolean:
11828 case value_t::binary:
11829 case value_t::discarded:
11830 default:
11831 {
11833 {
11834 return m_object;
11835 }
11836
11837 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11838 }
11839 }
11840 }
11841
11846 iter_impl const operator++(int) // NOLINT(readability-const-return-type)
11847 {
11848 auto result = *this;
11849 ++(*this);
11850 return result;
11851 }
11852
11858 {
11859 JSON_ASSERT(m_object != nullptr);
11860
11861 switch (m_object->m_type)
11862 {
11863 case value_t::object:
11864 {
11865 std::advance(m_it.object_iterator, 1);
11866 break;
11867 }
11868
11869 case value_t::array:
11870 {
11871 std::advance(m_it.array_iterator, 1);
11872 break;
11873 }
11874
11875 case value_t::null:
11876 case value_t::string:
11877 case value_t::boolean:
11881 case value_t::binary:
11882 case value_t::discarded:
11883 default:
11884 {
11886 break;
11887 }
11888 }
11889
11890 return *this;
11891 }
11892
11897 iter_impl const operator--(int) // NOLINT(readability-const-return-type)
11898 {
11899 auto result = *this;
11900 --(*this);
11901 return result;
11902 }
11903
11909 {
11910 JSON_ASSERT(m_object != nullptr);
11911
11912 switch (m_object->m_type)
11913 {
11914 case value_t::object:
11915 {
11916 std::advance(m_it.object_iterator, -1);
11917 break;
11918 }
11919
11920 case value_t::array:
11921 {
11922 std::advance(m_it.array_iterator, -1);
11923 break;
11924 }
11925
11926 case value_t::null:
11927 case value_t::string:
11928 case value_t::boolean:
11932 case value_t::binary:
11933 case value_t::discarded:
11934 default:
11935 {
11937 break;
11938 }
11939 }
11940
11941 return *this;
11942 }
11943
11948 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
11949 bool operator==(const IterImpl& other) const
11950 {
11951 // if objects are not the same, the comparison is undefined
11952 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11953 {
11954 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
11955 }
11956
11957 JSON_ASSERT(m_object != nullptr);
11958
11959 switch (m_object->m_type)
11960 {
11961 case value_t::object:
11962 return (m_it.object_iterator == other.m_it.object_iterator);
11963
11964 case value_t::array:
11965 return (m_it.array_iterator == other.m_it.array_iterator);
11966
11967 case value_t::null:
11968 case value_t::string:
11969 case value_t::boolean:
11973 case value_t::binary:
11974 case value_t::discarded:
11975 default:
11976 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
11977 }
11978 }
11979
11984 template < typename IterImpl, detail::enable_if_t < (std::is_same<IterImpl, iter_impl>::value || std::is_same<IterImpl, other_iter_impl>::value), std::nullptr_t > = nullptr >
11985 bool operator!=(const IterImpl& other) const
11986 {
11987 return !operator==(other);
11988 }
11989
11994 bool operator<(const iter_impl& other) const
11995 {
11996 // if objects are not the same, the comparison is undefined
11997 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
11998 {
11999 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12000 }
12001
12002 JSON_ASSERT(m_object != nullptr);
12003
12004 switch (m_object->m_type)
12005 {
12006 case value_t::object:
12007 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
12008
12009 case value_t::array:
12010 return (m_it.array_iterator < other.m_it.array_iterator);
12011
12012 case value_t::null:
12013 case value_t::string:
12014 case value_t::boolean:
12018 case value_t::binary:
12019 case value_t::discarded:
12020 default:
12022 }
12023 }
12024
12029 bool operator<=(const iter_impl& other) const
12030 {
12031 return !other.operator < (*this);
12032 }
12033
12038 bool operator>(const iter_impl& other) const
12039 {
12040 return !operator<=(other);
12041 }
12042
12047 bool operator>=(const iter_impl& other) const
12048 {
12049 return !operator<(other);
12050 }
12051
12057 {
12058 JSON_ASSERT(m_object != nullptr);
12059
12060 switch (m_object->m_type)
12061 {
12062 case value_t::object:
12063 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12064
12065 case value_t::array:
12066 {
12067 std::advance(m_it.array_iterator, i);
12068 break;
12069 }
12070
12071 case value_t::null:
12072 case value_t::string:
12073 case value_t::boolean:
12077 case value_t::binary:
12078 case value_t::discarded:
12079 default:
12080 {
12082 break;
12083 }
12084 }
12085
12086 return *this;
12087 }
12088
12094 {
12095 return operator+=(-i);
12096 }
12097
12103 {
12104 auto result = *this;
12105 result += i;
12106 return result;
12107 }
12108
12114 {
12115 auto result = it;
12116 result += i;
12117 return result;
12118 }
12119
12125 {
12126 auto result = *this;
12127 result -= i;
12128 return result;
12129 }
12130
12136 {
12137 JSON_ASSERT(m_object != nullptr);
12138
12139 switch (m_object->m_type)
12140 {
12141 case value_t::object:
12142 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12143
12144 case value_t::array:
12145 return m_it.array_iterator - other.m_it.array_iterator;
12146
12147 case value_t::null:
12148 case value_t::string:
12149 case value_t::boolean:
12153 case value_t::binary:
12154 case value_t::discarded:
12155 default:
12157 }
12158 }
12159
12165 {
12166 JSON_ASSERT(m_object != nullptr);
12167
12168 switch (m_object->m_type)
12169 {
12170 case value_t::object:
12171 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
12172
12173 case value_t::array:
12174 return *std::next(m_it.array_iterator, n);
12175
12176 case value_t::null:
12177 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12178
12179 case value_t::string:
12180 case value_t::boolean:
12184 case value_t::binary:
12185 case value_t::discarded:
12186 default:
12187 {
12189 {
12190 return *m_object;
12191 }
12192
12193 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12194 }
12195 }
12196 }
12197
12202 const typename object_t::key_type& key() const
12203 {
12204 JSON_ASSERT(m_object != nullptr);
12205
12206 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
12207 {
12208 return m_it.object_iterator->first;
12209 }
12210
12211 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
12212 }
12213
12219 {
12220 return operator*();
12221 }
12222
12225 pointer m_object = nullptr;
12228};
12229} // namespace detail
12230} // namespace nlohmann
12231
12232// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12233
12234// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12235
12236
12237#include <cstddef> // ptrdiff_t
12238#include <iterator> // reverse_iterator
12239#include <utility> // declval
12240
12241namespace nlohmann
12242{
12243namespace detail
12244{
12246// reverse_iterator //
12248
12267template<typename Base>
12268class json_reverse_iterator : public std::reverse_iterator<Base>
12269{
12270 public:
12271 using difference_type = std::ptrdiff_t;
12273 using base_iterator = std::reverse_iterator<Base>;
12275 using reference = typename Base::reference;
12276
12278 explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
12279 : base_iterator(it) {}
12280
12282 explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
12283
12285 json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
12286 {
12287 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12288 }
12289
12292 {
12293 return static_cast<json_reverse_iterator&>(base_iterator::operator++());
12294 }
12295
12297 json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
12298 {
12299 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12300 }
12301
12304 {
12305 return static_cast<json_reverse_iterator&>(base_iterator::operator--());
12306 }
12307
12310 {
12311 return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
12312 }
12313
12316 {
12317 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12318 }
12319
12322 {
12323 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12324 }
12325
12328 {
12329 return base_iterator(*this) - base_iterator(other);
12330 }
12331
12334 {
12335 return *(this->operator+(n));
12336 }
12337
12339 auto key() const -> decltype(std::declval<Base>().key())
12340 {
12341 auto it = --this->base();
12342 return it.key();
12343 }
12344
12347 {
12348 auto it = --this->base();
12349 return it.operator * ();
12350 }
12351};
12352} // namespace detail
12353} // namespace nlohmann
12354
12355// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12356
12357// #include <nlohmann/detail/json_pointer.hpp>
12358
12359
12360#include <algorithm> // all_of
12361#include <cctype> // isdigit
12362#include <limits> // max
12363#include <numeric> // accumulate
12364#include <string> // string
12365#include <utility> // move
12366#include <vector> // vector
12367
12368// #include <nlohmann/detail/exceptions.hpp>
12369
12370// #include <nlohmann/detail/macro_scope.hpp>
12371
12372// #include <nlohmann/detail/string_escape.hpp>
12373
12374// #include <nlohmann/detail/value_t.hpp>
12375
12376
12377namespace nlohmann
12378{
12379template<typename BasicJsonType>
12381{
12382 // allow basic_json to access private members
12384 friend class basic_json;
12385
12386 public:
12408 explicit json_pointer(const std::string& s = "")
12410 {}
12411
12426 std::string to_string() const
12427 {
12428 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12429 std::string{},
12430 [](const std::string & a, const std::string & b)
12431 {
12432 return a + "/" + detail::escape(b);
12433 });
12434 }
12435
12437 operator std::string() const
12438 {
12439 return to_string();
12440 }
12441
12459 {
12461 ptr.reference_tokens.begin(),
12462 ptr.reference_tokens.end());
12463 return *this;
12464 }
12465
12482 json_pointer& operator/=(std::string token)
12483 {
12484 push_back(std::move(token));
12485 return *this;
12486 }
12487
12504 json_pointer& operator/=(std::size_t array_idx)
12505 {
12506 return *this /= std::to_string(array_idx);
12507 }
12508
12525 const json_pointer& rhs)
12526 {
12527 return json_pointer(lhs) /= rhs;
12528 }
12529
12545 friend json_pointer operator/(const json_pointer& ptr, std::string token) // NOLINT(performance-unnecessary-value-param)
12546 {
12547 return json_pointer(ptr) /= std::move(token);
12548 }
12549
12565 friend json_pointer operator/(const json_pointer& ptr, std::size_t array_idx)
12566 {
12567 return json_pointer(ptr) /= array_idx;
12568 }
12569
12584 {
12585 if (empty())
12586 {
12587 return *this;
12588 }
12589
12590 json_pointer res = *this;
12591 res.pop_back();
12592 return res;
12593 }
12594
12609 {
12611 {
12612 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12613 }
12614
12615 reference_tokens.pop_back();
12616 }
12617
12632 const std::string& back() const
12633 {
12635 {
12636 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12637 }
12638
12639 return reference_tokens.back();
12640 }
12641
12654 void push_back(const std::string& token)
12655 {
12656 reference_tokens.push_back(token);
12657 }
12658
12660 void push_back(std::string&& token)
12661 {
12662 reference_tokens.push_back(std::move(token));
12663 }
12664
12679 bool empty() const noexcept
12680 {
12681 return reference_tokens.empty();
12682 }
12683
12684 private:
12695 static typename BasicJsonType::size_type array_index(const std::string& s)
12696 {
12697 using size_type = typename BasicJsonType::size_type;
12698
12699 // error condition (cf. RFC 6901, Sect. 4)
12700 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
12701 {
12702 JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
12703 }
12704
12705 // error condition (cf. RFC 6901, Sect. 4)
12706 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
12707 {
12708 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
12709 }
12710
12711 std::size_t processed_chars = 0;
12712 unsigned long long res = 0; // NOLINT(runtime/int)
12713 JSON_TRY
12714 {
12715 res = std::stoull(s, &processed_chars);
12716 }
12717 JSON_CATCH(std::out_of_range&)
12718 {
12719 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12720 }
12721
12722 // check if the string was completely read
12723 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
12724 {
12725 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12726 }
12727
12728 // only triggered on special platforms (like 32bit), see also
12729 // https://github.com/nlohmann/json/pull/2203
12730 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
12731 {
12732 JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
12733 }
12734
12735 return static_cast<size_type>(res);
12736 }
12737
12739 json_pointer top() const
12740 {
12742 {
12743 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12744 }
12745
12748 return result;
12749 }
12750
12751 private:
12761 {
12762 auto* result = &j;
12763
12764 // in case no reference tokens exist, return a reference to the JSON value
12765 // j which will be overwritten by a primitive value
12766 for (const auto& reference_token : reference_tokens)
12767 {
12768 switch (result->type())
12769 {
12771 {
12772 if (reference_token == "0")
12773 {
12774 // start a new array if reference token is 0
12775 result = &result->operator[](0);
12776 }
12777 else
12778 {
12779 // start a new object otherwise
12780 result = &result->operator[](reference_token);
12781 }
12782 break;
12783 }
12784
12786 {
12787 // create an entry in the object
12788 result = &result->operator[](reference_token);
12789 break;
12790 }
12791
12793 {
12794 // create an entry in the array
12795 result = &result->operator[](array_index(reference_token));
12796 break;
12797 }
12798
12799 /*
12800 The following code is only reached if there exists a reference
12801 token _and_ the current value is primitive. In this case, we have
12802 an error situation, because primitive values may only occur as
12803 single value; that is, with an empty list of reference tokens.
12804 */
12812 default:
12813 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
12814 }
12815 }
12816
12817 return *result;
12818 }
12819
12840 {
12841 for (const auto& reference_token : reference_tokens)
12842 {
12843 // convert null values to arrays or objects before continuing
12844 if (ptr->is_null())
12845 {
12846 // check if reference token is a number
12847 const bool nums =
12848 std::all_of(reference_token.begin(), reference_token.end(),
12849 [](const unsigned char x)
12850 {
12851 return std::isdigit(x);
12852 });
12853
12854 // change value to array for numbers or "-" or to object otherwise
12855 *ptr = (nums || reference_token == "-")
12858 }
12859
12860 switch (ptr->type())
12861 {
12863 {
12864 // use unchecked object access
12865 ptr = &ptr->operator[](reference_token);
12866 break;
12867 }
12868
12870 {
12871 if (reference_token == "-")
12872 {
12873 // explicitly treat "-" as index beyond the end
12874 ptr = &ptr->operator[](ptr->m_value.array->size());
12875 }
12876 else
12877 {
12878 // convert array index to number; unchecked access
12879 ptr = &ptr->operator[](array_index(reference_token));
12880 }
12881 break;
12882 }
12883
12892 default:
12893 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12894 }
12895 }
12896
12897 return *ptr;
12898 }
12899
12907 {
12908 for (const auto& reference_token : reference_tokens)
12909 {
12910 switch (ptr->type())
12911 {
12913 {
12914 // note: at performs range check
12915 ptr = &ptr->at(reference_token);
12916 break;
12917 }
12918
12920 {
12921 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12922 {
12923 // "-" always fails the range check
12925 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
12926 ") is out of range", *ptr));
12927 }
12928
12929 // note: at performs range check
12930 ptr = &ptr->at(array_index(reference_token));
12931 break;
12932 }
12933
12942 default:
12943 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12944 }
12945 }
12946
12947 return *ptr;
12948 }
12949
12964 {
12965 for (const auto& reference_token : reference_tokens)
12966 {
12967 switch (ptr->type())
12968 {
12970 {
12971 // use unchecked object access
12972 ptr = &ptr->operator[](reference_token);
12973 break;
12974 }
12975
12977 {
12978 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
12979 {
12980 // "-" cannot be used for const access
12981 JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
12982 }
12983
12984 // use unchecked array access
12985 ptr = &ptr->operator[](array_index(reference_token));
12986 break;
12987 }
12988
12997 default:
12998 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
12999 }
13000 }
13001
13002 return *ptr;
13003 }
13004
13011 const BasicJsonType& get_checked(const BasicJsonType* ptr) const
13012 {
13013 for (const auto& reference_token : reference_tokens)
13014 {
13015 switch (ptr->type())
13016 {
13018 {
13019 // note: at performs range check
13020 ptr = &ptr->at(reference_token);
13021 break;
13022 }
13023
13025 {
13026 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13027 {
13028 // "-" always fails the range check
13030 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13031 ") is out of range", *ptr));
13032 }
13033
13034 // note: at performs range check
13035 ptr = &ptr->at(array_index(reference_token));
13036 break;
13037 }
13038
13047 default:
13048 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13049 }
13050 }
13051
13052 return *ptr;
13053 }
13054
13059 bool contains(const BasicJsonType* ptr) const
13060 {
13061 for (const auto& reference_token : reference_tokens)
13062 {
13063 switch (ptr->type())
13064 {
13066 {
13067 if (!ptr->contains(reference_token))
13068 {
13069 // we did not find the key in the object
13070 return false;
13071 }
13072
13073 ptr = &ptr->operator[](reference_token);
13074 break;
13075 }
13076
13078 {
13079 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13080 {
13081 // "-" always fails the range check
13082 return false;
13083 }
13084 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13085 {
13086 // invalid char
13087 return false;
13088 }
13089 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
13090 {
13091 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13092 {
13093 // first char should be between '1' and '9'
13094 return false;
13095 }
13096 for (std::size_t i = 1; i < reference_token.size(); i++)
13097 {
13098 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13099 {
13100 // other char should be between '0' and '9'
13101 return false;
13102 }
13103 }
13104 }
13105
13106 const auto idx = array_index(reference_token);
13107 if (idx >= ptr->size())
13108 {
13109 // index out of range
13110 return false;
13111 }
13112
13113 ptr = &ptr->operator[](idx);
13114 break;
13115 }
13116
13125 default:
13126 {
13127 // we do not expect primitive values if there is still a
13128 // reference token to process
13129 return false;
13130 }
13131 }
13132 }
13133
13134 // no reference token left means we found a primitive value
13135 return true;
13136 }
13137
13147 static std::vector<std::string> split(const std::string& reference_string)
13148 {
13149 std::vector<std::string> result;
13150
13151 // special case: empty reference string -> no reference tokens
13152 if (reference_string.empty())
13153 {
13154 return result;
13155 }
13156
13157 // check if nonempty reference string begins with slash
13158 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
13159 {
13160 JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
13161 }
13162
13163 // extract the reference tokens:
13164 // - slash: position of the last read slash (or end of string)
13165 // - start: position after the previous slash
13166 for (
13167 // search for the first slash after the first character
13168 std::size_t slash = reference_string.find_first_of('/', 1),
13169 // set the beginning of the first reference token
13170 start = 1;
13171 // we can stop if start == 0 (if slash == std::string::npos)
13172 start != 0;
13173 // set the beginning of the next reference token
13174 // (will eventually be 0 if slash == std::string::npos)
13175 start = (slash == std::string::npos) ? 0 : slash + 1,
13176 // find next slash
13177 slash = reference_string.find_first_of('/', start))
13178 {
13179 // use the text between the beginning of the reference token
13180 // (start) and the last slash (slash).
13181 auto reference_token = reference_string.substr(start, slash - start);
13182
13183 // check reference tokens are properly escaped
13184 for (std::size_t pos = reference_token.find_first_of('~');
13185 pos != std::string::npos;
13186 pos = reference_token.find_first_of('~', pos + 1))
13187 {
13188 JSON_ASSERT(reference_token[pos] == '~');
13189
13190 // ~ must be followed by 0 or 1
13191 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
13192 (reference_token[pos + 1] != '0' &&
13193 reference_token[pos + 1] != '1')))
13194 {
13195 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
13196 }
13197 }
13198
13199 // finally, store the reference token
13200 detail::unescape(reference_token);
13201 result.push_back(reference_token);
13202 }
13203
13204 return result;
13205 }
13206
13207 private:
13215 static void flatten(const std::string& reference_string,
13216 const BasicJsonType& value,
13218 {
13219 switch (value.type())
13220 {
13222 {
13223 if (value.m_value.array->empty())
13224 {
13225 // flatten empty array as null
13226 result[reference_string] = nullptr;
13227 }
13228 else
13229 {
13230 // iterate array and use index as reference string
13231 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13232 {
13233 flatten(reference_string + "/" + std::to_string(i),
13234 value.m_value.array->operator[](i), result);
13235 }
13236 }
13237 break;
13238 }
13239
13241 {
13242 if (value.m_value.object->empty())
13243 {
13244 // flatten empty object as null
13245 result[reference_string] = nullptr;
13246 }
13247 else
13248 {
13249 // iterate object and use keys as reference string
13250 for (const auto& element : *value.m_value.object)
13251 {
13252 flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
13253 }
13254 }
13255 break;
13256 }
13257
13266 default:
13267 {
13268 // add primitive value with its reference string
13269 result[reference_string] = value;
13270 break;
13271 }
13272 }
13273 }
13274
13285 static BasicJsonType
13287 {
13288 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
13289 {
13290 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
13291 }
13292
13294
13295 // iterate the JSON object values
13296 for (const auto& element : *value.m_value.object)
13297 {
13298 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
13299 {
13300 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
13301 }
13302
13303 // assign value to reference pointed to by JSON pointer; Note that if
13304 // the JSON pointer is "" (i.e., points to the whole value), function
13305 // get_and_create returns a reference to result itself. An assignment
13306 // will then create a primitive value.
13307 json_pointer(element.first).get_and_create(result) = element.second;
13308 }
13309
13310 return result;
13311 }
13312
13324 friend bool operator==(json_pointer const& lhs,
13325 json_pointer const& rhs) noexcept
13326 {
13327 return lhs.reference_tokens == rhs.reference_tokens;
13328 }
13329
13341 friend bool operator!=(json_pointer const& lhs,
13342 json_pointer const& rhs) noexcept
13343 {
13344 return !(lhs == rhs);
13345 }
13346
13348 std::vector<std::string> reference_tokens;
13349};
13350} // namespace nlohmann
13351
13352// #include <nlohmann/detail/json_ref.hpp>
13353
13354
13355#include <initializer_list>
13356#include <utility>
13357
13358// #include <nlohmann/detail/meta/type_traits.hpp>
13359
13360
13361namespace nlohmann
13362{
13363namespace detail
13364{
13365template<typename BasicJsonType>
13367{
13368 public:
13369 using value_type = BasicJsonType;
13370
13372 : owned_value(std::move(value))
13373 {}
13374
13376 : value_ref(&value)
13377 {}
13378
13379 json_ref(std::initializer_list<json_ref> init)
13380 : owned_value(init)
13381 {}
13382
13383 template <
13384 class... Args,
13385 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13386 json_ref(Args && ... args)
13387 : owned_value(std::forward<Args>(args)...)
13388 {}
13389
13390 // class should be movable only
13391 json_ref(json_ref&&) noexcept = default;
13392 json_ref(const json_ref&) = delete;
13393 json_ref& operator=(const json_ref&) = delete;
13394 json_ref& operator=(json_ref&&) = delete;
13395 ~json_ref() = default;
13396
13398 {
13399 if (value_ref == nullptr)
13400 {
13401 return std::move(owned_value);
13402 }
13403 return *value_ref;
13404 }
13405
13406 value_type const& operator*() const
13407 {
13408 return value_ref ? *value_ref : owned_value;
13409 }
13410
13411 value_type const* operator->() const
13412 {
13413 return &** this;
13414 }
13415
13416 private:
13417 mutable value_type owned_value = nullptr;
13418 value_type const* value_ref = nullptr;
13419};
13420} // namespace detail
13421} // namespace nlohmann
13422
13423// #include <nlohmann/detail/macro_scope.hpp>
13424
13425// #include <nlohmann/detail/string_escape.hpp>
13426
13427// #include <nlohmann/detail/meta/cpp_future.hpp>
13428
13429// #include <nlohmann/detail/meta/type_traits.hpp>
13430
13431// #include <nlohmann/detail/output/binary_writer.hpp>
13432
13433
13434#include <algorithm> // reverse
13435#include <array> // array
13436#include <cmath> // isnan, isinf
13437#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13438#include <cstring> // memcpy
13439#include <limits> // numeric_limits
13440#include <string> // string
13441#include <utility> // move
13442
13443// #include <nlohmann/detail/input/binary_reader.hpp>
13444
13445// #include <nlohmann/detail/macro_scope.hpp>
13446
13447// #include <nlohmann/detail/output/output_adapters.hpp>
13448
13449
13450#include <algorithm> // copy
13451#include <cstddef> // size_t
13452#include <iterator> // back_inserter
13453#include <memory> // shared_ptr, make_shared
13454#include <string> // basic_string
13455#include <vector> // vector
13456
13457#ifndef JSON_NO_IO
13458 #include <ios> // streamsize
13459 #include <ostream> // basic_ostream
13460#endif // JSON_NO_IO
13461
13462// #include <nlohmann/detail/macro_scope.hpp>
13463
13464
13465namespace nlohmann
13466{
13467namespace detail
13468{
13470template<typename CharType> struct output_adapter_protocol
13471{
13472 virtual void write_character(CharType c) = 0;
13473 virtual void write_characters(const CharType* s, std::size_t length) = 0;
13474 virtual ~output_adapter_protocol() = default;
13475
13480 output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
13481};
13482
13484template<typename CharType>
13485using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13486
13488template<typename CharType>
13490{
13491 public:
13492 explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
13493 : v(vec)
13494 {}
13495
13496 void write_character(CharType c) override
13497 {
13498 v.push_back(c);
13499 }
13500
13502 void write_characters(const CharType* s, std::size_t length) override
13503 {
13504 std::copy(s, s + length, std::back_inserter(v));
13505 }
13506
13507 private:
13508 std::vector<CharType>& v;
13509};
13510
13511#ifndef JSON_NO_IO
13513template<typename CharType>
13515{
13516 public:
13517 explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
13518 : stream(s)
13519 {}
13520
13521 void write_character(CharType c) override
13522 {
13523 stream.put(c);
13524 }
13525
13527 void write_characters(const CharType* s, std::size_t length) override
13528 {
13529 stream.write(s, static_cast<std::streamsize>(length));
13530 }
13531
13532 private:
13533 std::basic_ostream<CharType>& stream;
13534};
13535#endif // JSON_NO_IO
13536
13538template<typename CharType, typename StringType = std::basic_string<CharType>>
13540{
13541 public:
13542 explicit output_string_adapter(StringType& s) noexcept
13543 : str(s)
13544 {}
13545
13546 void write_character(CharType c) override
13547 {
13548 str.push_back(c);
13549 }
13550
13552 void write_characters(const CharType* s, std::size_t length) override
13553 {
13554 str.append(s, length);
13555 }
13556
13557 private:
13558 StringType& str;
13559};
13560
13561template<typename CharType, typename StringType = std::basic_string<CharType>>
13563{
13564 public:
13565 output_adapter(std::vector<CharType>& vec)
13566 : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
13567
13568#ifndef JSON_NO_IO
13569 output_adapter(std::basic_ostream<CharType>& s)
13570 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
13571#endif // JSON_NO_IO
13572
13573 output_adapter(StringType& s)
13574 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
13575
13577 {
13578 return oa;
13579 }
13580
13581 private:
13583};
13584} // namespace detail
13585} // namespace nlohmann
13586
13587
13588namespace nlohmann
13589{
13590namespace detail
13591{
13593// binary writer //
13595
13599template<typename BasicJsonType, typename CharType>
13601{
13602 using string_t = typename BasicJsonType::string_t;
13603 using binary_t = typename BasicJsonType::binary_t;
13604 using number_float_t = typename BasicJsonType::number_float_t;
13605
13606 public:
13612 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
13613 {
13614 JSON_ASSERT(oa);
13615 }
13616
13621 void write_bson(const BasicJsonType& j)
13622 {
13623 switch (j.type())
13624 {
13625 case value_t::object:
13626 {
13627 write_bson_object(*j.m_value.object);
13628 break;
13629 }
13630
13631 case value_t::null:
13632 case value_t::array:
13633 case value_t::string:
13634 case value_t::boolean:
13635 case value_t::number_integer:
13636 case value_t::number_unsigned:
13637 case value_t::number_float:
13638 case value_t::binary:
13639 case value_t::discarded:
13640 default:
13641 {
13642 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));
13643 }
13644 }
13645 }
13646
13650 void write_cbor(const BasicJsonType& j)
13651 {
13652 switch (j.type())
13653 {
13654 case value_t::null:
13655 {
13656 oa->write_character(to_char_type(0xF6));
13657 break;
13658 }
13659
13660 case value_t::boolean:
13661 {
13662 oa->write_character(j.m_value.boolean
13663 ? to_char_type(0xF5)
13664 : to_char_type(0xF4));
13665 break;
13666 }
13667
13668 case value_t::number_integer:
13669 {
13670 if (j.m_value.number_integer >= 0)
13671 {
13672 // CBOR does not differentiate between positive signed
13673 // integers and unsigned integers. Therefore, we used the
13674 // code from the value_t::number_unsigned case here.
13675 if (j.m_value.number_integer <= 0x17)
13676 {
13677 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13678 }
13679 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13680 {
13681 oa->write_character(to_char_type(0x18));
13682 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13683 }
13684 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
13685 {
13686 oa->write_character(to_char_type(0x19));
13687 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13688 }
13689 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
13690 {
13691 oa->write_character(to_char_type(0x1A));
13692 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13693 }
13694 else
13695 {
13696 oa->write_character(to_char_type(0x1B));
13697 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13698 }
13699 }
13700 else
13701 {
13702 // The conversions below encode the sign in the first
13703 // byte, and the value is converted to a positive number.
13704 const auto positive_number = -1 - j.m_value.number_integer;
13705 if (j.m_value.number_integer >= -24)
13706 {
13707 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
13708 }
13709 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
13710 {
13711 oa->write_character(to_char_type(0x38));
13712 write_number(static_cast<std::uint8_t>(positive_number));
13713 }
13714 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
13715 {
13716 oa->write_character(to_char_type(0x39));
13717 write_number(static_cast<std::uint16_t>(positive_number));
13718 }
13719 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
13720 {
13721 oa->write_character(to_char_type(0x3A));
13722 write_number(static_cast<std::uint32_t>(positive_number));
13723 }
13724 else
13725 {
13726 oa->write_character(to_char_type(0x3B));
13727 write_number(static_cast<std::uint64_t>(positive_number));
13728 }
13729 }
13730 break;
13731 }
13732
13733 case value_t::number_unsigned:
13734 {
13735 if (j.m_value.number_unsigned <= 0x17)
13736 {
13737 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13738 }
13739 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13740 {
13741 oa->write_character(to_char_type(0x18));
13742 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13743 }
13744 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13745 {
13746 oa->write_character(to_char_type(0x19));
13747 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
13748 }
13749 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13750 {
13751 oa->write_character(to_char_type(0x1A));
13752 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
13753 }
13754 else
13755 {
13756 oa->write_character(to_char_type(0x1B));
13757 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
13758 }
13759 break;
13760 }
13761
13762 case value_t::number_float:
13763 {
13764 if (std::isnan(j.m_value.number_float))
13765 {
13766 // NaN is 0xf97e00 in CBOR
13767 oa->write_character(to_char_type(0xF9));
13768 oa->write_character(to_char_type(0x7E));
13769 oa->write_character(to_char_type(0x00));
13770 }
13771 else if (std::isinf(j.m_value.number_float))
13772 {
13773 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
13774 oa->write_character(to_char_type(0xf9));
13775 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
13776 oa->write_character(to_char_type(0x00));
13777 }
13778 else
13779 {
13780 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
13781 }
13782 break;
13783 }
13784
13785 case value_t::string:
13786 {
13787 // step 1: write control byte and the string length
13788 const auto N = j.m_value.string->size();
13789 if (N <= 0x17)
13790 {
13791 write_number(static_cast<std::uint8_t>(0x60 + N));
13792 }
13793 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13794 {
13795 oa->write_character(to_char_type(0x78));
13796 write_number(static_cast<std::uint8_t>(N));
13797 }
13798 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13799 {
13800 oa->write_character(to_char_type(0x79));
13801 write_number(static_cast<std::uint16_t>(N));
13802 }
13803 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13804 {
13805 oa->write_character(to_char_type(0x7A));
13806 write_number(static_cast<std::uint32_t>(N));
13807 }
13808 // LCOV_EXCL_START
13809 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13810 {
13811 oa->write_character(to_char_type(0x7B));
13812 write_number(static_cast<std::uint64_t>(N));
13813 }
13814 // LCOV_EXCL_STOP
13815
13816 // step 2: write the string
13817 oa->write_characters(
13818 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
13819 j.m_value.string->size());
13820 break;
13821 }
13822
13823 case value_t::array:
13824 {
13825 // step 1: write control byte and the array size
13826 const auto N = j.m_value.array->size();
13827 if (N <= 0x17)
13828 {
13829 write_number(static_cast<std::uint8_t>(0x80 + N));
13830 }
13831 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13832 {
13833 oa->write_character(to_char_type(0x98));
13834 write_number(static_cast<std::uint8_t>(N));
13835 }
13836 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13837 {
13838 oa->write_character(to_char_type(0x99));
13839 write_number(static_cast<std::uint16_t>(N));
13840 }
13841 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13842 {
13843 oa->write_character(to_char_type(0x9A));
13844 write_number(static_cast<std::uint32_t>(N));
13845 }
13846 // LCOV_EXCL_START
13847 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13848 {
13849 oa->write_character(to_char_type(0x9B));
13850 write_number(static_cast<std::uint64_t>(N));
13851 }
13852 // LCOV_EXCL_STOP
13853
13854 // step 2: write each element
13855 for (const auto& el : *j.m_value.array)
13856 {
13857 write_cbor(el);
13858 }
13859 break;
13860 }
13861
13862 case value_t::binary:
13863 {
13864 if (j.m_value.binary->has_subtype())
13865 {
13866 if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
13867 {
13868 write_number(static_cast<std::uint8_t>(0xd8));
13869 write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
13870 }
13871 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
13872 {
13873 write_number(static_cast<std::uint8_t>(0xd9));
13874 write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
13875 }
13876 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
13877 {
13878 write_number(static_cast<std::uint8_t>(0xda));
13879 write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
13880 }
13881 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
13882 {
13883 write_number(static_cast<std::uint8_t>(0xdb));
13884 write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
13885 }
13886 }
13887
13888 // step 1: write control byte and the binary array size
13889 const auto N = j.m_value.binary->size();
13890 if (N <= 0x17)
13891 {
13892 write_number(static_cast<std::uint8_t>(0x40 + N));
13893 }
13894 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13895 {
13896 oa->write_character(to_char_type(0x58));
13897 write_number(static_cast<std::uint8_t>(N));
13898 }
13899 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13900 {
13901 oa->write_character(to_char_type(0x59));
13902 write_number(static_cast<std::uint16_t>(N));
13903 }
13904 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13905 {
13906 oa->write_character(to_char_type(0x5A));
13907 write_number(static_cast<std::uint32_t>(N));
13908 }
13909 // LCOV_EXCL_START
13910 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13911 {
13912 oa->write_character(to_char_type(0x5B));
13913 write_number(static_cast<std::uint64_t>(N));
13914 }
13915 // LCOV_EXCL_STOP
13916
13917 // step 2: write each element
13918 oa->write_characters(
13919 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
13920 N);
13921
13922 break;
13923 }
13924
13925 case value_t::object:
13926 {
13927 // step 1: write control byte and the object size
13928 const auto N = j.m_value.object->size();
13929 if (N <= 0x17)
13930 {
13931 write_number(static_cast<std::uint8_t>(0xA0 + N));
13932 }
13933 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
13934 {
13935 oa->write_character(to_char_type(0xB8));
13936 write_number(static_cast<std::uint8_t>(N));
13937 }
13938 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
13939 {
13940 oa->write_character(to_char_type(0xB9));
13941 write_number(static_cast<std::uint16_t>(N));
13942 }
13943 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
13944 {
13945 oa->write_character(to_char_type(0xBA));
13946 write_number(static_cast<std::uint32_t>(N));
13947 }
13948 // LCOV_EXCL_START
13949 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
13950 {
13951 oa->write_character(to_char_type(0xBB));
13952 write_number(static_cast<std::uint64_t>(N));
13953 }
13954 // LCOV_EXCL_STOP
13955
13956 // step 2: write each element
13957 for (const auto& el : *j.m_value.object)
13958 {
13959 write_cbor(el.first);
13960 write_cbor(el.second);
13961 }
13962 break;
13963 }
13964
13965 case value_t::discarded:
13966 default:
13967 break;
13968 }
13969 }
13970
13974 void write_msgpack(const BasicJsonType& j)
13975 {
13976 switch (j.type())
13977 {
13978 case value_t::null: // nil
13979 {
13980 oa->write_character(to_char_type(0xC0));
13981 break;
13982 }
13983
13984 case value_t::boolean: // true and false
13985 {
13986 oa->write_character(j.m_value.boolean
13987 ? to_char_type(0xC3)
13988 : to_char_type(0xC2));
13989 break;
13990 }
13991
13992 case value_t::number_integer:
13993 {
13994 if (j.m_value.number_integer >= 0)
13995 {
13996 // MessagePack does not differentiate between positive
13997 // signed integers and unsigned integers. Therefore, we used
13998 // the code from the value_t::number_unsigned case here.
13999 if (j.m_value.number_unsigned < 128)
14000 {
14001 // positive fixnum
14002 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14003 }
14004 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14005 {
14006 // uint 8
14007 oa->write_character(to_char_type(0xCC));
14008 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14009 }
14010 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14011 {
14012 // uint 16
14013 oa->write_character(to_char_type(0xCD));
14014 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14015 }
14016 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14017 {
14018 // uint 32
14019 oa->write_character(to_char_type(0xCE));
14020 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14021 }
14022 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14023 {
14024 // uint 64
14025 oa->write_character(to_char_type(0xCF));
14026 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14027 }
14028 }
14029 else
14030 {
14031 if (j.m_value.number_integer >= -32)
14032 {
14033 // negative fixnum
14034 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14035 }
14036 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14037 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14038 {
14039 // int 8
14040 oa->write_character(to_char_type(0xD0));
14041 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14042 }
14043 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14044 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14045 {
14046 // int 16
14047 oa->write_character(to_char_type(0xD1));
14048 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
14049 }
14050 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14051 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14052 {
14053 // int 32
14054 oa->write_character(to_char_type(0xD2));
14055 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
14056 }
14057 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14058 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14059 {
14060 // int 64
14061 oa->write_character(to_char_type(0xD3));
14062 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
14063 }
14064 }
14065 break;
14066 }
14067
14068 case value_t::number_unsigned:
14069 {
14070 if (j.m_value.number_unsigned < 128)
14071 {
14072 // positive fixnum
14073 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14074 }
14075 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14076 {
14077 // uint 8
14078 oa->write_character(to_char_type(0xCC));
14079 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14080 }
14081 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14082 {
14083 // uint 16
14084 oa->write_character(to_char_type(0xCD));
14085 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14086 }
14087 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14088 {
14089 // uint 32
14090 oa->write_character(to_char_type(0xCE));
14091 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14092 }
14093 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14094 {
14095 // uint 64
14096 oa->write_character(to_char_type(0xCF));
14097 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14098 }
14099 break;
14100 }
14101
14102 case value_t::number_float:
14103 {
14104 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
14105 break;
14106 }
14107
14108 case value_t::string:
14109 {
14110 // step 1: write control byte and the string length
14111 const auto N = j.m_value.string->size();
14112 if (N <= 31)
14113 {
14114 // fixstr
14115 write_number(static_cast<std::uint8_t>(0xA0 | N));
14116 }
14117 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14118 {
14119 // str 8
14120 oa->write_character(to_char_type(0xD9));
14121 write_number(static_cast<std::uint8_t>(N));
14122 }
14123 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14124 {
14125 // str 16
14126 oa->write_character(to_char_type(0xDA));
14127 write_number(static_cast<std::uint16_t>(N));
14128 }
14129 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14130 {
14131 // str 32
14132 oa->write_character(to_char_type(0xDB));
14133 write_number(static_cast<std::uint32_t>(N));
14134 }
14135
14136 // step 2: write the string
14137 oa->write_characters(
14138 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14139 j.m_value.string->size());
14140 break;
14141 }
14142
14143 case value_t::array:
14144 {
14145 // step 1: write control byte and the array size
14146 const auto N = j.m_value.array->size();
14147 if (N <= 15)
14148 {
14149 // fixarray
14150 write_number(static_cast<std::uint8_t>(0x90 | N));
14151 }
14152 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14153 {
14154 // array 16
14155 oa->write_character(to_char_type(0xDC));
14156 write_number(static_cast<std::uint16_t>(N));
14157 }
14158 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14159 {
14160 // array 32
14161 oa->write_character(to_char_type(0xDD));
14162 write_number(static_cast<std::uint32_t>(N));
14163 }
14164
14165 // step 2: write each element
14166 for (const auto& el : *j.m_value.array)
14167 {
14168 write_msgpack(el);
14169 }
14170 break;
14171 }
14172
14173 case value_t::binary:
14174 {
14175 // step 0: determine if the binary type has a set subtype to
14176 // determine whether or not to use the ext or fixext types
14177 const bool use_ext = j.m_value.binary->has_subtype();
14178
14179 // step 1: write control byte and the byte string length
14180 const auto N = j.m_value.binary->size();
14181 if (N <= (std::numeric_limits<std::uint8_t>::max)())
14182 {
14183 std::uint8_t output_type{};
14184 bool fixed = true;
14185 if (use_ext)
14186 {
14187 switch (N)
14188 {
14189 case 1:
14190 output_type = 0xD4; // fixext 1
14191 break;
14192 case 2:
14193 output_type = 0xD5; // fixext 2
14194 break;
14195 case 4:
14196 output_type = 0xD6; // fixext 4
14197 break;
14198 case 8:
14199 output_type = 0xD7; // fixext 8
14200 break;
14201 case 16:
14202 output_type = 0xD8; // fixext 16
14203 break;
14204 default:
14205 output_type = 0xC7; // ext 8
14206 fixed = false;
14207 break;
14208 }
14209
14210 }
14211 else
14212 {
14213 output_type = 0xC4; // bin 8
14214 fixed = false;
14215 }
14216
14217 oa->write_character(to_char_type(output_type));
14218 if (!fixed)
14219 {
14220 write_number(static_cast<std::uint8_t>(N));
14221 }
14222 }
14223 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14224 {
14225 std::uint8_t output_type = use_ext
14226 ? 0xC8 // ext 16
14227 : 0xC5; // bin 16
14228
14229 oa->write_character(to_char_type(output_type));
14230 write_number(static_cast<std::uint16_t>(N));
14231 }
14232 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14233 {
14234 std::uint8_t output_type = use_ext
14235 ? 0xC9 // ext 32
14236 : 0xC6; // bin 32
14237
14238 oa->write_character(to_char_type(output_type));
14239 write_number(static_cast<std::uint32_t>(N));
14240 }
14241
14242 // step 1.5: if this is an ext type, write the subtype
14243 if (use_ext)
14244 {
14245 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14246 }
14247
14248 // step 2: write the byte string
14249 oa->write_characters(
14250 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14251 N);
14252
14253 break;
14254 }
14255
14256 case value_t::object:
14257 {
14258 // step 1: write control byte and the object size
14259 const auto N = j.m_value.object->size();
14260 if (N <= 15)
14261 {
14262 // fixmap
14263 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
14264 }
14265 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14266 {
14267 // map 16
14268 oa->write_character(to_char_type(0xDE));
14269 write_number(static_cast<std::uint16_t>(N));
14270 }
14271 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14272 {
14273 // map 32
14274 oa->write_character(to_char_type(0xDF));
14275 write_number(static_cast<std::uint32_t>(N));
14276 }
14277
14278 // step 2: write each element
14279 for (const auto& el : *j.m_value.object)
14280 {
14281 write_msgpack(el.first);
14282 write_msgpack(el.second);
14283 }
14284 break;
14285 }
14286
14287 case value_t::discarded:
14288 default:
14289 break;
14290 }
14291 }
14292
14299 void write_ubjson(const BasicJsonType& j, const bool use_count,
14300 const bool use_type, const bool add_prefix = true)
14301 {
14302 switch (j.type())
14303 {
14304 case value_t::null:
14305 {
14306 if (add_prefix)
14307 {
14308 oa->write_character(to_char_type('Z'));
14309 }
14310 break;
14311 }
14312
14313 case value_t::boolean:
14314 {
14315 if (add_prefix)
14316 {
14317 oa->write_character(j.m_value.boolean
14318 ? to_char_type('T')
14319 : to_char_type('F'));
14320 }
14321 break;
14322 }
14323
14324 case value_t::number_integer:
14325 {
14326 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
14327 break;
14328 }
14329
14330 case value_t::number_unsigned:
14331 {
14332 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
14333 break;
14334 }
14335
14336 case value_t::number_float:
14337 {
14338 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
14339 break;
14340 }
14341
14342 case value_t::string:
14343 {
14344 if (add_prefix)
14345 {
14346 oa->write_character(to_char_type('S'));
14347 }
14348 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
14349 oa->write_characters(
14350 reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14351 j.m_value.string->size());
14352 break;
14353 }
14354
14355 case value_t::array:
14356 {
14357 if (add_prefix)
14358 {
14359 oa->write_character(to_char_type('['));
14360 }
14361
14362 bool prefix_required = true;
14363 if (use_type && !j.m_value.array->empty())
14364 {
14365 JSON_ASSERT(use_count);
14366 const CharType first_prefix = ubjson_prefix(j.front());
14367 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14368 [this, first_prefix](const BasicJsonType & v)
14369 {
14370 return ubjson_prefix(v) == first_prefix;
14371 });
14372
14373 if (same_prefix)
14374 {
14375 prefix_required = false;
14376 oa->write_character(to_char_type('$'));
14377 oa->write_character(first_prefix);
14378 }
14379 }
14380
14381 if (use_count)
14382 {
14383 oa->write_character(to_char_type('#'));
14384 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
14385 }
14386
14387 for (const auto& el : *j.m_value.array)
14388 {
14389 write_ubjson(el, use_count, use_type, prefix_required);
14390 }
14391
14392 if (!use_count)
14393 {
14394 oa->write_character(to_char_type(']'));
14395 }
14396
14397 break;
14398 }
14399
14400 case value_t::binary:
14401 {
14402 if (add_prefix)
14403 {
14404 oa->write_character(to_char_type('['));
14405 }
14406
14407 if (use_type && !j.m_value.binary->empty())
14408 {
14409 JSON_ASSERT(use_count);
14410 oa->write_character(to_char_type('$'));
14411 oa->write_character('U');
14412 }
14413
14414 if (use_count)
14415 {
14416 oa->write_character(to_char_type('#'));
14417 write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
14418 }
14419
14420 if (use_type)
14421 {
14422 oa->write_characters(
14423 reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14424 j.m_value.binary->size());
14425 }
14426 else
14427 {
14428 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14429 {
14430 oa->write_character(to_char_type('U'));
14431 oa->write_character(j.m_value.binary->data()[i]);
14432 }
14433 }
14434
14435 if (!use_count)
14436 {
14437 oa->write_character(to_char_type(']'));
14438 }
14439
14440 break;
14441 }
14442
14443 case value_t::object:
14444 {
14445 if (add_prefix)
14446 {
14447 oa->write_character(to_char_type('{'));
14448 }
14449
14450 bool prefix_required = true;
14451 if (use_type && !j.m_value.object->empty())
14452 {
14453 JSON_ASSERT(use_count);
14454 const CharType first_prefix = ubjson_prefix(j.front());
14455 const bool same_prefix = std::all_of(j.begin(), j.end(),
14456 [this, first_prefix](const BasicJsonType & v)
14457 {
14458 return ubjson_prefix(v) == first_prefix;
14459 });
14460
14461 if (same_prefix)
14462 {
14463 prefix_required = false;
14464 oa->write_character(to_char_type('$'));
14465 oa->write_character(first_prefix);
14466 }
14467 }
14468
14469 if (use_count)
14470 {
14471 oa->write_character(to_char_type('#'));
14472 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
14473 }
14474
14475 for (const auto& el : *j.m_value.object)
14476 {
14477 write_number_with_ubjson_prefix(el.first.size(), true);
14478 oa->write_characters(
14479 reinterpret_cast<const CharType*>(el.first.c_str()),
14480 el.first.size());
14481 write_ubjson(el.second, use_count, use_type, prefix_required);
14482 }
14483
14484 if (!use_count)
14485 {
14486 oa->write_character(to_char_type('}'));
14487 }
14488
14489 break;
14490 }
14491
14492 case value_t::discarded:
14493 default:
14494 break;
14495 }
14496 }
14497
14498 private:
14500 // BSON //
14502
14507 static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
14508 {
14509 const auto it = name.find(static_cast<typename string_t::value_type>(0));
14510 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14511 {
14512 JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
14513 static_cast<void>(j);
14514 }
14515
14516 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14517 }
14518
14523 const std::uint8_t element_type)
14524 {
14525 oa->write_character(to_char_type(element_type)); // boolean
14526 oa->write_characters(
14527 reinterpret_cast<const CharType*>(name.c_str()),
14528 name.size() + 1u);
14529 }
14530
14535 const bool value)
14536 {
14537 write_bson_entry_header(name, 0x08);
14538 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
14539 }
14540
14544 void write_bson_double(const string_t& name,
14545 const double value)
14546 {
14547 write_bson_entry_header(name, 0x01);
14548 write_number<double, true>(value);
14549 }
14550
14554 static std::size_t calc_bson_string_size(const string_t& value)
14555 {
14556 return sizeof(std::int32_t) + value.size() + 1ul;
14557 }
14558
14562 void write_bson_string(const string_t& name,
14563 const string_t& value)
14564 {
14565 write_bson_entry_header(name, 0x02);
14566
14567 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
14568 oa->write_characters(
14569 reinterpret_cast<const CharType*>(value.c_str()),
14570 value.size() + 1);
14571 }
14572
14576 void write_bson_null(const string_t& name)
14577 {
14578 write_bson_entry_header(name, 0x0A);
14579 }
14580
14584 static std::size_t calc_bson_integer_size(const std::int64_t value)
14585 {
14586 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
14587 ? sizeof(std::int32_t)
14588 : sizeof(std::int64_t);
14589 }
14590
14595 const std::int64_t value)
14596 {
14597 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
14598 {
14599 write_bson_entry_header(name, 0x10); // int32
14600 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
14601 }
14602 else
14603 {
14604 write_bson_entry_header(name, 0x12); // int64
14605 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
14606 }
14607 }
14608
14612 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
14613 {
14614 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14615 ? sizeof(std::int32_t)
14616 : sizeof(std::int64_t);
14617 }
14618
14623 const BasicJsonType& j)
14624 {
14625 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14626 {
14627 write_bson_entry_header(name, 0x10 /* int32 */);
14628 write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
14629 }
14630 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14631 {
14632 write_bson_entry_header(name, 0x12 /* int64 */);
14633 write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
14634 }
14635 else
14636 {
14637 JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(j.m_value.number_unsigned) + " cannot be represented by BSON as it does not fit int64", j));
14638 }
14639 }
14640
14645 const typename BasicJsonType::object_t& value)
14646 {
14647 write_bson_entry_header(name, 0x03); // object
14648 write_bson_object(value);
14649 }
14650
14654 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
14655 {
14656 std::size_t array_index = 0ul;
14657
14658 const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), std::size_t(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
14659 {
14660 return result + calc_bson_element_size(std::to_string(array_index++), el);
14661 });
14662
14663 return sizeof(std::int32_t) + embedded_document_size + 1ul;
14664 }
14665
14669 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
14670 {
14671 return sizeof(std::int32_t) + value.size() + 1ul;
14672 }
14673
14677 void write_bson_array(const string_t& name,
14678 const typename BasicJsonType::array_t& value)
14679 {
14680 write_bson_entry_header(name, 0x04); // array
14681 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
14682
14683 std::size_t array_index = 0ul;
14684
14685 for (const auto& el : value)
14686 {
14687 write_bson_element(std::to_string(array_index++), el);
14688 }
14689
14690 oa->write_character(to_char_type(0x00));
14691 }
14692
14696 void write_bson_binary(const string_t& name,
14697 const binary_t& value)
14698 {
14699 write_bson_entry_header(name, 0x05);
14700
14701 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
14702 write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : std::uint8_t(0x00));
14703
14704 oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
14705 }
14706
14711 static std::size_t calc_bson_element_size(const string_t& name,
14712 const BasicJsonType& j)
14713 {
14714 const auto header_size = calc_bson_entry_header_size(name, j);
14715 switch (j.type())
14716 {
14717 case value_t::object:
14718 return header_size + calc_bson_object_size(*j.m_value.object);
14719
14720 case value_t::array:
14721 return header_size + calc_bson_array_size(*j.m_value.array);
14722
14723 case value_t::binary:
14724 return header_size + calc_bson_binary_size(*j.m_value.binary);
14725
14726 case value_t::boolean:
14727 return header_size + 1ul;
14728
14729 case value_t::number_float:
14730 return header_size + 8ul;
14731
14732 case value_t::number_integer:
14733 return header_size + calc_bson_integer_size(j.m_value.number_integer);
14734
14735 case value_t::number_unsigned:
14736 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
14737
14738 case value_t::string:
14739 return header_size + calc_bson_string_size(*j.m_value.string);
14740
14741 case value_t::null:
14742 return header_size + 0ul;
14743
14744 // LCOV_EXCL_START
14745 case value_t::discarded:
14746 default:
14747 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14748 return 0ul;
14749 // LCOV_EXCL_STOP
14750 }
14751 }
14752
14760 const BasicJsonType& j)
14761 {
14762 switch (j.type())
14763 {
14764 case value_t::object:
14765 return write_bson_object_entry(name, *j.m_value.object);
14766
14767 case value_t::array:
14768 return write_bson_array(name, *j.m_value.array);
14769
14770 case value_t::binary:
14771 return write_bson_binary(name, *j.m_value.binary);
14772
14773 case value_t::boolean:
14774 return write_bson_boolean(name, j.m_value.boolean);
14775
14776 case value_t::number_float:
14777 return write_bson_double(name, j.m_value.number_float);
14778
14779 case value_t::number_integer:
14780 return write_bson_integer(name, j.m_value.number_integer);
14781
14782 case value_t::number_unsigned:
14783 return write_bson_unsigned(name, j);
14784
14785 case value_t::string:
14786 return write_bson_string(name, *j.m_value.string);
14787
14788 case value_t::null:
14789 return write_bson_null(name);
14790
14791 // LCOV_EXCL_START
14792 case value_t::discarded:
14793 default:
14794 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
14795 return;
14796 // LCOV_EXCL_STOP
14797 }
14798 }
14799
14806 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
14807 {
14808 std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
14809 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
14810 {
14811 return result += calc_bson_element_size(el.first, el.second);
14812 });
14813
14814 return sizeof(std::int32_t) + document_size + 1ul;
14815 }
14816
14821 void write_bson_object(const typename BasicJsonType::object_t& value)
14822 {
14823 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
14824
14825 for (const auto& el : value)
14826 {
14827 write_bson_element(el.first, el.second);
14828 }
14829
14830 oa->write_character(to_char_type(0x00));
14831 }
14832
14834 // CBOR //
14836
14837 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
14838 {
14839 return to_char_type(0xFA); // Single-Precision Float
14840 }
14841
14842 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
14843 {
14844 return to_char_type(0xFB); // Double-Precision Float
14845 }
14846
14848 // MsgPack //
14850
14851 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
14852 {
14853 return to_char_type(0xCA); // float 32
14854 }
14855
14856 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
14857 {
14858 return to_char_type(0xCB); // float 64
14859 }
14860
14862 // UBJSON //
14864
14865 // UBJSON: write number (floating point)
14866 template<typename NumberType, typename std::enable_if<
14867 std::is_floating_point<NumberType>::value, int>::type = 0>
14868 void write_number_with_ubjson_prefix(const NumberType n,
14869 const bool add_prefix)
14870 {
14871 if (add_prefix)
14872 {
14873 oa->write_character(get_ubjson_float_prefix(n));
14874 }
14875 write_number(n);
14876 }
14877
14878 // UBJSON: write number (unsigned integer)
14879 template<typename NumberType, typename std::enable_if<
14880 std::is_unsigned<NumberType>::value, int>::type = 0>
14881 void write_number_with_ubjson_prefix(const NumberType n,
14882 const bool add_prefix)
14883 {
14884 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
14885 {
14886 if (add_prefix)
14887 {
14888 oa->write_character(to_char_type('i')); // int8
14889 }
14890 write_number(static_cast<std::uint8_t>(n));
14891 }
14892 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
14893 {
14894 if (add_prefix)
14895 {
14896 oa->write_character(to_char_type('U')); // uint8
14897 }
14898 write_number(static_cast<std::uint8_t>(n));
14899 }
14900 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
14901 {
14902 if (add_prefix)
14903 {
14904 oa->write_character(to_char_type('I')); // int16
14905 }
14906 write_number(static_cast<std::int16_t>(n));
14907 }
14908 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14909 {
14910 if (add_prefix)
14911 {
14912 oa->write_character(to_char_type('l')); // int32
14913 }
14914 write_number(static_cast<std::int32_t>(n));
14915 }
14916 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14917 {
14918 if (add_prefix)
14919 {
14920 oa->write_character(to_char_type('L')); // int64
14921 }
14922 write_number(static_cast<std::int64_t>(n));
14923 }
14924 else
14925 {
14926 if (add_prefix)
14927 {
14928 oa->write_character(to_char_type('H')); // high-precision number
14929 }
14930
14931 const auto number = BasicJsonType(n).dump();
14932 write_number_with_ubjson_prefix(number.size(), true);
14933 for (std::size_t i = 0; i < number.size(); ++i)
14934 {
14935 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
14936 }
14937 }
14938 }
14939
14940 // UBJSON: write number (signed integer)
14941 template < typename NumberType, typename std::enable_if <
14942 std::is_signed<NumberType>::value&&
14943 !std::is_floating_point<NumberType>::value, int >::type = 0 >
14944 void write_number_with_ubjson_prefix(const NumberType n,
14945 const bool add_prefix)
14946 {
14947 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
14948 {
14949 if (add_prefix)
14950 {
14951 oa->write_character(to_char_type('i')); // int8
14952 }
14953 write_number(static_cast<std::int8_t>(n));
14954 }
14955 else if (static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint8_t>::max)()))
14956 {
14957 if (add_prefix)
14958 {
14959 oa->write_character(to_char_type('U')); // uint8
14960 }
14961 write_number(static_cast<std::uint8_t>(n));
14962 }
14963 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
14964 {
14965 if (add_prefix)
14966 {
14967 oa->write_character(to_char_type('I')); // int16
14968 }
14969 write_number(static_cast<std::int16_t>(n));
14970 }
14971 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
14972 {
14973 if (add_prefix)
14974 {
14975 oa->write_character(to_char_type('l')); // int32
14976 }
14977 write_number(static_cast<std::int32_t>(n));
14978 }
14979 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
14980 {
14981 if (add_prefix)
14982 {
14983 oa->write_character(to_char_type('L')); // int64
14984 }
14985 write_number(static_cast<std::int64_t>(n));
14986 }
14987 // LCOV_EXCL_START
14988 else
14989 {
14990 if (add_prefix)
14991 {
14992 oa->write_character(to_char_type('H')); // high-precision number
14993 }
14994
14995 const auto number = BasicJsonType(n).dump();
14996 write_number_with_ubjson_prefix(number.size(), true);
14997 for (std::size_t i = 0; i < number.size(); ++i)
14998 {
14999 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15000 }
15001 }
15002 // LCOV_EXCL_STOP
15003 }
15004
15008 CharType ubjson_prefix(const BasicJsonType& j) const noexcept
15009 {
15010 switch (j.type())
15011 {
15012 case value_t::null:
15013 return 'Z';
15014
15015 case value_t::boolean:
15016 return j.m_value.boolean ? 'T' : 'F';
15017
15018 case value_t::number_integer:
15019 {
15020 if ((std::numeric_limits<std::int8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
15021 {
15022 return 'i';
15023 }
15024 if ((std::numeric_limits<std::uint8_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
15025 {
15026 return 'U';
15027 }
15028 if ((std::numeric_limits<std::int16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
15029 {
15030 return 'I';
15031 }
15032 if ((std::numeric_limits<std::int32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
15033 {
15034 return 'l';
15035 }
15036 if ((std::numeric_limits<std::int64_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
15037 {
15038 return 'L';
15039 }
15040 // anything else is treated as high-precision number
15041 return 'H'; // LCOV_EXCL_LINE
15042 }
15043
15044 case value_t::number_unsigned:
15045 {
15046 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15047 {
15048 return 'i';
15049 }
15050 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15051 {
15052 return 'U';
15053 }
15054 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15055 {
15056 return 'I';
15057 }
15058 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15059 {
15060 return 'l';
15061 }
15062 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15063 {
15064 return 'L';
15065 }
15066 // anything else is treated as high-precision number
15067 return 'H'; // LCOV_EXCL_LINE
15068 }
15069
15070 case value_t::number_float:
15071 return get_ubjson_float_prefix(j.m_value.number_float);
15072
15073 case value_t::string:
15074 return 'S';
15075
15076 case value_t::array: // fallthrough
15077 case value_t::binary:
15078 return '[';
15079
15080 case value_t::object:
15081 return '{';
15082
15083 case value_t::discarded:
15084 default: // discarded values
15085 return 'N';
15086 }
15087 }
15088
15089 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15090 {
15091 return 'd'; // float 32
15092 }
15093
15094 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15095 {
15096 return 'D'; // float 64
15097 }
15098
15100 // Utility functions //
15102
15103 /*
15104 @brief write a number to output input
15105 @param[in] n number of type @a NumberType
15106 @tparam NumberType the type of the number
15107 @tparam OutputIsLittleEndian Set to true if output data is
15108 required to be little endian
15109
15110 @note This function needs to respect the system's endianess, because bytes
15111 in CBOR, MessagePack, and UBJSON are stored in network order (big
15112 endian) and therefore need reordering on little endian systems.
15113 */
15114 template<typename NumberType, bool OutputIsLittleEndian = false>
15115 void write_number(const NumberType n)
15116 {
15117 // step 1: write number to array of length NumberType
15118 std::array<CharType, sizeof(NumberType)> vec{};
15119 std::memcpy(vec.data(), &n, sizeof(NumberType));
15120
15121 // step 2: write array to output (with possible reordering)
15122 if (is_little_endian != OutputIsLittleEndian)
15123 {
15124 // reverse byte order prior to conversion if necessary
15125 std::reverse(vec.begin(), vec.end());
15126 }
15127
15128 oa->write_characters(vec.data(), sizeof(NumberType));
15129 }
15130
15132 {
15133#ifdef __GNUC__
15134#pragma GCC diagnostic push
15135#pragma GCC diagnostic ignored "-Wfloat-equal"
15136#endif
15137 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
15138 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
15139 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
15140 {
15141 oa->write_character(format == detail::input_format_t::cbor
15142 ? get_cbor_float_prefix(static_cast<float>(n))
15143 : get_msgpack_float_prefix(static_cast<float>(n)));
15144 write_number(static_cast<float>(n));
15145 }
15146 else
15147 {
15148 oa->write_character(format == detail::input_format_t::cbor
15149 ? get_cbor_float_prefix(n)
15150 : get_msgpack_float_prefix(n));
15151 write_number(n);
15152 }
15153#ifdef __GNUC__
15154#pragma GCC diagnostic pop
15155#endif
15156 }
15157
15158 public:
15159 // The following to_char_type functions are implement the conversion
15160 // between uint8_t and CharType. In case CharType is not unsigned,
15161 // such a conversion is required to allow values greater than 128.
15162 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
15163 template < typename C = CharType,
15164 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
15165 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15166 {
15167 return *reinterpret_cast<char*>(&x);
15168 }
15169
15170 template < typename C = CharType,
15171 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
15172 static CharType to_char_type(std::uint8_t x) noexcept
15173 {
15174 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
15175 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
15176 CharType result;
15177 std::memcpy(&result, &x, sizeof(x));
15178 return result;
15179 }
15180
15181 template<typename C = CharType,
15183 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15184 {
15185 return x;
15186 }
15187
15188 template < typename InputCharType, typename C = CharType,
15189 enable_if_t <
15190 std::is_signed<C>::value &&
15191 std::is_signed<char>::value &&
15192 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
15193 > * = nullptr >
15194 static constexpr CharType to_char_type(InputCharType x) noexcept
15195 {
15196 return x;
15197 }
15198
15199 private:
15201 const bool is_little_endian = little_endianess();
15202
15205};
15206} // namespace detail
15207} // namespace nlohmann
15208
15209// #include <nlohmann/detail/output/output_adapters.hpp>
15210
15211// #include <nlohmann/detail/output/serializer.hpp>
15212
15213
15214#include <algorithm> // reverse, remove, fill, find, none_of
15215#include <array> // array
15216#include <clocale> // localeconv, lconv
15217#include <cmath> // labs, isfinite, isnan, signbit
15218#include <cstddef> // size_t, ptrdiff_t
15219#include <cstdint> // uint8_t
15220#include <cstdio> // snprintf
15221#include <limits> // numeric_limits
15222#include <string> // string, char_traits
15223#include <type_traits> // is_same
15224#include <utility> // move
15225
15226// #include <nlohmann/detail/conversions/to_chars.hpp>
15227
15228
15229#include <array> // array
15230#include <cmath> // signbit, isfinite
15231#include <cstdint> // intN_t, uintN_t
15232#include <cstring> // memcpy, memmove
15233#include <limits> // numeric_limits
15234#include <type_traits> // conditional
15235
15236// #include <nlohmann/detail/macro_scope.hpp>
15237
15238
15239namespace nlohmann
15240{
15241namespace detail
15242{
15243
15263namespace dtoa_impl
15264{
15265
15266template<typename Target, typename Source>
15267Target reinterpret_bits(const Source source)
15268{
15269 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
15270
15271 Target target;
15272 std::memcpy(&target, &source, sizeof(Source));
15273 return target;
15274}
15275
15276struct diyfp // f * 2^e
15277{
15278 static constexpr int kPrecision = 64; // = q
15279
15280 std::uint64_t f = 0;
15281 int e = 0;
15282
15283 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
15284
15289 static diyfp sub(const diyfp& x, const diyfp& y) noexcept
15290 {
15291 JSON_ASSERT(x.e == y.e);
15292 JSON_ASSERT(x.f >= y.f);
15293
15294 return {x.f - y.f, x.e};
15295 }
15296
15301 static diyfp mul(const diyfp& x, const diyfp& y) noexcept
15302 {
15303 static_assert(kPrecision == 64, "internal error");
15304
15305 // Computes:
15306 // f = round((x.f * y.f) / 2^q)
15307 // e = x.e + y.e + q
15308
15309 // Emulate the 64-bit * 64-bit multiplication:
15310 //
15311 // p = u * v
15312 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15313 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
15314 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
15315 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
15316 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
15317 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
15318 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
15319 //
15320 // (Since Q might be larger than 2^32 - 1)
15321 //
15322 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15323 //
15324 // (Q_hi + H does not overflow a 64-bit int)
15325 //
15326 // = p_lo + 2^64 p_hi
15327
15328 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15329 const std::uint64_t u_hi = x.f >> 32u;
15330 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15331 const std::uint64_t v_hi = y.f >> 32u;
15332
15333 const std::uint64_t p0 = u_lo * v_lo;
15334 const std::uint64_t p1 = u_lo * v_hi;
15335 const std::uint64_t p2 = u_hi * v_lo;
15336 const std::uint64_t p3 = u_hi * v_hi;
15337
15338 const std::uint64_t p0_hi = p0 >> 32u;
15339 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15340 const std::uint64_t p1_hi = p1 >> 32u;
15341 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15342 const std::uint64_t p2_hi = p2 >> 32u;
15343
15344 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15345
15346 // The full product might now be computed as
15347 //
15348 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
15349 // p_lo = p0_lo + (Q << 32)
15350 //
15351 // But in this particular case here, the full p_lo is not required.
15352 // Effectively we only need to add the highest bit in p_lo to p_hi (and
15353 // Q_hi + 1 does not overflow).
15354
15355 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
15356
15357 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15358
15359 return {h, x.e + y.e + 64};
15360 }
15361
15366 static diyfp normalize(diyfp x) noexcept
15367 {
15368 JSON_ASSERT(x.f != 0);
15369
15370 while ((x.f >> 63u) == 0)
15371 {
15372 x.f <<= 1u;
15373 x.e--;
15374 }
15375
15376 return x;
15377 }
15378
15383 static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
15384 {
15385 const int delta = x.e - target_exponent;
15386
15387 JSON_ASSERT(delta >= 0);
15388 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
15389
15390 return {x.f << delta, target_exponent};
15391 }
15392};
15393
15400
15407template<typename FloatType>
15409{
15410 JSON_ASSERT(std::isfinite(value));
15411 JSON_ASSERT(value > 0);
15412
15413 // Convert the IEEE representation into a diyfp.
15414 //
15415 // If v is denormal:
15416 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
15417 // If v is normalized:
15418 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
15419
15420 static_assert(std::numeric_limits<FloatType>::is_iec559,
15421 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
15422
15423 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
15424 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
15425 constexpr int kMinExp = 1 - kBias;
15426 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
15427
15428 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
15429
15430 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
15431 const std::uint64_t E = bits >> (kPrecision - 1);
15432 const std::uint64_t F = bits & (kHiddenBit - 1);
15433
15434 const bool is_denormal = E == 0;
15435 const diyfp v = is_denormal
15436 ? diyfp(F, kMinExp)
15437 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
15438
15439 // Compute the boundaries m- and m+ of the floating-point value
15440 // v = f * 2^e.
15441 //
15442 // Determine v- and v+, the floating-point predecessor and successor if v,
15443 // respectively.
15444 //
15445 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
15446 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
15447 //
15448 // v+ = v + 2^e
15449 //
15450 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
15451 // between m- and m+ round to v, regardless of how the input rounding
15452 // algorithm breaks ties.
15453 //
15454 // ---+-------------+-------------+-------------+-------------+--- (A)
15455 // v- m- v m+ v+
15456 //
15457 // -----------------+------+------+-------------+-------------+--- (B)
15458 // v- m- v m+ v+
15459
15460 const bool lower_boundary_is_closer = F == 0 && E > 1;
15461 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
15462 const diyfp m_minus = lower_boundary_is_closer
15463 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
15464 : diyfp(2 * v.f - 1, v.e - 1); // (A)
15465
15466 // Determine the normalized w+ = m+.
15467 const diyfp w_plus = diyfp::normalize(m_plus);
15468
15469 // Determine w- = m- such that e_(w-) = e_(w+).
15470 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
15471
15472 return {diyfp::normalize(v), w_minus, w_plus};
15473}
15474
15475// Given normalized diyfp w, Grisu needs to find a (normalized) cached
15476// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
15477// within a certain range [alpha, gamma] (Definition 3.2 from [1])
15478//
15479// alpha <= e = e_c + e_w + q <= gamma
15480//
15481// or
15482//
15483// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
15484// <= f_c * f_w * 2^gamma
15485//
15486// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
15487//
15488// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
15489//
15490// or
15491//
15492// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
15493//
15494// The choice of (alpha,gamma) determines the size of the table and the form of
15495// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
15496// in practice:
15497//
15498// The idea is to cut the number c * w = f * 2^e into two parts, which can be
15499// processed independently: An integral part p1, and a fractional part p2:
15500//
15501// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
15502// = (f div 2^-e) + (f mod 2^-e) * 2^e
15503// = p1 + p2 * 2^e
15504//
15505// The conversion of p1 into decimal form requires a series of divisions and
15506// modulos by (a power of) 10. These operations are faster for 32-bit than for
15507// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
15508// achieved by choosing
15509//
15510// -e >= 32 or e <= -32 := gamma
15511//
15512// In order to convert the fractional part
15513//
15514// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
15515//
15516// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
15517// d[-i] are extracted in order:
15518//
15519// (10 * p2) div 2^-e = d[-1]
15520// (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
15521//
15522// The multiplication by 10 must not overflow. It is sufficient to choose
15523//
15524// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
15525//
15526// Since p2 = f mod 2^-e < 2^-e,
15527//
15528// -e <= 60 or e >= -60 := alpha
15529
15530constexpr int kAlpha = -60;
15531constexpr int kGamma = -32;
15532
15533struct cached_power // c = f * 2^e ~= 10^k
15534{
15535 std::uint64_t f;
15536 int e;
15537 int k;
15538};
15539
15548{
15549 // Now
15550 //
15551 // alpha <= e_c + e + q <= gamma (1)
15552 // ==> f_c * 2^alpha <= c * 2^e * 2^q
15553 //
15554 // and since the c's are normalized, 2^(q-1) <= f_c,
15555 //
15556 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
15557 // ==> 2^(alpha - e - 1) <= c
15558 //
15559 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
15560 //
15561 // k = ceil( log_10( 2^(alpha - e - 1) ) )
15562 // = ceil( (alpha - e - 1) * log_10(2) )
15563 //
15564 // From the paper:
15565 // "In theory the result of the procedure could be wrong since c is rounded,
15566 // and the computation itself is approximated [...]. In practice, however,
15567 // this simple function is sufficient."
15568 //
15569 // For IEEE double precision floating-point numbers converted into
15570 // normalized diyfp's w = f * 2^e, with q = 64,
15571 //
15572 // e >= -1022 (min IEEE exponent)
15573 // -52 (p - 1)
15574 // -52 (p - 1, possibly normalize denormal IEEE numbers)
15575 // -11 (normalize the diyfp)
15576 // = -1137
15577 //
15578 // and
15579 //
15580 // e <= +1023 (max IEEE exponent)
15581 // -52 (p - 1)
15582 // -11 (normalize the diyfp)
15583 // = 960
15584 //
15585 // This binary exponent range [-1137,960] results in a decimal exponent
15586 // range [-307,324]. One does not need to store a cached power for each
15587 // k in this range. For each such k it suffices to find a cached power
15588 // such that the exponent of the product lies in [alpha,gamma].
15589 // This implies that the difference of the decimal exponents of adjacent
15590 // table entries must be less than or equal to
15591 //
15592 // floor( (gamma - alpha) * log_10(2) ) = 8.
15593 //
15594 // (A smaller distance gamma-alpha would require a larger table.)
15595
15596 // NB:
15597 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
15598
15599 constexpr int kCachedPowersMinDecExp = -300;
15600 constexpr int kCachedPowersDecStep = 8;
15601
15602 static constexpr std::array<cached_power, 79> kCachedPowers =
15603 {
15604 {
15605 { 0xAB70FE17C79AC6CA, -1060, -300 },
15606 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
15607 { 0xBE5691EF416BD60C, -1007, -284 },
15608 { 0x8DD01FAD907FFC3C, -980, -276 },
15609 { 0xD3515C2831559A83, -954, -268 },
15610 { 0x9D71AC8FADA6C9B5, -927, -260 },
15611 { 0xEA9C227723EE8BCB, -901, -252 },
15612 { 0xAECC49914078536D, -874, -244 },
15613 { 0x823C12795DB6CE57, -847, -236 },
15614 { 0xC21094364DFB5637, -821, -228 },
15615 { 0x9096EA6F3848984F, -794, -220 },
15616 { 0xD77485CB25823AC7, -768, -212 },
15617 { 0xA086CFCD97BF97F4, -741, -204 },
15618 { 0xEF340A98172AACE5, -715, -196 },
15619 { 0xB23867FB2A35B28E, -688, -188 },
15620 { 0x84C8D4DFD2C63F3B, -661, -180 },
15621 { 0xC5DD44271AD3CDBA, -635, -172 },
15622 { 0x936B9FCEBB25C996, -608, -164 },
15623 { 0xDBAC6C247D62A584, -582, -156 },
15624 { 0xA3AB66580D5FDAF6, -555, -148 },
15625 { 0xF3E2F893DEC3F126, -529, -140 },
15626 { 0xB5B5ADA8AAFF80B8, -502, -132 },
15627 { 0x87625F056C7C4A8B, -475, -124 },
15628 { 0xC9BCFF6034C13053, -449, -116 },
15629 { 0x964E858C91BA2655, -422, -108 },
15630 { 0xDFF9772470297EBD, -396, -100 },
15631 { 0xA6DFBD9FB8E5B88F, -369, -92 },
15632 { 0xF8A95FCF88747D94, -343, -84 },
15633 { 0xB94470938FA89BCF, -316, -76 },
15634 { 0x8A08F0F8BF0F156B, -289, -68 },
15635 { 0xCDB02555653131B6, -263, -60 },
15636 { 0x993FE2C6D07B7FAC, -236, -52 },
15637 { 0xE45C10C42A2B3B06, -210, -44 },
15638 { 0xAA242499697392D3, -183, -36 },
15639 { 0xFD87B5F28300CA0E, -157, -28 },
15640 { 0xBCE5086492111AEB, -130, -20 },
15641 { 0x8CBCCC096F5088CC, -103, -12 },
15642 { 0xD1B71758E219652C, -77, -4 },
15643 { 0x9C40000000000000, -50, 4 },
15644 { 0xE8D4A51000000000, -24, 12 },
15645 { 0xAD78EBC5AC620000, 3, 20 },
15646 { 0x813F3978F8940984, 30, 28 },
15647 { 0xC097CE7BC90715B3, 56, 36 },
15648 { 0x8F7E32CE7BEA5C70, 83, 44 },
15649 { 0xD5D238A4ABE98068, 109, 52 },
15650 { 0x9F4F2726179A2245, 136, 60 },
15651 { 0xED63A231D4C4FB27, 162, 68 },
15652 { 0xB0DE65388CC8ADA8, 189, 76 },
15653 { 0x83C7088E1AAB65DB, 216, 84 },
15654 { 0xC45D1DF942711D9A, 242, 92 },
15655 { 0x924D692CA61BE758, 269, 100 },
15656 { 0xDA01EE641A708DEA, 295, 108 },
15657 { 0xA26DA3999AEF774A, 322, 116 },
15658 { 0xF209787BB47D6B85, 348, 124 },
15659 { 0xB454E4A179DD1877, 375, 132 },
15660 { 0x865B86925B9BC5C2, 402, 140 },
15661 { 0xC83553C5C8965D3D, 428, 148 },
15662 { 0x952AB45CFA97A0B3, 455, 156 },
15663 { 0xDE469FBD99A05FE3, 481, 164 },
15664 { 0xA59BC234DB398C25, 508, 172 },
15665 { 0xF6C69A72A3989F5C, 534, 180 },
15666 { 0xB7DCBF5354E9BECE, 561, 188 },
15667 { 0x88FCF317F22241E2, 588, 196 },
15668 { 0xCC20CE9BD35C78A5, 614, 204 },
15669 { 0x98165AF37B2153DF, 641, 212 },
15670 { 0xE2A0B5DC971F303A, 667, 220 },
15671 { 0xA8D9D1535CE3B396, 694, 228 },
15672 { 0xFB9B7CD9A4A7443C, 720, 236 },
15673 { 0xBB764C4CA7A44410, 747, 244 },
15674 { 0x8BAB8EEFB6409C1A, 774, 252 },
15675 { 0xD01FEF10A657842C, 800, 260 },
15676 { 0x9B10A4E5E9913129, 827, 268 },
15677 { 0xE7109BFBA19C0C9D, 853, 276 },
15678 { 0xAC2820D9623BF429, 880, 284 },
15679 { 0x80444B5E7AA7CF85, 907, 292 },
15680 { 0xBF21E44003ACDD2D, 933, 300 },
15681 { 0x8E679C2F5E44FF8F, 960, 308 },
15682 { 0xD433179D9C8CB841, 986, 316 },
15683 { 0x9E19DB92B4E31BA9, 1013, 324 },
15684 }
15685 };
15686
15687 // This computation gives exactly the same results for k as
15688 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
15689 // for |e| <= 1500, but doesn't require floating-point operations.
15690 // NB: log_10(2) ~= 78913 / 2^18
15691 JSON_ASSERT(e >= -1500);
15692 JSON_ASSERT(e <= 1500);
15693 const int f = kAlpha - e - 1;
15694 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
15695
15696 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
15697 JSON_ASSERT(index >= 0);
15698 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
15699
15700 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
15701 JSON_ASSERT(kAlpha <= cached.e + e + 64);
15702 JSON_ASSERT(kGamma >= cached.e + e + 64);
15703
15704 return cached;
15705}
15706
15711inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
15712{
15713 // LCOV_EXCL_START
15714 if (n >= 1000000000)
15715 {
15716 pow10 = 1000000000;
15717 return 10;
15718 }
15719 // LCOV_EXCL_STOP
15720 if (n >= 100000000)
15721 {
15722 pow10 = 100000000;
15723 return 9;
15724 }
15725 if (n >= 10000000)
15726 {
15727 pow10 = 10000000;
15728 return 8;
15729 }
15730 if (n >= 1000000)
15731 {
15732 pow10 = 1000000;
15733 return 7;
15734 }
15735 if (n >= 100000)
15736 {
15737 pow10 = 100000;
15738 return 6;
15739 }
15740 if (n >= 10000)
15741 {
15742 pow10 = 10000;
15743 return 5;
15744 }
15745 if (n >= 1000)
15746 {
15747 pow10 = 1000;
15748 return 4;
15749 }
15750 if (n >= 100)
15751 {
15752 pow10 = 100;
15753 return 3;
15754 }
15755 if (n >= 10)
15756 {
15757 pow10 = 10;
15758 return 2;
15759 }
15760
15761 pow10 = 1;
15762 return 1;
15763}
15764
15765inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
15766 std::uint64_t rest, std::uint64_t ten_k)
15767{
15768 JSON_ASSERT(len >= 1);
15769 JSON_ASSERT(dist <= delta);
15770 JSON_ASSERT(rest <= delta);
15771 JSON_ASSERT(ten_k > 0);
15772
15773 // <--------------------------- delta ---->
15774 // <---- dist --------->
15775 // --------------[------------------+-------------------]--------------
15776 // M- w M+
15777 //
15778 // ten_k
15779 // <------>
15780 // <---- rest ---->
15781 // --------------[------------------+----+--------------]--------------
15782 // w V
15783 // = buf * 10^k
15784 //
15785 // ten_k represents a unit-in-the-last-place in the decimal representation
15786 // stored in buf.
15787 // Decrement buf by ten_k while this takes buf closer to w.
15788
15789 // The tests are written in this order to avoid overflow in unsigned
15790 // integer arithmetic.
15791
15792 while (rest < dist
15793 && delta - rest >= ten_k
15794 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
15795 {
15796 JSON_ASSERT(buf[len - 1] != '0');
15797 buf[len - 1]--;
15798 rest += ten_k;
15799 }
15800}
15801
15806inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
15807 diyfp M_minus, diyfp w, diyfp M_plus)
15808{
15809 static_assert(kAlpha >= -60, "internal error");
15810 static_assert(kGamma <= -32, "internal error");
15811
15812 // Generates the digits (and the exponent) of a decimal floating-point
15813 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
15814 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
15815 //
15816 // <--------------------------- delta ---->
15817 // <---- dist --------->
15818 // --------------[------------------+-------------------]--------------
15819 // M- w M+
15820 //
15821 // Grisu2 generates the digits of M+ from left to right and stops as soon as
15822 // V is in [M-,M+].
15823
15824 JSON_ASSERT(M_plus.e >= kAlpha);
15825 JSON_ASSERT(M_plus.e <= kGamma);
15826
15827 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
15828 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
15829
15830 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
15831 //
15832 // M+ = f * 2^e
15833 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
15834 // = ((p1 ) * 2^-e + (p2 )) * 2^e
15835 // = p1 + p2 * 2^e
15836
15837 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
15838
15839 auto p1 = static_cast<std::uint32_t>(M_plus.f >> -one.e); // p1 = f div 2^-e (Since -e >= 32, p1 fits into a 32-bit int.)
15840 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
15841
15842 // 1)
15843 //
15844 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
15845
15846 JSON_ASSERT(p1 > 0);
15847
15848 std::uint32_t pow10{};
15849 const int k = find_largest_pow10(p1, pow10);
15850
15851 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
15852 //
15853 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
15854 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
15855 //
15856 // M+ = p1 + p2 * 2^e
15857 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
15858 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
15859 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
15860 //
15861 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
15862 //
15863 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
15864 //
15865 // but stop as soon as
15866 //
15867 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
15868
15869 int n = k;
15870 while (n > 0)
15871 {
15872 // Invariants:
15873 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
15874 // pow10 = 10^(n-1) <= p1 < 10^n
15875 //
15876 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
15877 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
15878 //
15879 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
15880 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
15881 //
15882 JSON_ASSERT(d <= 9);
15883 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15884 //
15885 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
15886 //
15887 p1 = r;
15888 n--;
15889 //
15890 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
15891 // pow10 = 10^n
15892 //
15893
15894 // Now check if enough digits have been generated.
15895 // Compute
15896 //
15897 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
15898 //
15899 // Note:
15900 // Since rest and delta share the same exponent e, it suffices to
15901 // compare the significands.
15902 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
15903 if (rest <= delta)
15904 {
15905 // V = buffer * 10^n, with M- <= V <= M+.
15906
15907 decimal_exponent += n;
15908
15909 // We may now just stop. But instead look if the buffer could be
15910 // decremented to bring V closer to w.
15911 //
15912 // pow10 = 10^n is now 1 ulp in the decimal representation V.
15913 // The rounding procedure works with diyfp's with an implicit
15914 // exponent of e.
15915 //
15916 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
15917 //
15918 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
15919 grisu2_round(buffer, length, dist, delta, rest, ten_n);
15920
15921 return;
15922 }
15923
15924 pow10 /= 10;
15925 //
15926 // pow10 = 10^(n-1) <= p1 < 10^n
15927 // Invariants restored.
15928 }
15929
15930 // 2)
15931 //
15932 // The digits of the integral part have been generated:
15933 //
15934 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
15935 // = buffer + p2 * 2^e
15936 //
15937 // Now generate the digits of the fractional part p2 * 2^e.
15938 //
15939 // Note:
15940 // No decimal point is generated: the exponent is adjusted instead.
15941 //
15942 // p2 actually represents the fraction
15943 //
15944 // p2 * 2^e
15945 // = p2 / 2^-e
15946 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
15947 //
15948 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
15949 //
15950 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
15951 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
15952 //
15953 // using
15954 //
15955 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
15956 // = ( d) * 2^-e + ( r)
15957 //
15958 // or
15959 // 10^m * p2 * 2^e = d + r * 2^e
15960 //
15961 // i.e.
15962 //
15963 // M+ = buffer + p2 * 2^e
15964 // = buffer + 10^-m * (d + r * 2^e)
15965 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
15966 //
15967 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
15968
15969 JSON_ASSERT(p2 > delta);
15970
15971 int m = 0;
15972 for (;;)
15973 {
15974 // Invariant:
15975 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
15976 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
15977 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
15978 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
15979 //
15980 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
15981 p2 *= 10;
15982 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
15983 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
15984 //
15985 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
15986 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
15987 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
15988 //
15989 JSON_ASSERT(d <= 9);
15990 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
15991 //
15992 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
15993 //
15994 p2 = r;
15995 m++;
15996 //
15997 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
15998 // Invariant restored.
15999
16000 // Check if enough digits have been generated.
16001 //
16002 // 10^-m * p2 * 2^e <= delta * 2^e
16003 // p2 * 2^e <= 10^m * delta * 2^e
16004 // p2 <= 10^m * delta
16005 delta *= 10;
16006 dist *= 10;
16007 if (p2 <= delta)
16008 {
16009 break;
16010 }
16011 }
16012
16013 // V = buffer * 10^-m, with M- <= V <= M+.
16014
16015 decimal_exponent -= m;
16016
16017 // 1 ulp in the decimal representation is now 10^-m.
16018 // Since delta and dist are now scaled by 10^m, we need to do the
16019 // same with ulp in order to keep the units in sync.
16020 //
16021 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16022 //
16023 const std::uint64_t ten_m = one.f;
16024 grisu2_round(buffer, length, dist, delta, p2, ten_m);
16025
16026 // By construction this algorithm generates the shortest possible decimal
16027 // number (Loitsch, Theorem 6.2) which rounds back to w.
16028 // For an input number of precision p, at least
16029 //
16030 // N = 1 + ceil(p * log_10(2))
16031 //
16032 // decimal digits are sufficient to identify all binary floating-point
16033 // numbers (Matula, "In-and-Out conversions").
16034 // This implies that the algorithm does not produce more than N decimal
16035 // digits.
16036 //
16037 // N = 17 for p = 53 (IEEE double precision)
16038 // N = 9 for p = 24 (IEEE single precision)
16039}
16040
16047inline void grisu2(char* buf, int& len, int& decimal_exponent,
16048 diyfp m_minus, diyfp v, diyfp m_plus)
16049{
16050 JSON_ASSERT(m_plus.e == m_minus.e);
16051 JSON_ASSERT(m_plus.e == v.e);
16052
16053 // --------(-----------------------+-----------------------)-------- (A)
16054 // m- v m+
16055 //
16056 // --------------------(-----------+-----------------------)-------- (B)
16057 // m- v m+
16058 //
16059 // First scale v (and m- and m+) such that the exponent is in the range
16060 // [alpha, gamma].
16061
16062 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
16063
16064 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
16065
16066 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
16067 const diyfp w = diyfp::mul(v, c_minus_k);
16068 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
16069 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
16070
16071 // ----(---+---)---------------(---+---)---------------(---+---)----
16072 // w- w w+
16073 // = c*m- = c*v = c*m+
16074 //
16075 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
16076 // w+ are now off by a small amount.
16077 // In fact:
16078 //
16079 // w - v * 10^k < 1 ulp
16080 //
16081 // To account for this inaccuracy, add resp. subtract 1 ulp.
16082 //
16083 // --------+---[---------------(---+---)---------------]---+--------
16084 // w- M- w M+ w+
16085 //
16086 // Now any number in [M-, M+] (bounds included) will round to w when input,
16087 // regardless of how the input rounding algorithm breaks ties.
16088 //
16089 // And digit_gen generates the shortest possible such number in [M-, M+].
16090 // Note that this does not mean that Grisu2 always generates the shortest
16091 // possible number in the interval (m-, m+).
16092 const diyfp M_minus(w_minus.f + 1, w_minus.e);
16093 const diyfp M_plus (w_plus.f - 1, w_plus.e );
16094
16095 decimal_exponent = -cached.k; // = -(-k) = k
16096
16097 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
16098}
16099
16105template<typename FloatType>
16107void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
16108{
16109 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
16110 "internal error: not enough precision");
16111
16112 JSON_ASSERT(std::isfinite(value));
16113 JSON_ASSERT(value > 0);
16114
16115 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
16116 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
16117 // decimal representations are not exactly "short".
16118 //
16119 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
16120 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
16121 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
16122 // does.
16123 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
16124 // representation using the corresponding std::from_chars function recovers value exactly". That
16125 // indicates that single precision floating-point numbers should be recovered using
16126 // 'std::strtof'.
16127 //
16128 // NB: If the neighbors are computed for single-precision numbers, there is a single float
16129 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
16130 // value is off by 1 ulp.
16131#if 0
16132 const boundaries w = compute_boundaries(static_cast<double>(value));
16133#else
16135#endif
16136
16137 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
16138}
16139
16147inline char* append_exponent(char* buf, int e)
16148{
16149 JSON_ASSERT(e > -1000);
16150 JSON_ASSERT(e < 1000);
16151
16152 if (e < 0)
16153 {
16154 e = -e;
16155 *buf++ = '-';
16156 }
16157 else
16158 {
16159 *buf++ = '+';
16160 }
16161
16162 auto k = static_cast<std::uint32_t>(e);
16163 if (k < 10)
16164 {
16165 // Always print at least two digits in the exponent.
16166 // This is for compatibility with printf("%g").
16167 *buf++ = '0';
16168 *buf++ = static_cast<char>('0' + k);
16169 }
16170 else if (k < 100)
16171 {
16172 *buf++ = static_cast<char>('0' + k / 10);
16173 k %= 10;
16174 *buf++ = static_cast<char>('0' + k);
16175 }
16176 else
16177 {
16178 *buf++ = static_cast<char>('0' + k / 100);
16179 k %= 100;
16180 *buf++ = static_cast<char>('0' + k / 10);
16181 k %= 10;
16182 *buf++ = static_cast<char>('0' + k);
16183 }
16184
16185 return buf;
16186}
16187
16199inline char* format_buffer(char* buf, int len, int decimal_exponent,
16200 int min_exp, int max_exp)
16201{
16202 JSON_ASSERT(min_exp < 0);
16203 JSON_ASSERT(max_exp > 0);
16204
16205 const int k = len;
16206 const int n = len + decimal_exponent;
16207
16208 // v = buf * 10^(n-k)
16209 // k is the length of the buffer (number of decimal digits)
16210 // n is the position of the decimal point relative to the start of the buffer.
16211
16212 if (k <= n && n <= max_exp)
16213 {
16214 // digits[000]
16215 // len <= max_exp + 2
16216
16217 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
16218 // Make it look like a floating-point number (#362, #378)
16219 buf[n + 0] = '.';
16220 buf[n + 1] = '0';
16221 return buf + (static_cast<size_t>(n) + 2);
16222 }
16223
16224 if (0 < n && n <= max_exp)
16225 {
16226 // dig.its
16227 // len <= max_digits10 + 1
16228
16229 JSON_ASSERT(k > n);
16230
16231 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
16232 buf[n] = '.';
16233 return buf + (static_cast<size_t>(k) + 1U);
16234 }
16235
16236 if (min_exp < n && n <= 0)
16237 {
16238 // 0.[000]digits
16239 // len <= 2 + (-min_exp - 1) + max_digits10
16240
16241 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
16242 buf[0] = '0';
16243 buf[1] = '.';
16244 std::memset(buf + 2, '0', static_cast<size_t>(-n));
16245 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
16246 }
16247
16248 if (k == 1)
16249 {
16250 // dE+123
16251 // len <= 1 + 5
16252
16253 buf += 1;
16254 }
16255 else
16256 {
16257 // d.igitsE+123
16258 // len <= max_digits10 + 1 + 5
16259
16260 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
16261 buf[1] = '.';
16262 buf += 1 + static_cast<size_t>(k);
16263 }
16264
16265 *buf++ = 'e';
16266 return append_exponent(buf, n - 1);
16267}
16268
16269} // namespace dtoa_impl
16270
16281template<typename FloatType>
16284char* to_chars(char* first, const char* last, FloatType value)
16285{
16286 static_cast<void>(last); // maybe unused - fix warning
16287 JSON_ASSERT(std::isfinite(value));
16288
16289 // Use signbit(value) instead of (value < 0) since signbit works for -0.
16290 if (std::signbit(value))
16291 {
16292 value = -value;
16293 *first++ = '-';
16294 }
16295
16296#ifdef __GNUC__
16297#pragma GCC diagnostic push
16298#pragma GCC diagnostic ignored "-Wfloat-equal"
16299#endif
16300 if (value == 0) // +-0
16301 {
16302 *first++ = '0';
16303 // Make it look like a floating-point number (#362, #378)
16304 *first++ = '.';
16305 *first++ = '0';
16306 return first;
16307 }
16308#ifdef __GNUC__
16309#pragma GCC diagnostic pop
16310#endif
16311
16312 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
16313
16314 // Compute v = buffer * 10^decimal_exponent.
16315 // The decimal digits are stored in the buffer, which needs to be interpreted
16316 // as an unsigned decimal integer.
16317 // len is the length of the buffer, i.e. the number of decimal digits.
16318 int len = 0;
16319 int decimal_exponent = 0;
16320 dtoa_impl::grisu2(first, len, decimal_exponent, value);
16321
16322 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
16323
16324 // Format the buffer like printf("%.*g", prec, value)
16325 constexpr int kMinExp = -4;
16326 // Use digits10 here to increase compatibility with version 2.
16327 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
16328
16329 JSON_ASSERT(last - first >= kMaxExp + 2);
16330 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
16331 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
16332
16333 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
16334}
16335
16336} // namespace detail
16337} // namespace nlohmann
16338
16339// #include <nlohmann/detail/exceptions.hpp>
16340
16341// #include <nlohmann/detail/macro_scope.hpp>
16342
16343// #include <nlohmann/detail/meta/cpp_future.hpp>
16344
16345// #include <nlohmann/detail/output/binary_writer.hpp>
16346
16347// #include <nlohmann/detail/output/output_adapters.hpp>
16348
16349// #include <nlohmann/detail/value_t.hpp>
16350
16351
16352namespace nlohmann
16353{
16354namespace detail
16355{
16357// serialization //
16359
16362{
16363 strict,
16364 replace,
16365 ignore
16366};
16367
16368template<typename BasicJsonType>
16370{
16371 using string_t = typename BasicJsonType::string_t;
16372 using number_float_t = typename BasicJsonType::number_float_t;
16373 using number_integer_t = typename BasicJsonType::number_integer_t;
16374 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
16375 using binary_char_t = typename BasicJsonType::binary_t::value_type;
16376 static constexpr std::uint8_t UTF8_ACCEPT = 0;
16377 static constexpr std::uint8_t UTF8_REJECT = 1;
16378
16379 public:
16387 : o(std::move(s))
16388 , loc(std::localeconv())
16389 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
16390 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
16391 , indent_char(ichar)
16393 , error_handler(error_handler_)
16394 {}
16395
16396 // delete because of pointer members
16397 serializer(const serializer&) = delete;
16401 ~serializer() = default;
16402
16425 void dump(const BasicJsonType& val,
16426 const bool pretty_print,
16427 const bool ensure_ascii,
16428 const unsigned int indent_step,
16429 const unsigned int current_indent = 0)
16430 {
16431 switch (val.m_type)
16432 {
16433 case value_t::object:
16434 {
16435 if (val.m_value.object->empty())
16436 {
16437 o->write_characters("{}", 2);
16438 return;
16439 }
16440
16441 if (pretty_print)
16442 {
16443 o->write_characters("{\n", 2);
16444
16445 // variable to hold indentation for recursive calls
16446 const auto new_indent = current_indent + indent_step;
16447 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16448 {
16449 indent_string.resize(indent_string.size() * 2, ' ');
16450 }
16451
16452 // first n-1 elements
16453 auto i = val.m_value.object->cbegin();
16454 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16455 {
16456 o->write_characters(indent_string.c_str(), new_indent);
16457 o->write_character('\"');
16458 dump_escaped(i->first, ensure_ascii);
16459 o->write_characters("\": ", 3);
16460 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16461 o->write_characters(",\n", 2);
16462 }
16463
16464 // last element
16465 JSON_ASSERT(i != val.m_value.object->cend());
16466 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16467 o->write_characters(indent_string.c_str(), new_indent);
16468 o->write_character('\"');
16469 dump_escaped(i->first, ensure_ascii);
16470 o->write_characters("\": ", 3);
16471 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16472
16473 o->write_character('\n');
16474 o->write_characters(indent_string.c_str(), current_indent);
16475 o->write_character('}');
16476 }
16477 else
16478 {
16479 o->write_character('{');
16480
16481 // first n-1 elements
16482 auto i = val.m_value.object->cbegin();
16483 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16484 {
16485 o->write_character('\"');
16486 dump_escaped(i->first, ensure_ascii);
16487 o->write_characters("\":", 2);
16488 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16489 o->write_character(',');
16490 }
16491
16492 // last element
16493 JSON_ASSERT(i != val.m_value.object->cend());
16494 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16495 o->write_character('\"');
16496 dump_escaped(i->first, ensure_ascii);
16497 o->write_characters("\":", 2);
16498 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16499
16500 o->write_character('}');
16501 }
16502
16503 return;
16504 }
16505
16506 case value_t::array:
16507 {
16508 if (val.m_value.array->empty())
16509 {
16510 o->write_characters("[]", 2);
16511 return;
16512 }
16513
16514 if (pretty_print)
16515 {
16516 o->write_characters("[\n", 2);
16517
16518 // variable to hold indentation for recursive calls
16519 const auto new_indent = current_indent + indent_step;
16520 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16521 {
16522 indent_string.resize(indent_string.size() * 2, ' ');
16523 }
16524
16525 // first n-1 elements
16526 for (auto i = val.m_value.array->cbegin();
16527 i != val.m_value.array->cend() - 1; ++i)
16528 {
16529 o->write_characters(indent_string.c_str(), new_indent);
16530 dump(*i, true, ensure_ascii, indent_step, new_indent);
16531 o->write_characters(",\n", 2);
16532 }
16533
16534 // last element
16535 JSON_ASSERT(!val.m_value.array->empty());
16536 o->write_characters(indent_string.c_str(), new_indent);
16537 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
16538
16539 o->write_character('\n');
16540 o->write_characters(indent_string.c_str(), current_indent);
16541 o->write_character(']');
16542 }
16543 else
16544 {
16545 o->write_character('[');
16546
16547 // first n-1 elements
16548 for (auto i = val.m_value.array->cbegin();
16549 i != val.m_value.array->cend() - 1; ++i)
16550 {
16551 dump(*i, false, ensure_ascii, indent_step, current_indent);
16552 o->write_character(',');
16553 }
16554
16555 // last element
16556 JSON_ASSERT(!val.m_value.array->empty());
16557 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
16558
16559 o->write_character(']');
16560 }
16561
16562 return;
16563 }
16564
16565 case value_t::string:
16566 {
16567 o->write_character('\"');
16568 dump_escaped(*val.m_value.string, ensure_ascii);
16569 o->write_character('\"');
16570 return;
16571 }
16572
16573 case value_t::binary:
16574 {
16575 if (pretty_print)
16576 {
16577 o->write_characters("{\n", 2);
16578
16579 // variable to hold indentation for recursive calls
16580 const auto new_indent = current_indent + indent_step;
16581 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16582 {
16583 indent_string.resize(indent_string.size() * 2, ' ');
16584 }
16585
16586 o->write_characters(indent_string.c_str(), new_indent);
16587
16588 o->write_characters("\"bytes\": [", 10);
16589
16590 if (!val.m_value.binary->empty())
16591 {
16592 for (auto i = val.m_value.binary->cbegin();
16593 i != val.m_value.binary->cend() - 1; ++i)
16594 {
16595 dump_integer(*i);
16596 o->write_characters(", ", 2);
16597 }
16598 dump_integer(val.m_value.binary->back());
16599 }
16600
16601 o->write_characters("],\n", 3);
16602 o->write_characters(indent_string.c_str(), new_indent);
16603
16604 o->write_characters("\"subtype\": ", 11);
16605 if (val.m_value.binary->has_subtype())
16606 {
16607 dump_integer(val.m_value.binary->subtype());
16608 }
16609 else
16610 {
16611 o->write_characters("null", 4);
16612 }
16613 o->write_character('\n');
16614 o->write_characters(indent_string.c_str(), current_indent);
16615 o->write_character('}');
16616 }
16617 else
16618 {
16619 o->write_characters("{\"bytes\":[", 10);
16620
16621 if (!val.m_value.binary->empty())
16622 {
16623 for (auto i = val.m_value.binary->cbegin();
16624 i != val.m_value.binary->cend() - 1; ++i)
16625 {
16626 dump_integer(*i);
16627 o->write_character(',');
16628 }
16629 dump_integer(val.m_value.binary->back());
16630 }
16631
16632 o->write_characters("],\"subtype\":", 12);
16633 if (val.m_value.binary->has_subtype())
16634 {
16635 dump_integer(val.m_value.binary->subtype());
16636 o->write_character('}');
16637 }
16638 else
16639 {
16640 o->write_characters("null}", 5);
16641 }
16642 }
16643 return;
16644 }
16645
16646 case value_t::boolean:
16647 {
16648 if (val.m_value.boolean)
16649 {
16650 o->write_characters("true", 4);
16651 }
16652 else
16653 {
16654 o->write_characters("false", 5);
16655 }
16656 return;
16657 }
16658
16660 {
16661 dump_integer(val.m_value.number_integer);
16662 return;
16663 }
16664
16666 {
16667 dump_integer(val.m_value.number_unsigned);
16668 return;
16669 }
16670
16672 {
16673 dump_float(val.m_value.number_float);
16674 return;
16675 }
16676
16677 case value_t::discarded:
16678 {
16679 o->write_characters("<discarded>", 11);
16680 return;
16681 }
16682
16683 case value_t::null:
16684 {
16685 o->write_characters("null", 4);
16686 return;
16687 }
16688
16689 default: // LCOV_EXCL_LINE
16690 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16691 }
16692 }
16693
16709 void dump_escaped(const string_t& s, const bool ensure_ascii)
16710 {
16711 std::uint32_t codepoint{};
16712 std::uint8_t state = UTF8_ACCEPT;
16713 std::size_t bytes = 0; // number of bytes written to string_buffer
16714
16715 // number of bytes written at the point of the last valid byte
16717 std::size_t undumped_chars = 0;
16718
16719 for (std::size_t i = 0; i < s.size(); ++i)
16720 {
16721 const auto byte = static_cast<std::uint8_t>(s[i]);
16722
16723 switch (decode(state, codepoint, byte))
16724 {
16725 case UTF8_ACCEPT: // decode found a new code point
16726 {
16727 switch (codepoint)
16728 {
16729 case 0x08: // backspace
16730 {
16731 string_buffer[bytes++] = '\\';
16732 string_buffer[bytes++] = 'b';
16733 break;
16734 }
16735
16736 case 0x09: // horizontal tab
16737 {
16738 string_buffer[bytes++] = '\\';
16739 string_buffer[bytes++] = 't';
16740 break;
16741 }
16742
16743 case 0x0A: // newline
16744 {
16745 string_buffer[bytes++] = '\\';
16746 string_buffer[bytes++] = 'n';
16747 break;
16748 }
16749
16750 case 0x0C: // formfeed
16751 {
16752 string_buffer[bytes++] = '\\';
16753 string_buffer[bytes++] = 'f';
16754 break;
16755 }
16756
16757 case 0x0D: // carriage return
16758 {
16759 string_buffer[bytes++] = '\\';
16760 string_buffer[bytes++] = 'r';
16761 break;
16762 }
16763
16764 case 0x22: // quotation mark
16765 {
16766 string_buffer[bytes++] = '\\';
16767 string_buffer[bytes++] = '\"';
16768 break;
16769 }
16770
16771 case 0x5C: // reverse solidus
16772 {
16773 string_buffer[bytes++] = '\\';
16774 string_buffer[bytes++] = '\\';
16775 break;
16776 }
16777
16778 default:
16779 {
16780 // escape control characters (0x00..0x1F) or, if
16781 // ensure_ascii parameter is used, non-ASCII characters
16782 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
16783 {
16784 if (codepoint <= 0xFFFF)
16785 {
16786 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16787 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
16788 static_cast<std::uint16_t>(codepoint));
16789 bytes += 6;
16790 }
16791 else
16792 {
16793 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16794 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
16795 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
16796 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
16797 bytes += 12;
16798 }
16799 }
16800 else
16801 {
16802 // copy byte to buffer (all previous bytes
16803 // been copied have in default case above)
16804 string_buffer[bytes++] = s[i];
16805 }
16806 break;
16807 }
16808 }
16809
16810 // write buffer and reset index; there must be 13 bytes
16811 // left, as this is the maximal number of bytes to be
16812 // written ("\uxxxx\uxxxx\0") for one code point
16813 if (string_buffer.size() - bytes < 13)
16814 {
16815 o->write_characters(string_buffer.data(), bytes);
16816 bytes = 0;
16817 }
16818
16819 // remember the byte position of this accept
16821 undumped_chars = 0;
16822 break;
16823 }
16824
16825 case UTF8_REJECT: // decode found invalid UTF-8 byte
16826 {
16827 switch (error_handler)
16828 {
16830 {
16831 std::string sn(9, '\0');
16832 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16833 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
16834 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType()));
16835 }
16836
16839 {
16840 // in case we saw this character the first time, we
16841 // would like to read it again, because the byte
16842 // may be OK for itself, but just not OK for the
16843 // previous sequence
16844 if (undumped_chars > 0)
16845 {
16846 --i;
16847 }
16848
16849 // reset length buffer to the last accepted index;
16850 // thus removing/ignoring the invalid characters
16852
16854 {
16855 // add a replacement character
16856 if (ensure_ascii)
16857 {
16858 string_buffer[bytes++] = '\\';
16859 string_buffer[bytes++] = 'u';
16860 string_buffer[bytes++] = 'f';
16861 string_buffer[bytes++] = 'f';
16862 string_buffer[bytes++] = 'f';
16863 string_buffer[bytes++] = 'd';
16864 }
16865 else
16866 {
16870 }
16871
16872 // write buffer and reset index; there must be 13 bytes
16873 // left, as this is the maximal number of bytes to be
16874 // written ("\uxxxx\uxxxx\0") for one code point
16875 if (string_buffer.size() - bytes < 13)
16876 {
16877 o->write_characters(string_buffer.data(), bytes);
16878 bytes = 0;
16879 }
16880
16882 }
16883
16884 undumped_chars = 0;
16885
16886 // continue processing the string
16888 break;
16889 }
16890
16891 default: // LCOV_EXCL_LINE
16892 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16893 }
16894 break;
16895 }
16896
16897 default: // decode found yet incomplete multi-byte code point
16898 {
16899 if (!ensure_ascii)
16900 {
16901 // code point will not be escaped - copy byte to buffer
16902 string_buffer[bytes++] = s[i];
16903 }
16905 break;
16906 }
16907 }
16908 }
16909
16910 // we finished processing the string
16912 {
16913 // write buffer
16914 if (bytes > 0)
16915 {
16916 o->write_characters(string_buffer.data(), bytes);
16917 }
16918 }
16919 else
16920 {
16921 // we finish reading, but do not accept: string was incomplete
16922 switch (error_handler)
16923 {
16925 {
16926 std::string sn(9, '\0');
16927 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
16928 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
16929 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType()));
16930 }
16931
16933 {
16934 // write all accepted bytes
16935 o->write_characters(string_buffer.data(), bytes_after_last_accept);
16936 break;
16937 }
16938
16940 {
16941 // write all accepted bytes
16942 o->write_characters(string_buffer.data(), bytes_after_last_accept);
16943 // add a replacement character
16944 if (ensure_ascii)
16945 {
16946 o->write_characters("\\ufffd", 6);
16947 }
16948 else
16949 {
16950 o->write_characters("\xEF\xBF\xBD", 3);
16951 }
16952 break;
16953 }
16954
16955 default: // LCOV_EXCL_LINE
16956 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
16957 }
16958 }
16959 }
16960
16961 private:
16970 inline unsigned int count_digits(number_unsigned_t x) noexcept
16971 {
16972 unsigned int n_digits = 1;
16973 for (;;)
16974 {
16975 if (x < 10)
16976 {
16977 return n_digits;
16978 }
16979 if (x < 100)
16980 {
16981 return n_digits + 1;
16982 }
16983 if (x < 1000)
16984 {
16985 return n_digits + 2;
16986 }
16987 if (x < 10000)
16988 {
16989 return n_digits + 3;
16990 }
16991 x = x / 10000u;
16992 n_digits += 4;
16993 }
16994 }
16995
17005 template < typename NumberType, detail::enable_if_t <
17006 std::is_integral<NumberType>::value ||
17007 std::is_same<NumberType, number_unsigned_t>::value ||
17008 std::is_same<NumberType, number_integer_t>::value ||
17009 std::is_same<NumberType, binary_char_t>::value,
17010 int > = 0 >
17011 void dump_integer(NumberType x)
17012 {
17013 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
17014 {
17015 {
17016 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
17017 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
17018 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
17019 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
17020 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
17021 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17022 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17023 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17024 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17025 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17026 }
17027 };
17028
17029 // special case for "0"
17030 if (x == 0)
17031 {
17032 o->write_character('0');
17033 return;
17034 }
17035
17036 // use a pointer to fill the buffer
17037 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17038
17039 const bool is_negative = std::is_signed<NumberType>::value && !(x >= 0); // see issue #755
17040 number_unsigned_t abs_value;
17041
17042 unsigned int n_chars{};
17043
17044 if (is_negative)
17045 {
17046 *buffer_ptr = '-';
17047 abs_value = remove_sign(static_cast<number_integer_t>(x));
17048
17049 // account one more byte for the minus sign
17050 n_chars = 1 + count_digits(abs_value);
17051 }
17052 else
17053 {
17054 abs_value = static_cast<number_unsigned_t>(x);
17055 n_chars = count_digits(abs_value);
17056 }
17057
17058 // spare 1 byte for '\0'
17059 JSON_ASSERT(n_chars < number_buffer.size() - 1);
17060
17061 // jump to the end to generate the string from backward
17062 // so we later avoid reversing the result
17063 buffer_ptr += n_chars;
17064
17065 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
17066 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
17067 while (abs_value >= 100)
17068 {
17069 const auto digits_index = static_cast<unsigned>((abs_value % 100));
17070 abs_value /= 100;
17071 *(--buffer_ptr) = digits_to_99[digits_index][1];
17072 *(--buffer_ptr) = digits_to_99[digits_index][0];
17073 }
17074
17075 if (abs_value >= 10)
17076 {
17077 const auto digits_index = static_cast<unsigned>(abs_value);
17078 *(--buffer_ptr) = digits_to_99[digits_index][1];
17079 *(--buffer_ptr) = digits_to_99[digits_index][0];
17080 }
17081 else
17082 {
17083 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
17084 }
17085
17086 o->write_characters(number_buffer.data(), n_chars);
17087 }
17088
17097 void dump_float(number_float_t x)
17098 {
17099 // NaN / inf
17100 if (!std::isfinite(x))
17101 {
17102 o->write_characters("null", 4);
17103 return;
17104 }
17105
17106 // If number_float_t is an IEEE-754 single or double precision number,
17107 // use the Grisu2 algorithm to produce short numbers which are
17108 // guaranteed to round-trip, using strtof and strtod, resp.
17109 //
17110 // NB: The test below works if <long double> == <double>.
17111 static constexpr bool is_ieee_single_or_double
17112 = (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 24 && std::numeric_limits<number_float_t>::max_exponent == 128) ||
17113 (std::numeric_limits<number_float_t>::is_iec559 && std::numeric_limits<number_float_t>::digits == 53 && std::numeric_limits<number_float_t>::max_exponent == 1024);
17114
17115 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
17116 }
17117
17118 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
17119 {
17120 auto* begin = number_buffer.data();
17121 auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
17122
17123 o->write_characters(begin, static_cast<size_t>(end - begin));
17124 }
17125
17126 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
17127 {
17128 // get number of digits for a float -> text -> float round-trip
17129 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
17130
17131 // the actual conversion
17132 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17133 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
17134
17135 // negative value indicates an error
17136 JSON_ASSERT(len > 0);
17137 // check if buffer was large enough
17138 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
17139
17140 // erase thousands separator
17141 if (thousands_sep != '\0')
17142 {
17143 auto* const end = std::remove(number_buffer.begin(),
17144 number_buffer.begin() + len, thousands_sep);
17145 std::fill(end, number_buffer.end(), '\0');
17146 JSON_ASSERT((end - number_buffer.begin()) <= len);
17147 len = (end - number_buffer.begin());
17148 }
17149
17150 // convert decimal point to '.'
17151 if (decimal_point != '\0' && decimal_point != '.')
17152 {
17153 auto* const dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
17154 if (dec_pos != number_buffer.end())
17155 {
17156 *dec_pos = '.';
17157 }
17158 }
17159
17160 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
17161
17162 // determine if need to append ".0"
17163 const bool value_is_int_like =
17164 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
17165 [](char c)
17166 {
17167 return c == '.' || c == 'e';
17168 });
17169
17170 if (value_is_int_like)
17171 {
17172 o->write_characters(".0", 2);
17173 }
17174 }
17175
17197 static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
17198 {
17199 static const std::array<std::uint8_t, 400> utf8d =
17200 {
17201 {
17202 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00..1F
17203 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20..3F
17204 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40..5F
17205 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60..7F
17206 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, // 80..9F
17207 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // A0..BF
17208 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // C0..DF
17209 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
17210 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
17211 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
17212 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, // s1..s2
17213 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, // s3..s4
17214 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, // s5..s6
17215 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // s7..s8
17216 }
17217 };
17218
17219 JSON_ASSERT(byte < utf8d.size());
17220 const std::uint8_t type = utf8d[byte];
17221
17222 codep = (state != UTF8_ACCEPT)
17223 ? (byte & 0x3fu) | (codep << 6u)
17224 : (0xFFu >> type) & (byte);
17225
17226 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
17227 JSON_ASSERT(index < 400);
17228 state = utf8d[index];
17229 return state;
17230 }
17231
17232 /*
17233 * Overload to make the compiler happy while it is instantiating
17234 * dump_integer for number_unsigned_t.
17235 * Must never be called.
17236 */
17238 {
17239 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17240 return x; // LCOV_EXCL_LINE
17241 }
17242
17243 /*
17244 * Helper function for dump_integer
17245 *
17246 * This function takes a negative signed integer and returns its absolute
17247 * value as unsigned integer. The plus/minus shuffling is necessary as we can
17248 * not directly remove the sign of an arbitrary signed integer as the
17249 * absolute values of INT_MIN and INT_MAX are usually not the same. See
17250 * #1708 for details.
17251 */
17252 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
17253 {
17254 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
17255 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
17256 }
17257
17258 private:
17260 output_adapter_t<char> o = nullptr;
17261
17263 std::array<char, 64> number_buffer{{}};
17264
17266 const std::lconv* loc = nullptr;
17268 const char thousands_sep = '\0';
17270 const char decimal_point = '\0';
17271
17273 std::array<char, 512> string_buffer{{}};
17274
17276 const char indent_char;
17279
17282};
17283} // namespace detail
17284} // namespace nlohmann
17285
17286// #include <nlohmann/detail/value_t.hpp>
17287
17288// #include <nlohmann/json_fwd.hpp>
17289
17290// #include <nlohmann/ordered_map.hpp>
17291
17292
17293#include <functional> // less
17294#include <initializer_list> // initializer_list
17295#include <iterator> // input_iterator_tag, iterator_traits
17296#include <memory> // allocator
17297#include <stdexcept> // for out_of_range
17298#include <type_traits> // enable_if, is_convertible
17299#include <utility> // pair
17300#include <vector> // vector
17301
17302// #include <nlohmann/detail/macro_scope.hpp>
17303
17304
17305namespace nlohmann
17306{
17307
17310template <class Key, class T, class IgnoredLess = std::less<Key>,
17311 class Allocator = std::allocator<std::pair<const Key, T>>>
17312 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
17313{
17314 using key_type = Key;
17315 using mapped_type = T;
17316 using Container = std::vector<std::pair<const Key, T>, Allocator>;
17317 using typename Container::iterator;
17318 using typename Container::const_iterator;
17319 using typename Container::size_type;
17320 using typename Container::value_type;
17321
17322 // Explicit constructors instead of `using Container::Container`
17323 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
17324 ordered_map(const Allocator& alloc = Allocator()) : Container{alloc} {}
17325 template <class It>
17326 ordered_map(It first, It last, const Allocator& alloc = Allocator())
17327 : Container{first, last, alloc} {}
17328 ordered_map(std::initializer_list<T> init, const Allocator& alloc = Allocator() )
17329 : Container{init, alloc} {}
17330
17331 std::pair<iterator, bool> emplace(const key_type& key, T&& t)
17332 {
17333 for (auto it = this->begin(); it != this->end(); ++it)
17334 {
17335 if (it->first == key)
17336 {
17337 return {it, false};
17338 }
17339 }
17340 Container::emplace_back(key, t);
17341 return {--this->end(), true};
17342 }
17343
17344 T& operator[](const Key& key)
17345 {
17346 return emplace(key, T{}).first->second;
17347 }
17348
17349 const T& operator[](const Key& key) const
17350 {
17351 return at(key);
17352 }
17353
17354 T& at(const Key& key)
17355 {
17356 for (auto it = this->begin(); it != this->end(); ++it)
17357 {
17358 if (it->first == key)
17359 {
17360 return it->second;
17361 }
17362 }
17363
17364 JSON_THROW(std::out_of_range("key not found"));
17365 }
17366
17367 const T& at(const Key& key) const
17368 {
17369 for (auto it = this->begin(); it != this->end(); ++it)
17370 {
17371 if (it->first == key)
17372 {
17373 return it->second;
17374 }
17375 }
17376
17377 JSON_THROW(std::out_of_range("key not found"));
17378 }
17379
17380 size_type erase(const Key& key)
17381 {
17382 for (auto it = this->begin(); it != this->end(); ++it)
17383 {
17384 if (it->first == key)
17385 {
17386 // Since we cannot move const Keys, re-construct them in place
17387 for (auto next = it; ++next != this->end(); ++it)
17388 {
17389 it->~value_type(); // Destroy but keep allocation
17390 new (&*it) value_type{std::move(*next)};
17391 }
17392 Container::pop_back();
17393 return 1;
17394 }
17395 }
17396 return 0;
17397 }
17398
17399 iterator erase(iterator pos)
17400 {
17401 auto it = pos;
17402
17403 // Since we cannot move const Keys, re-construct them in place
17404 for (auto next = it; ++next != this->end(); ++it)
17405 {
17406 it->~value_type(); // Destroy but keep allocation
17407 new (&*it) value_type{std::move(*next)};
17408 }
17409 Container::pop_back();
17410 return pos;
17411 }
17412
17413 size_type count(const Key& key) const
17414 {
17415 for (auto it = this->begin(); it != this->end(); ++it)
17416 {
17417 if (it->first == key)
17418 {
17419 return 1;
17420 }
17421 }
17422 return 0;
17423 }
17424
17425 iterator find(const Key& key)
17426 {
17427 for (auto it = this->begin(); it != this->end(); ++it)
17428 {
17429 if (it->first == key)
17430 {
17431 return it;
17432 }
17433 }
17434 return Container::end();
17435 }
17436
17437 const_iterator find(const Key& key) const
17438 {
17439 for (auto it = this->begin(); it != this->end(); ++it)
17440 {
17441 if (it->first == key)
17442 {
17443 return it;
17444 }
17445 }
17446 return Container::end();
17447 }
17448
17449 std::pair<iterator, bool> insert( value_type&& value )
17450 {
17451 return emplace(value.first, std::move(value.second));
17452 }
17453
17454 std::pair<iterator, bool> insert( const value_type& value )
17455 {
17456 for (auto it = this->begin(); it != this->end(); ++it)
17457 {
17458 if (it->first == value.first)
17459 {
17460 return {it, false};
17461 }
17462 }
17463 Container::push_back(value);
17464 return {--this->end(), true};
17465 }
17466
17467 template<typename InputIt>
17468 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
17469 std::input_iterator_tag>::value>::type;
17470
17471 template<typename InputIt, typename = require_input_iter<InputIt>>
17472 void insert(InputIt first, InputIt last)
17473 {
17474 for (auto it = first; it != last; ++it)
17475 {
17476 insert(*it);
17477 }
17478 }
17479};
17480
17481} // namespace nlohmann
17482
17483
17484#if defined(JSON_HAS_CPP_17)
17485 #include <string_view>
17486#endif
17487
17493namespace nlohmann
17494{
17495
17581class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
17582{
17583 private:
17584 template<detail::value_t> friend struct detail::external_constructor;
17585 friend ::nlohmann::json_pointer<basic_json>;
17586
17587 template<typename BasicJsonType, typename InputType>
17588 friend class ::nlohmann::detail::parser;
17589 friend ::nlohmann::detail::serializer<basic_json>;
17590 template<typename BasicJsonType>
17591 friend class ::nlohmann::detail::iter_impl;
17592 template<typename BasicJsonType, typename CharType>
17593 friend class ::nlohmann::detail::binary_writer;
17594 template<typename BasicJsonType, typename InputType, typename SAX>
17595 friend class ::nlohmann::detail::binary_reader;
17596 template<typename BasicJsonType>
17597 friend class ::nlohmann::detail::json_sax_dom_parser;
17598 template<typename BasicJsonType>
17599 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
17600 friend class ::nlohmann::detail::exception;
17601
17604
17606 // convenience aliases for types residing in namespace detail;
17608
17609 template<typename InputAdapterType>
17610 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
17611 InputAdapterType adapter,
17613 const bool allow_exceptions = true,
17614 const bool ignore_comments = false
17615 )
17616 {
17617 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
17618 std::move(cb), allow_exceptions, ignore_comments);
17619 }
17620
17621 private:
17623 template<typename BasicJsonType>
17625 template<typename BasicJsonType>
17627 template<typename Iterator>
17630
17631 template<typename CharType>
17633
17634 template<typename InputType>
17637
17640
17641 public:
17645 template<typename T, typename SFINAE>
17646 using json_serializer = JSONSerializer<T, SFINAE>;
17652 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
17653
17657
17659 // exceptions //
17661
17665
17678
17680
17681
17683 // container types //
17685
17690
17693
17698
17700 using difference_type = std::ptrdiff_t;
17702 using size_type = std::size_t;
17703
17705 using allocator_type = AllocatorType<basic_json>;
17706
17708 using pointer = typename std::allocator_traits<allocator_type>::pointer;
17710 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
17711
17720
17722
17723
17728 {
17729 return allocator_type();
17730 }
17731
17760 {
17761 basic_json result;
17762
17763 result["copyright"] = "(C) 2013-2021 Niels Lohmann";
17764 result["name"] = "JSON for Modern C++";
17765 result["url"] = "https://github.com/nlohmann/json";
17766 result["version"]["string"] =
17767 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
17768 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
17769 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
17770 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
17771 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
17772 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
17773
17774#ifdef _WIN32
17775 result["platform"] = "win32";
17776#elif defined __linux__
17777 result["platform"] = "linux";
17778#elif defined __APPLE__
17779 result["platform"] = "apple";
17780#elif defined __unix__
17781 result["platform"] = "unix";
17782#else
17783 result["platform"] = "unknown";
17784#endif
17785
17786#if defined(__ICC) || defined(__INTEL_COMPILER)
17787 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
17788#elif defined(__clang__)
17789 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
17790#elif defined(__GNUC__) || defined(__GNUG__)
17791 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
17792#elif defined(__HP_cc) || defined(__HP_aCC)
17793 result["compiler"] = "hp"
17794#elif defined(__IBMCPP__)
17795 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
17796#elif defined(_MSC_VER)
17797 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
17798#elif defined(__PGI)
17799 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
17800#elif defined(__SUNPRO_CC)
17801 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
17802#else
17803 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
17804#endif
17805
17806#ifdef __cplusplus
17807 result["compiler"]["c++"] = std::to_string(__cplusplus);
17808#else
17809 result["compiler"]["c++"] = "unknown";
17810#endif
17811 return result;
17812 }
17813
17814
17816 // JSON value data types //
17818
17823
17824#if defined(JSON_HAS_CPP_14)
17825 // Use transparent comparator if possible, combined with perfect forwarding
17826 // on find() and count() calls prevents unnecessary string construction.
17827 using object_comparator_t = std::less<>;
17828#else
17829 using object_comparator_t = std::less<StringType>;
17830#endif
17831
17915 using object_t = ObjectType<StringType,
17916 basic_json,
17918 AllocatorType<std::pair<const StringType,
17919 basic_json>>>;
17920
17965 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
17966
18018 using string_t = StringType;
18019
18044 using boolean_t = BooleanType;
18045
18116 using number_integer_t = NumberIntegerType;
18117
18187 using number_unsigned_t = NumberUnsignedType;
18188
18255 using number_float_t = NumberFloatType;
18256
18328
18329 private:
18330
18332 template<typename T, typename... Args>
18334 static T* create(Args&& ... args)
18335 {
18336 AllocatorType<T> alloc;
18337 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18338
18339 auto deleter = [&](T * obj)
18340 {
18341 AllocatorTraits::deallocate(alloc, obj, 1);
18342 };
18343 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18344 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18345 JSON_ASSERT(obj != nullptr);
18346 return obj.release();
18347 }
18348
18350 // JSON value storage //
18352
18379 union json_value
18380 {
18397
18399 json_value() = default;
18401 json_value(boolean_t v) noexcept : boolean(v) {}
18410 {
18411 switch (t)
18412 {
18413 case value_t::object:
18414 {
18415 object = create<object_t>();
18416 break;
18417 }
18418
18419 case value_t::array:
18420 {
18421 array = create<array_t>();
18422 break;
18423 }
18424
18425 case value_t::string:
18426 {
18427 string = create<string_t>("");
18428 break;
18429 }
18430
18431 case value_t::binary:
18432 {
18433 binary = create<binary_t>();
18434 break;
18435 }
18436
18437 case value_t::boolean:
18438 {
18439 boolean = boolean_t(false);
18440 break;
18441 }
18442
18443 case value_t::number_integer:
18444 {
18446 break;
18447 }
18448
18449 case value_t::number_unsigned:
18450 {
18452 break;
18453 }
18454
18455 case value_t::number_float:
18456 {
18458 break;
18459 }
18460
18461 case value_t::null:
18462 {
18463 object = nullptr; // silence warning, see #821
18464 break;
18465 }
18466
18467 case value_t::discarded:
18468 default:
18469 {
18470 object = nullptr; // silence warning, see #821
18471 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
18472 {
18473 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.2", basic_json())); // LCOV_EXCL_LINE
18474 }
18475 break;
18476 }
18477 }
18478 }
18479
18482 {
18483 string = create<string_t>(value);
18484 }
18485
18488 {
18489 string = create<string_t>(std::move(value));
18490 }
18491
18494 {
18495 object = create<object_t>(value);
18496 }
18497
18500 {
18501 object = create<object_t>(std::move(value));
18502 }
18503
18506 {
18507 array = create<array_t>(value);
18508 }
18509
18512 {
18513 array = create<array_t>(std::move(value));
18514 }
18515
18518 {
18519 binary = create<binary_t>(value);
18520 }
18521
18524 {
18525 binary = create<binary_t>(std::move(value));
18526 }
18527
18530 {
18531 binary = create<binary_t>(value);
18532 }
18533
18536 {
18537 binary = create<binary_t>(std::move(value));
18538 }
18539
18541 {
18542 if (t == value_t::array || t == value_t::object)
18543 {
18544 // flatten the current json_value to a heap-allocated stack
18545 std::vector<basic_json> stack;
18546
18547 // move the top-level items to stack
18548 if (t == value_t::array)
18549 {
18550 stack.reserve(array->size());
18551 std::move(array->begin(), array->end(), std::back_inserter(stack));
18552 }
18553 else
18554 {
18555 stack.reserve(object->size());
18556 for (auto&& it : *object)
18557 {
18558 stack.push_back(std::move(it.second));
18559 }
18560 }
18561
18562 while (!stack.empty())
18563 {
18564 // move the last item to local variable to be processed
18565 basic_json current_item(std::move(stack.back()));
18566 stack.pop_back();
18567
18568 // if current_item is array/object, move
18569 // its children to the stack to be processed later
18570 if (current_item.is_array())
18571 {
18572 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
18573
18574 current_item.m_value.array->clear();
18575 }
18576 else if (current_item.is_object())
18577 {
18578 for (auto&& it : *current_item.m_value.object)
18579 {
18580 stack.push_back(std::move(it.second));
18581 }
18582
18583 current_item.m_value.object->clear();
18584 }
18585
18586 // it's now safe that current_item get destructed
18587 // since it doesn't have any children
18588 }
18589 }
18590
18591 switch (t)
18592 {
18593 case value_t::object:
18594 {
18595 AllocatorType<object_t> alloc;
18596 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18597 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18598 break;
18599 }
18600
18601 case value_t::array:
18602 {
18603 AllocatorType<array_t> alloc;
18604 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18605 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18606 break;
18607 }
18608
18609 case value_t::string:
18610 {
18611 AllocatorType<string_t> alloc;
18612 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18613 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18614 break;
18615 }
18616
18617 case value_t::binary:
18618 {
18619 AllocatorType<binary_t> alloc;
18620 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18621 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18622 break;
18623 }
18624
18625 case value_t::null:
18626 case value_t::boolean:
18627 case value_t::number_integer:
18628 case value_t::number_unsigned:
18629 case value_t::number_float:
18630 case value_t::discarded:
18631 default:
18632 {
18633 break;
18634 }
18635 }
18636 }
18637 };
18638
18639 private:
18658 void assert_invariant(bool check_parents = true) const noexcept
18659 {
18660 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18661 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18662 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18663 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18664
18665#if JSON_DIAGNOSTICS
18666 JSON_TRY
18667 {
18668 // cppcheck-suppress assertWithSideEffect
18669 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
18670 {
18671 return j.m_parent == this;
18672 }));
18673 }
18674 JSON_CATCH(...) {} // LCOV_EXCL_LINE
18675#endif
18676 static_cast<void>(check_parents);
18677 }
18678
18680 {
18681#if JSON_DIAGNOSTICS
18682 switch (m_type)
18683 {
18684 case value_t::array:
18685 {
18686 for (auto& element : *m_value.array)
18687 {
18688 element.m_parent = this;
18689 }
18690 break;
18691 }
18692
18693 case value_t::object:
18694 {
18695 for (auto& element : *m_value.object)
18696 {
18697 element.second.m_parent = this;
18698 }
18699 break;
18700 }
18701
18702 case value_t::null:
18703 case value_t::string:
18704 case value_t::boolean:
18705 case value_t::number_integer:
18706 case value_t::number_unsigned:
18707 case value_t::number_float:
18708 case value_t::binary:
18709 case value_t::discarded:
18710 default:
18711 break;
18712 }
18713#endif
18714 }
18715
18717 {
18718#if JSON_DIAGNOSTICS
18719 for (typename iterator::difference_type i = 0; i < count; ++i)
18720 {
18721 (it + i)->m_parent = this;
18722 }
18723#else
18724 static_cast<void>(count);
18725#endif
18726 return it;
18727 }
18728
18729 reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1))
18730 {
18731#if JSON_DIAGNOSTICS
18732 if (old_capacity != std::size_t(-1))
18733 {
18734 // see https://github.com/nlohmann/json/issues/2838
18735 JSON_ASSERT(type() == value_t::array);
18736 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
18737 {
18738 // capacity has changed: update all parents
18739 set_parents();
18740 return j;
18741 }
18742 }
18743
18744 // ordered_json uses a vector internally, so pointers could have
18745 // been invalidated; see https://github.com/nlohmann/json/issues/2962
18746#ifdef JSON_HEDLEY_MSVC_VERSION
18747#pragma warning(push )
18748#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
18749#endif
18751 {
18752 set_parents();
18753 return j;
18754 }
18755#ifdef JSON_HEDLEY_MSVC_VERSION
18756#pragma warning( pop )
18757#endif
18758
18759 j.m_parent = this;
18760#else
18761 static_cast<void>(j);
18762 static_cast<void>(old_capacity);
18763#endif
18764 return j;
18765 }
18766
18767 public:
18769 // JSON parser callback //
18771
18788
18839
18841 // constructors //
18843
18848
18880 : m_type(v), m_value(v)
18881 {
18883 }
18884
18903 basic_json(std::nullptr_t = nullptr) noexcept
18904 : basic_json(value_t::null)
18905 {
18907 }
18908
18971 template < typename CompatibleType,
18975 basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
18976 JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
18977 std::forward<CompatibleType>(val))))
18978 {
18979 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
18980 set_parents();
18982 }
18983
19010 template < typename BasicJsonType,
19012 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
19013 basic_json(const BasicJsonType& val)
19014 {
19015 using other_boolean_t = typename BasicJsonType::boolean_t;
19016 using other_number_float_t = typename BasicJsonType::number_float_t;
19017 using other_number_integer_t = typename BasicJsonType::number_integer_t;
19018 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
19019 using other_string_t = typename BasicJsonType::string_t;
19020 using other_object_t = typename BasicJsonType::object_t;
19021 using other_array_t = typename BasicJsonType::array_t;
19022 using other_binary_t = typename BasicJsonType::binary_t;
19023
19024 switch (val.type())
19025 {
19026 case value_t::boolean:
19027 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
19028 break;
19029 case value_t::number_float:
19030 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
19031 break;
19032 case value_t::number_integer:
19033 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
19034 break;
19035 case value_t::number_unsigned:
19036 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
19037 break;
19038 case value_t::string:
19039 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
19040 break;
19041 case value_t::object:
19042 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
19043 break;
19044 case value_t::array:
19045 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
19046 break;
19047 case value_t::binary:
19048 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
19049 break;
19050 case value_t::null:
19051 *this = nullptr;
19052 break;
19053 case value_t::discarded:
19054 m_type = value_t::discarded;
19055 break;
19056 default: // LCOV_EXCL_LINE
19057 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19058 }
19059 set_parents();
19061 }
19062
19138 bool type_deduction = true,
19139 value_t manual_type = value_t::array)
19140 {
19141 // check if each element is an array with two elements whose first
19142 // element is a string
19143 bool is_an_object = std::all_of(init.begin(), init.end(),
19144 [](const detail::json_ref<basic_json>& element_ref)
19145 {
19146 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19147 });
19148
19149 // adjust type if type deduction is not wanted
19150 if (!type_deduction)
19151 {
19152 // if array is wanted, do not create an object though possible
19153 if (manual_type == value_t::array)
19154 {
19155 is_an_object = false;
19156 }
19157
19158 // if object is wanted but impossible, throw an exception
19159 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19160 {
19161 JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
19162 }
19163 }
19164
19165 if (is_an_object)
19166 {
19167 // the initializer list is a list of pairs -> create object
19168 m_type = value_t::object;
19169 m_value = value_t::object;
19170
19171 for (auto& element_ref : init)
19172 {
19173 auto element = element_ref.moved_or_copied();
19175 std::move(*((*element.m_value.array)[0].m_value.string)),
19176 std::move((*element.m_value.array)[1]));
19177 }
19178 }
19179 else
19180 {
19181 // the initializer list describes an array -> create array
19182 m_type = value_t::array;
19183 m_value.array = create<array_t>(init.begin(), init.end());
19184 }
19185
19186 set_parents();
19188 }
19189
19218 static basic_json binary(const typename binary_t::container_type& init)
19219 {
19220 auto res = basic_json();
19221 res.m_type = value_t::binary;
19222 res.m_value = init;
19223 return res;
19224 }
19225
19255 static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
19256 {
19257 auto res = basic_json();
19258 res.m_type = value_t::binary;
19259 res.m_value = binary_t(init, subtype);
19260 return res;
19261 }
19262
19266 {
19267 auto res = basic_json();
19268 res.m_type = value_t::binary;
19269 res.m_value = std::move(init);
19270 return res;
19271 }
19272
19275 static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
19276 {
19277 auto res = basic_json();
19278 res.m_type = value_t::binary;
19279 res.m_value = binary_t(std::move(init), subtype);
19280 return res;
19281 }
19282
19322 {
19323 return basic_json(init, false, value_t::array);
19324 }
19325
19366 {
19367 return basic_json(init, false, value_t::object);
19368 }
19369
19393 : m_type(value_t::array)
19394 {
19395 m_value.array = create<array_t>(cnt, val);
19396 set_parents();
19398 }
19399
19455 template < class InputIT, typename std::enable_if <
19456 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19457 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19458 basic_json(InputIT first, InputIT last)
19459 {
19460 JSON_ASSERT(first.m_object != nullptr);
19461 JSON_ASSERT(last.m_object != nullptr);
19462
19463 // make sure iterator fits the current value
19464 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19465 {
19466 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
19467 }
19468
19469 // copy type from first iterator
19470 m_type = first.m_object->m_type;
19471
19472 // check if iterator range is complete for primitive values
19473 switch (m_type)
19474 {
19475 case value_t::boolean:
19476 case value_t::number_float:
19477 case value_t::number_integer:
19478 case value_t::number_unsigned:
19479 case value_t::string:
19480 {
19481 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19482 || !last.m_it.primitive_iterator.is_end()))
19483 {
19484 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
19485 }
19486 break;
19487 }
19488
19489 case value_t::null:
19490 case value_t::object:
19491 case value_t::array:
19492 case value_t::binary:
19493 case value_t::discarded:
19494 default:
19495 break;
19496 }
19497
19498 switch (m_type)
19499 {
19500 case value_t::number_integer:
19501 {
19502 m_value.number_integer = first.m_object->m_value.number_integer;
19503 break;
19504 }
19505
19506 case value_t::number_unsigned:
19507 {
19508 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19509 break;
19510 }
19511
19512 case value_t::number_float:
19513 {
19514 m_value.number_float = first.m_object->m_value.number_float;
19515 break;
19516 }
19517
19518 case value_t::boolean:
19519 {
19520 m_value.boolean = first.m_object->m_value.boolean;
19521 break;
19522 }
19523
19524 case value_t::string:
19525 {
19526 m_value = *first.m_object->m_value.string;
19527 break;
19528 }
19529
19530 case value_t::object:
19531 {
19532 m_value.object = create<object_t>(first.m_it.object_iterator,
19533 last.m_it.object_iterator);
19534 break;
19535 }
19536
19537 case value_t::array:
19538 {
19539 m_value.array = create<array_t>(first.m_it.array_iterator,
19540 last.m_it.array_iterator);
19541 break;
19542 }
19543
19544 case value_t::binary:
19545 {
19546 m_value = *first.m_object->m_value.binary;
19547 break;
19548 }
19549
19550 case value_t::null:
19551 case value_t::discarded:
19552 default:
19553 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
19554 }
19555
19556 set_parents();
19558 }
19559
19560
19562 // other constructors and destructor //
19564
19565 template<typename JsonRef,
19567 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19568 basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19569
19596 : m_type(other.m_type)
19597 {
19598 // check of passed value is valid
19599 other.assert_invariant();
19600
19601 switch (m_type)
19602 {
19603 case value_t::object:
19604 {
19605 m_value = *other.m_value.object;
19606 break;
19607 }
19608
19609 case value_t::array:
19610 {
19611 m_value = *other.m_value.array;
19612 break;
19613 }
19614
19615 case value_t::string:
19616 {
19617 m_value = *other.m_value.string;
19618 break;
19619 }
19620
19621 case value_t::boolean:
19622 {
19623 m_value = other.m_value.boolean;
19624 break;
19625 }
19626
19627 case value_t::number_integer:
19628 {
19629 m_value = other.m_value.number_integer;
19630 break;
19631 }
19632
19633 case value_t::number_unsigned:
19634 {
19635 m_value = other.m_value.number_unsigned;
19636 break;
19637 }
19638
19639 case value_t::number_float:
19640 {
19641 m_value = other.m_value.number_float;
19642 break;
19643 }
19644
19645 case value_t::binary:
19646 {
19647 m_value = *other.m_value.binary;
19648 break;
19649 }
19650
19651 case value_t::null:
19652 case value_t::discarded:
19653 default:
19654 break;
19655 }
19656
19657 set_parents();
19659 }
19660
19687 basic_json(basic_json&& other) noexcept
19688 : m_type(std::move(other.m_type)),
19689 m_value(std::move(other.m_value))
19690 {
19691 // check that passed value is valid
19692 other.assert_invariant(false);
19693
19694 // invalidate payload
19695 other.m_type = value_t::null;
19696 other.m_value = {};
19697
19698 set_parents();
19700 }
19701
19726 std::is_nothrow_move_constructible<value_t>::value&&
19727 std::is_nothrow_move_assignable<value_t>::value&&
19728 std::is_nothrow_move_constructible<json_value>::value&&
19729 std::is_nothrow_move_assignable<json_value>::value
19730 )
19731 {
19732 // check that passed value is valid
19733 other.assert_invariant();
19734
19735 using std::swap;
19736 swap(m_type, other.m_type);
19737 swap(m_value, other.m_value);
19738
19739 set_parents();
19741 return *this;
19742 }
19743
19759 ~basic_json() noexcept
19760 {
19761 assert_invariant(false);
19762 m_value.destroy(m_type);
19763 }
19764
19766
19767 public:
19769 // object inspection //
19771
19775
19823 string_t dump(const int indent = -1,
19824 const char indent_char = ' ',
19825 const bool ensure_ascii = false,
19826 const error_handler_t error_handler = error_handler_t::strict) const
19827 {
19828 string_t result;
19829 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19830
19831 if (indent >= 0)
19832 {
19833 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19834 }
19835 else
19836 {
19837 s.dump(*this, false, ensure_ascii, 0);
19838 }
19839
19840 return result;
19841 }
19842
19876 constexpr value_t type() const noexcept
19877 {
19878 return m_type;
19879 }
19880
19907 constexpr bool is_primitive() const noexcept
19908 {
19909 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
19910 }
19911
19934 constexpr bool is_structured() const noexcept
19935 {
19936 return is_array() || is_object();
19937 }
19938
19956 constexpr bool is_null() const noexcept
19957 {
19958 return m_type == value_t::null;
19959 }
19960
19978 constexpr bool is_boolean() const noexcept
19979 {
19980 return m_type == value_t::boolean;
19981 }
19982
20008 constexpr bool is_number() const noexcept
20009 {
20010 return is_number_integer() || is_number_float();
20011 }
20012
20037 constexpr bool is_number_integer() const noexcept
20038 {
20039 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
20040 }
20041
20065 constexpr bool is_number_unsigned() const noexcept
20066 {
20067 return m_type == value_t::number_unsigned;
20068 }
20069
20093 constexpr bool is_number_float() const noexcept
20094 {
20095 return m_type == value_t::number_float;
20096 }
20097
20115 constexpr bool is_object() const noexcept
20116 {
20117 return m_type == value_t::object;
20118 }
20119
20137 constexpr bool is_array() const noexcept
20138 {
20139 return m_type == value_t::array;
20140 }
20141
20159 constexpr bool is_string() const noexcept
20160 {
20161 return m_type == value_t::string;
20162 }
20163
20181 constexpr bool is_binary() const noexcept
20182 {
20183 return m_type == value_t::binary;
20184 }
20185
20208 constexpr bool is_discarded() const noexcept
20209 {
20210 return m_type == value_t::discarded;
20211 }
20212
20234 constexpr operator value_t() const noexcept
20235 {
20236 return m_type;
20237 }
20238
20240
20241 private:
20243 // value access //
20245
20247 boolean_t get_impl(boolean_t* /*unused*/) const
20248 {
20250 {
20251 return m_value.boolean;
20252 }
20253
20254 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
20255 }
20256
20258 object_t* get_impl_ptr(object_t* /*unused*/) noexcept
20259 {
20260 return is_object() ? m_value.object : nullptr;
20261 }
20262
20264 constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
20265 {
20266 return is_object() ? m_value.object : nullptr;
20267 }
20268
20270 array_t* get_impl_ptr(array_t* /*unused*/) noexcept
20271 {
20272 return is_array() ? m_value.array : nullptr;
20273 }
20274
20276 constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
20277 {
20278 return is_array() ? m_value.array : nullptr;
20279 }
20280
20282 string_t* get_impl_ptr(string_t* /*unused*/) noexcept
20283 {
20284 return is_string() ? m_value.string : nullptr;
20285 }
20286
20288 constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
20289 {
20290 return is_string() ? m_value.string : nullptr;
20291 }
20292
20294 boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
20295 {
20296 return is_boolean() ? &m_value.boolean : nullptr;
20297 }
20298
20300 constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
20301 {
20302 return is_boolean() ? &m_value.boolean : nullptr;
20303 }
20304
20307 {
20308 return is_number_integer() ? &m_value.number_integer : nullptr;
20309 }
20310
20312 constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20313 {
20314 return is_number_integer() ? &m_value.number_integer : nullptr;
20315 }
20316
20319 {
20320 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20321 }
20322
20324 constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20325 {
20326 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20327 }
20328
20331 {
20332 return is_number_float() ? &m_value.number_float : nullptr;
20333 }
20334
20336 constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20337 {
20338 return is_number_float() ? &m_value.number_float : nullptr;
20339 }
20340
20342 binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20343 {
20344 return is_binary() ? m_value.binary : nullptr;
20345 }
20346
20348 constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20349 {
20350 return is_binary() ? m_value.binary : nullptr;
20351 }
20352
20364 template<typename ReferenceType, typename ThisType>
20365 static ReferenceType get_ref_impl(ThisType& obj)
20366 {
20367 // delegate the call to get_ptr<>()
20368 auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20369
20370 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20371 {
20372 return *ptr;
20373 }
20374
20375 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
20376 }
20377
20378 public:
20382
20409 template<typename PointerType, typename std::enable_if<
20410 std::is_pointer<PointerType>::value, int>::type = 0>
20411 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20412 {
20413 // delegate the call to get_impl_ptr<>()
20414 return get_impl_ptr(static_cast<PointerType>(nullptr));
20415 }
20416
20421 template < typename PointerType, typename std::enable_if <
20422 std::is_pointer<PointerType>::value&&
20423 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20424 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20425 {
20426 // delegate the call to get_impl_ptr<>() const
20427 return get_impl_ptr(static_cast<PointerType>(nullptr));
20428 }
20429
20430 private:
20469 template < typename ValueType,
20473 int > = 0 >
20474 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20475 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20476 {
20477 ValueType ret{};
20478 JSONSerializer<ValueType>::from_json(*this, ret);
20479 return ret;
20480 }
20481
20512 template < typename ValueType,
20515 int > = 0 >
20516 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20517 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20518 {
20519 return JSONSerializer<ValueType>::from_json(*this);
20520 }
20521
20537 template < typename BasicJsonType,
20540 int > = 0 >
20541 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20542 {
20543 return *this;
20544 }
20545
20560 template<typename BasicJsonType,
20562 std::is_same<BasicJsonType, basic_json_t>::value,
20563 int> = 0>
20565 {
20566 return *this;
20567 }
20568
20573 template<typename PointerType,
20575 std::is_pointer<PointerType>::value,
20576 int> = 0>
20577 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20578 -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20579 {
20580 // delegate the call to get_ptr
20581 return get_ptr<PointerType>();
20582 }
20583
20584 public:
20608 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20609#if defined(JSON_HAS_CPP_14)
20610 constexpr
20611#endif
20612 auto get() const noexcept(
20613 noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20614 -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20615 {
20616 // we cannot static_assert on ValueTypeCV being non-const, because
20617 // there is support for get<const basic_json_t>(), which is why we
20618 // still need the uncvref
20619 static_assert(!std::is_reference<ValueTypeCV>::value,
20620 "get() cannot be used with reference types, you might want to use get_ref()");
20621 return get_impl<ValueType>(detail::priority_tag<4> {});
20622 }
20623
20651 template<typename PointerType, typename std::enable_if<
20652 std::is_pointer<PointerType>::value, int>::type = 0>
20653 auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20654 {
20655 // delegate the call to get_ptr
20656 return get_ptr<PointerType>();
20657 }
20658
20692 template < typename ValueType,
20696 int > = 0 >
20697 ValueType & get_to(ValueType& v) const noexcept(noexcept(
20698 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20699 {
20700 JSONSerializer<ValueType>::from_json(*this, v);
20701 return v;
20702 }
20703
20704 // specialization to allow to call get_to with a basic_json value
20705 // see https://github.com/nlohmann/json/issues/2175
20706 template<typename ValueType,
20709 int> = 0>
20710 ValueType & get_to(ValueType& v) const
20711 {
20712 v = *this;
20713 return v;
20714 }
20715
20716 template <
20717 typename T, std::size_t N,
20718 typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20721 Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20722 noexcept(noexcept(JSONSerializer<Array>::from_json(
20723 std::declval<const basic_json_t&>(), v)))
20724 {
20725 JSONSerializer<Array>::from_json(*this, v);
20726 return v;
20727 }
20728
20755 template<typename ReferenceType, typename std::enable_if<
20756 std::is_reference<ReferenceType>::value, int>::type = 0>
20757 ReferenceType get_ref()
20758 {
20759 // delegate call to get_ref_impl
20760 return get_ref_impl<ReferenceType>(*this);
20761 }
20762
20767 template < typename ReferenceType, typename std::enable_if <
20768 std::is_reference<ReferenceType>::value&&
20769 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
20770 ReferenceType get_ref() const
20771 {
20772 // delegate call to get_ref_impl
20773 return get_ref_impl<ReferenceType>(*this);
20774 }
20775
20805 template < typename ValueType, typename std::enable_if <
20812
20813#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20815#endif
20817 >::value, int >::type = 0 >
20818 JSON_EXPLICIT operator ValueType() const
20819 {
20820 // delegate the call to get<>() const
20821 return get<ValueType>();
20822 }
20823
20834 {
20835 if (!is_binary())
20836 {
20837 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20838 }
20839
20840 return *get_ptr<binary_t*>();
20841 }
20842
20844 const binary_t& get_binary() const
20845 {
20846 if (!is_binary())
20847 {
20848 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
20849 }
20850
20851 return *get_ptr<const binary_t*>();
20852 }
20853
20855
20856
20858 // element access //
20860
20864
20892 {
20893 // at only works for arrays
20895 {
20896 JSON_TRY
20897 {
20898 return set_parent(m_value.array->at(idx));
20899 }
20900 JSON_CATCH (std::out_of_range&)
20901 {
20902 // create better exception explanation
20903 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20904 }
20905 }
20906 else
20907 {
20908 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20909 }
20910 }
20911
20939 {
20940 // at only works for arrays
20942 {
20943 JSON_TRY
20944 {
20945 return m_value.array->at(idx);
20946 }
20947 JSON_CATCH (std::out_of_range&)
20948 {
20949 // create better exception explanation
20950 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
20951 }
20952 }
20953 else
20954 {
20955 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
20956 }
20957 }
20958
20989 reference at(const typename object_t::key_type& key)
20990 {
20991 // at only works for objects
20993 {
20994 JSON_TRY
20995 {
20996 return set_parent(m_value.object->at(key));
20997 }
20998 JSON_CATCH (std::out_of_range&)
20999 {
21000 // create better exception explanation
21001 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21002 }
21003 }
21004 else
21005 {
21006 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21007 }
21008 }
21009
21040 const_reference at(const typename object_t::key_type& key) const
21041 {
21042 // at only works for objects
21044 {
21045 JSON_TRY
21046 {
21047 return m_value.object->at(key);
21048 }
21049 JSON_CATCH (std::out_of_range&)
21050 {
21051 // create better exception explanation
21052 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21053 }
21054 }
21055 else
21056 {
21057 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21058 }
21059 }
21060
21087 {
21088 // implicitly convert null value to an empty array
21089 if (is_null())
21090 {
21091 m_type = value_t::array;
21092 m_value.array = create<array_t>();
21094 }
21095
21096 // operator[] only works for arrays
21098 {
21099 // fill up array with null values if given idx is outside range
21100 if (idx >= m_value.array->size())
21101 {
21102#if JSON_DIAGNOSTICS
21103 // remember array size before resizing
21104 const auto previous_size = m_value.array->size();
21105#endif
21106 m_value.array->resize(idx + 1);
21107
21108#if JSON_DIAGNOSTICS
21109 // set parent for values added above
21110 set_parents(begin() + static_cast<typename iterator::difference_type>(previous_size), static_cast<typename iterator::difference_type>(idx + 1 - previous_size));
21111#endif
21112 }
21113
21114 return m_value.array->operator[](idx);
21115 }
21116
21117 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21118 }
21119
21140 {
21141 // const operator[] only works for arrays
21143 {
21144 return m_value.array->operator[](idx);
21145 }
21146
21147 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21148 }
21149
21177 reference operator[](const typename object_t::key_type& key)
21178 {
21179 // implicitly convert null value to an empty object
21180 if (is_null())
21181 {
21182 m_type = value_t::object;
21183 m_value.object = create<object_t>();
21185 }
21186
21187 // operator[] only works for objects
21189 {
21190 return set_parent(m_value.object->operator[](key));
21191 }
21192
21193 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21194 }
21195
21226 const_reference operator[](const typename object_t::key_type& key) const
21227 {
21228 // const operator[] only works for objects
21230 {
21231 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21232 return m_value.object->find(key)->second;
21233 }
21234
21235 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21236 }
21237
21265 template<typename T>
21267 reference operator[](T* key)
21268 {
21269 // implicitly convert null to object
21270 if (is_null())
21271 {
21272 m_type = value_t::object;
21273 m_value = value_t::object;
21275 }
21276
21277 // at only works for objects
21279 {
21280 return set_parent(m_value.object->operator[](key));
21281 }
21282
21283 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21284 }
21285
21316 template<typename T>
21318 const_reference operator[](T* key) const
21319 {
21320 // at only works for objects
21322 {
21323 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21324 return m_value.object->find(key)->second;
21325 }
21326
21327 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21328 }
21329
21380 // using std::is_convertible in a std::enable_if will fail when using explicit conversions
21381 template < class ValueType, typename std::enable_if <
21383 && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
21384 ValueType value(const typename object_t::key_type& key, const ValueType& default_value) const
21385 {
21386 // at only works for objects
21388 {
21389 // if key is found, return value and given default value otherwise
21390 const auto it = find(key);
21391 if (it != end())
21392 {
21393 return it->template get<ValueType>();
21394 }
21395
21396 return default_value;
21397 }
21398
21399 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21400 }
21401
21406 string_t value(const typename object_t::key_type& key, const char* default_value) const
21407 {
21408 return value(key, string_t(default_value));
21409 }
21410
21454 template<class ValueType, typename std::enable_if<
21456 ValueType value(const json_pointer& ptr, const ValueType& default_value) const
21457 {
21458 // at only works for objects
21460 {
21461 // if pointer resolves a value, return it or use default value
21462 JSON_TRY
21463 {
21464 return ptr.get_checked(this).template get<ValueType>();
21465 }
21467 {
21468 return default_value;
21469 }
21470 }
21471
21472 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21473 }
21474
21480 string_t value(const json_pointer& ptr, const char* default_value) const
21481 {
21482 return value(ptr, string_t(default_value));
21483 }
21484
21511 {
21512 return *begin();
21513 }
21514
21519 {
21520 return *cbegin();
21521 }
21522
21555 {
21556 auto tmp = end();
21557 --tmp;
21558 return *tmp;
21559 }
21560
21565 {
21566 auto tmp = cend();
21567 --tmp;
21568 return *tmp;
21569 }
21570
21617 template < class IteratorType, typename std::enable_if <
21618 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21619 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21620 = 0 >
21621 IteratorType erase(IteratorType pos)
21622 {
21623 // make sure iterator fits the current value
21624 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21625 {
21626 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
21627 }
21628
21629 IteratorType result = end();
21630
21631 switch (m_type)
21632 {
21633 case value_t::boolean:
21634 case value_t::number_float:
21635 case value_t::number_integer:
21636 case value_t::number_unsigned:
21637 case value_t::string:
21638 case value_t::binary:
21639 {
21640 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21641 {
21642 JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
21643 }
21644
21645 if (is_string())
21646 {
21647 AllocatorType<string_t> alloc;
21648 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21649 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21650 m_value.string = nullptr;
21651 }
21652 else if (is_binary())
21653 {
21654 AllocatorType<binary_t> alloc;
21655 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21656 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21657 m_value.binary = nullptr;
21658 }
21659
21660 m_type = value_t::null;
21662 break;
21663 }
21664
21665 case value_t::object:
21666 {
21667 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21668 break;
21669 }
21670
21671 case value_t::array:
21672 {
21673 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21674 break;
21675 }
21676
21677 case value_t::null:
21678 case value_t::discarded:
21679 default:
21680 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21681 }
21682
21683 return result;
21684 }
21685
21732 template < class IteratorType, typename std::enable_if <
21733 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21734 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21735 = 0 >
21736 IteratorType erase(IteratorType first, IteratorType last)
21737 {
21738 // make sure iterator fits the current value
21739 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
21740 {
21741 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
21742 }
21743
21744 IteratorType result = end();
21745
21746 switch (m_type)
21747 {
21748 case value_t::boolean:
21749 case value_t::number_float:
21750 case value_t::number_integer:
21751 case value_t::number_unsigned:
21752 case value_t::string:
21753 case value_t::binary:
21754 {
21755 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21756 || !last.m_it.primitive_iterator.is_end()))
21757 {
21758 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
21759 }
21760
21761 if (is_string())
21762 {
21763 AllocatorType<string_t> alloc;
21764 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21765 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21766 m_value.string = nullptr;
21767 }
21768 else if (is_binary())
21769 {
21770 AllocatorType<binary_t> alloc;
21771 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21772 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21773 m_value.binary = nullptr;
21774 }
21775
21776 m_type = value_t::null;
21778 break;
21779 }
21780
21781 case value_t::object:
21782 {
21783 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21784 last.m_it.object_iterator);
21785 break;
21786 }
21787
21788 case value_t::array:
21789 {
21790 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21791 last.m_it.array_iterator);
21792 break;
21793 }
21794
21795 case value_t::null:
21796 case value_t::discarded:
21797 default:
21798 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21799 }
21800
21801 return result;
21802 }
21803
21833 size_type erase(const typename object_t::key_type& key)
21834 {
21835 // this erase only works for objects
21837 {
21838 return m_value.object->erase(key);
21839 }
21840
21841 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21842 }
21843
21868 void erase(const size_type idx)
21869 {
21870 // this erase only works for arrays
21872 {
21873 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21874 {
21875 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21876 }
21877
21878 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21879 }
21880 else
21881 {
21882 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21883 }
21884 }
21885
21887
21888
21890 // lookup //
21892
21895
21920 template<typename KeyT>
21921 iterator find(KeyT&& key)
21922 {
21923 auto result = end();
21924
21925 if (is_object())
21926 {
21927 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
21928 }
21929
21930 return result;
21931 }
21932
21937 template<typename KeyT>
21938 const_iterator find(KeyT&& key) const
21939 {
21940 auto result = cend();
21941
21942 if (is_object())
21943 {
21944 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
21945 }
21946
21947 return result;
21948 }
21949
21971 template<typename KeyT>
21972 size_type count(KeyT&& key) const
21973 {
21974 // return 0 for all nonobject types
21975 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
21976 }
21977
22003 template < typename KeyT, typename std::enable_if <
22004 !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
22005 bool contains(KeyT && key) const
22006 {
22007 return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
22008 }
22009
22036 bool contains(const json_pointer& ptr) const
22037 {
22038 return ptr.contains(this);
22039 }
22040
22042
22043
22045 // iterators //
22047
22050
22075 iterator begin() noexcept
22076 {
22077 iterator result(this);
22078 result.set_begin();
22079 return result;
22080 }
22081
22085 const_iterator begin() const noexcept
22086 {
22087 return cbegin();
22088 }
22089
22115 const_iterator cbegin() const noexcept
22116 {
22117 const_iterator result(this);
22118 result.set_begin();
22119 return result;
22120 }
22121
22146 iterator end() noexcept
22147 {
22148 iterator result(this);
22149 result.set_end();
22150 return result;
22151 }
22152
22156 const_iterator end() const noexcept
22157 {
22158 return cend();
22159 }
22160
22186 const_iterator cend() const noexcept
22187 {
22188 const_iterator result(this);
22189 result.set_end();
22190 return result;
22191 }
22192
22217 {
22218 return reverse_iterator(end());
22219 }
22220
22225 {
22226 return crbegin();
22227 }
22228
22254 {
22255 return reverse_iterator(begin());
22256 }
22257
22262 {
22263 return crend();
22264 }
22265
22291 {
22292 return const_reverse_iterator(cend());
22293 }
22294
22320 {
22322 }
22323
22324 public:
22384 {
22385 return ref.items();
22386 }
22387
22393 {
22394 return ref.items();
22395 }
22396
22466 {
22467 return iteration_proxy<iterator>(*this);
22468 }
22469
22474 {
22475 return iteration_proxy<const_iterator>(*this);
22476 }
22477
22479
22480
22482 // capacity //
22484
22487
22530 bool empty() const noexcept
22531 {
22532 switch (m_type)
22533 {
22534 case value_t::null:
22535 {
22536 // null values are empty
22537 return true;
22538 }
22539
22540 case value_t::array:
22541 {
22542 // delegate call to array_t::empty()
22543 return m_value.array->empty();
22544 }
22545
22546 case value_t::object:
22547 {
22548 // delegate call to object_t::empty()
22549 return m_value.object->empty();
22550 }
22551
22552 case value_t::string:
22553 case value_t::boolean:
22554 case value_t::number_integer:
22555 case value_t::number_unsigned:
22556 case value_t::number_float:
22557 case value_t::binary:
22558 case value_t::discarded:
22559 default:
22560 {
22561 // all other types are nonempty
22562 return false;
22563 }
22564 }
22565 }
22566
22610 size_type size() const noexcept
22611 {
22612 switch (m_type)
22613 {
22614 case value_t::null:
22615 {
22616 // null values are empty
22617 return 0;
22618 }
22619
22620 case value_t::array:
22621 {
22622 // delegate call to array_t::size()
22623 return m_value.array->size();
22624 }
22625
22626 case value_t::object:
22627 {
22628 // delegate call to object_t::size()
22629 return m_value.object->size();
22630 }
22631
22632 case value_t::string:
22633 case value_t::boolean:
22634 case value_t::number_integer:
22635 case value_t::number_unsigned:
22636 case value_t::number_float:
22637 case value_t::binary:
22638 case value_t::discarded:
22639 default:
22640 {
22641 // all other types have size 1
22642 return 1;
22643 }
22644 }
22645 }
22646
22688 size_type max_size() const noexcept
22689 {
22690 switch (m_type)
22691 {
22692 case value_t::array:
22693 {
22694 // delegate call to array_t::max_size()
22695 return m_value.array->max_size();
22696 }
22697
22698 case value_t::object:
22699 {
22700 // delegate call to object_t::max_size()
22701 return m_value.object->max_size();
22702 }
22703
22704 case value_t::null:
22705 case value_t::string:
22706 case value_t::boolean:
22707 case value_t::number_integer:
22708 case value_t::number_unsigned:
22709 case value_t::number_float:
22710 case value_t::binary:
22711 case value_t::discarded:
22712 default:
22713 {
22714 // all other types have max_size() == size()
22715 return size();
22716 }
22717 }
22718 }
22719
22721
22722
22724 // modifiers //
22726
22729
22767 void clear() noexcept
22768 {
22769 switch (m_type)
22770 {
22771 case value_t::number_integer:
22772 {
22773 m_value.number_integer = 0;
22774 break;
22775 }
22776
22777 case value_t::number_unsigned:
22778 {
22779 m_value.number_unsigned = 0;
22780 break;
22781 }
22782
22783 case value_t::number_float:
22784 {
22785 m_value.number_float = 0.0;
22786 break;
22787 }
22788
22789 case value_t::boolean:
22790 {
22791 m_value.boolean = false;
22792 break;
22793 }
22794
22795 case value_t::string:
22796 {
22797 m_value.string->clear();
22798 break;
22799 }
22800
22801 case value_t::binary:
22802 {
22803 m_value.binary->clear();
22804 break;
22805 }
22806
22807 case value_t::array:
22808 {
22809 m_value.array->clear();
22810 break;
22811 }
22812
22813 case value_t::object:
22814 {
22815 m_value.object->clear();
22816 break;
22817 }
22818
22819 case value_t::null:
22820 case value_t::discarded:
22821 default:
22822 break;
22823 }
22824 }
22825
22847 {
22848 // push_back only works for null objects or arrays
22849 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22850 {
22851 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22852 }
22853
22854 // transform null object into an array
22855 if (is_null())
22856 {
22857 m_type = value_t::array;
22858 m_value = value_t::array;
22860 }
22861
22862 // add element to array (move semantics)
22863 const auto old_capacity = m_value.array->capacity();
22864 m_value.array->push_back(std::move(val));
22865 set_parent(m_value.array->back(), old_capacity);
22866 // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
22867 }
22868
22874 {
22875 push_back(std::move(val));
22876 return *this;
22877 }
22878
22883 void push_back(const basic_json& val)
22884 {
22885 // push_back only works for null objects or arrays
22886 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
22887 {
22888 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22889 }
22890
22891 // transform null object into an array
22892 if (is_null())
22893 {
22894 m_type = value_t::array;
22895 m_value = value_t::array;
22897 }
22898
22899 // add element to array
22900 const auto old_capacity = m_value.array->capacity();
22901 m_value.array->push_back(val);
22902 set_parent(m_value.array->back(), old_capacity);
22903 }
22904
22910 {
22911 push_back(val);
22912 return *this;
22913 }
22914
22935 void push_back(const typename object_t::value_type& val)
22936 {
22937 // push_back only works for null objects or objects
22938 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
22939 {
22940 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
22941 }
22942
22943 // transform null object into an object
22944 if (is_null())
22945 {
22946 m_type = value_t::object;
22947 m_value = value_t::object;
22949 }
22950
22951 // add element to object
22952 auto res = m_value.object->insert(val);
22953 set_parent(res.first->second);
22954 }
22955
22960 reference operator+=(const typename object_t::value_type& val)
22961 {
22962 push_back(val);
22963 return *this;
22964 }
22965
22992 {
22993 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
22994 {
22995 basic_json&& key = init.begin()->moved_or_copied();
22996 push_back(typename object_t::value_type(
22997 std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
22998 }
22999 else
23000 {
23001 push_back(basic_json(init));
23002 }
23003 }
23004
23010 {
23011 push_back(init);
23012 return *this;
23013 }
23014
23038 template<class... Args>
23039 reference emplace_back(Args&& ... args)
23040 {
23041 // emplace_back only works for null objects or arrays
23042 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23043 {
23044 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
23045 }
23046
23047 // transform null object into an array
23048 if (is_null())
23049 {
23050 m_type = value_t::array;
23051 m_value = value_t::array;
23053 }
23054
23055 // add element to array (perfect forwarding)
23056 const auto old_capacity = m_value.array->capacity();
23057 m_value.array->emplace_back(std::forward<Args>(args)...);
23058 return set_parent(m_value.array->back(), old_capacity);
23059 }
23060
23088 template<class... Args>
23089 std::pair<iterator, bool> emplace(Args&& ... args)
23090 {
23091 // emplace only works for null objects or arrays
23092 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23093 {
23094 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
23095 }
23096
23097 // transform null object into an object
23098 if (is_null())
23099 {
23100 m_type = value_t::object;
23101 m_value = value_t::object;
23103 }
23104
23105 // add element to array (perfect forwarding)
23106 auto res = m_value.object->emplace(std::forward<Args>(args)...);
23107 set_parent(res.first->second);
23108
23109 // create result iterator and set iterator to the result of emplace
23110 auto it = begin();
23111 it.m_it.object_iterator = res.first;
23112
23113 // return pair of iterator and boolean
23114 return {it, res.second};
23115 }
23116
23120 template<typename... Args>
23122 {
23123 iterator result(this);
23124 JSON_ASSERT(m_value.array != nullptr);
23125
23126 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
23127 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
23128 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
23129
23130 // This could have been written as:
23131 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
23132 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
23133
23134 set_parents();
23135 return result;
23136 }
23137
23161 {
23162 // insert only works for arrays
23164 {
23165 // check if iterator pos fits to this JSON value
23166 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23167 {
23168 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23169 }
23170
23171 // insert to array and return iterator
23172 return insert_iterator(pos, val);
23173 }
23174
23175 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23176 }
23177
23183 {
23184 return insert(pos, val);
23185 }
23186
23212 {
23213 // insert only works for arrays
23215 {
23216 // check if iterator pos fits to this JSON value
23217 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23218 {
23219 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23220 }
23221
23222 // insert to array and return iterator
23223 return insert_iterator(pos, cnt, val);
23224 }
23225
23226 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23227 }
23228
23260 {
23261 // insert only works for arrays
23263 {
23264 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23265 }
23266
23267 // check if iterator pos fits to this JSON value
23268 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23269 {
23270 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23271 }
23272
23273 // check if range iterators belong to the same JSON object
23274 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23275 {
23276 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23277 }
23278
23279 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
23280 {
23281 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
23282 }
23283
23284 // insert to array and return iterator
23285 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
23286 }
23287
23313 {
23314 // insert only works for arrays
23316 {
23317 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23318 }
23319
23320 // check if iterator pos fits to this JSON value
23321 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23322 {
23323 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23324 }
23325
23326 // insert to array and return iterator
23327 return insert_iterator(pos, ilist.begin(), ilist.end());
23328 }
23329
23354 {
23355 // insert only works for objects
23357 {
23358 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23359 }
23360
23361 // check if range iterators belong to the same JSON object
23362 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23363 {
23364 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23365 }
23366
23367 // passed iterators must belong to objects
23368 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23369 {
23370 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23371 }
23372
23373 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
23374 }
23375
23396 {
23397 // implicitly convert null value to an empty object
23398 if (is_null())
23399 {
23400 m_type = value_t::object;
23401 m_value.object = create<object_t>();
23403 }
23404
23406 {
23407 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23408 }
23410 {
23411 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
23412 }
23413
23414 for (auto it = j.cbegin(); it != j.cend(); ++it)
23415 {
23416 m_value.object->operator[](it.key()) = it.value();
23417 }
23418 }
23419
23447 {
23448 // implicitly convert null value to an empty object
23449 if (is_null())
23450 {
23451 m_type = value_t::object;
23452 m_value.object = create<object_t>();
23454 }
23455
23457 {
23458 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23459 }
23460
23461 // check if range iterators belong to the same JSON object
23462 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23463 {
23464 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23465 }
23466
23467 // passed iterators must belong to objects
23468 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
23469 || !last.m_object->is_object()))
23470 {
23471 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23472 }
23473
23474 for (auto it = first; it != last; ++it)
23475 {
23476 m_value.object->operator[](it.key()) = it.value();
23477 }
23478 }
23479
23497 void swap(reference other) noexcept (
23498 std::is_nothrow_move_constructible<value_t>::value&&
23499 std::is_nothrow_move_assignable<value_t>::value&&
23500 std::is_nothrow_move_constructible<json_value>::value&&
23501 std::is_nothrow_move_assignable<json_value>::value
23502 )
23503 {
23504 std::swap(m_type, other.m_type);
23505 std::swap(m_value, other.m_value);
23506
23507 set_parents();
23508 other.set_parents();
23510 }
23511
23530 friend void swap(reference left, reference right) noexcept (
23531 std::is_nothrow_move_constructible<value_t>::value&&
23532 std::is_nothrow_move_assignable<value_t>::value&&
23533 std::is_nothrow_move_constructible<json_value>::value&&
23534 std::is_nothrow_move_assignable<json_value>::value
23535 )
23536 {
23537 left.swap(right);
23538 }
23539
23560 void swap(array_t& other) // NOLINT(bugprone-exception-escape)
23561 {
23562 // swap only works for arrays
23564 {
23565 std::swap(*(m_value.array), other);
23566 }
23567 else
23568 {
23569 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23570 }
23571 }
23572
23593 void swap(object_t& other) // NOLINT(bugprone-exception-escape)
23594 {
23595 // swap only works for objects
23597 {
23598 std::swap(*(m_value.object), other);
23599 }
23600 else
23601 {
23602 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23603 }
23604 }
23605
23626 void swap(string_t& other) // NOLINT(bugprone-exception-escape)
23627 {
23628 // swap only works for strings
23630 {
23631 std::swap(*(m_value.string), other);
23632 }
23633 else
23634 {
23635 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23636 }
23637 }
23638
23659 void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
23660 {
23661 // swap only works for strings
23663 {
23664 std::swap(*(m_value.binary), other);
23665 }
23666 else
23667 {
23668 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23669 }
23670 }
23671
23673 void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
23674 {
23675 // swap only works for strings
23677 {
23678 std::swap(*(m_value.binary), other);
23679 }
23680 else
23681 {
23682 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23683 }
23684 }
23685
23687
23688 public:
23690 // lexicographical comparison operators //
23692
23695
23751 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
23752 {
23753#ifdef __GNUC__
23754#pragma GCC diagnostic push
23755#pragma GCC diagnostic ignored "-Wfloat-equal"
23756#endif
23757 const auto lhs_type = lhs.type();
23758 const auto rhs_type = rhs.type();
23759
23760 if (lhs_type == rhs_type)
23761 {
23762 switch (lhs_type)
23763 {
23764 case value_t::array:
23765 return *lhs.m_value.array == *rhs.m_value.array;
23766
23767 case value_t::object:
23768 return *lhs.m_value.object == *rhs.m_value.object;
23769
23770 case value_t::null:
23771 return true;
23772
23773 case value_t::string:
23774 return *lhs.m_value.string == *rhs.m_value.string;
23775
23776 case value_t::boolean:
23777 return lhs.m_value.boolean == rhs.m_value.boolean;
23778
23779 case value_t::number_integer:
23780 return lhs.m_value.number_integer == rhs.m_value.number_integer;
23781
23782 case value_t::number_unsigned:
23783 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
23784
23785 case value_t::number_float:
23786 return lhs.m_value.number_float == rhs.m_value.number_float;
23787
23788 case value_t::binary:
23789 return *lhs.m_value.binary == *rhs.m_value.binary;
23790
23791 case value_t::discarded:
23792 default:
23793 return false;
23794 }
23795 }
23796 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23797 {
23798 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
23799 }
23800 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23801 {
23802 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
23803 }
23804 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23805 {
23806 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
23807 }
23808 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23809 {
23810 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
23811 }
23812 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23813 {
23814 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
23815 }
23816 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23817 {
23818 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23819 }
23820
23821 return false;
23822#ifdef __GNUC__
23823#pragma GCC diagnostic pop
23824#endif
23825 }
23826
23831 template<typename ScalarType, typename std::enable_if<
23832 std::is_scalar<ScalarType>::value, int>::type = 0>
23833 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
23834 {
23835 return lhs == basic_json(rhs);
23836 }
23837
23842 template<typename ScalarType, typename std::enable_if<
23843 std::is_scalar<ScalarType>::value, int>::type = 0>
23844 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
23845 {
23846 return basic_json(lhs) == rhs;
23847 }
23848
23867 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
23868 {
23869 return !(lhs == rhs);
23870 }
23871
23876 template<typename ScalarType, typename std::enable_if<
23877 std::is_scalar<ScalarType>::value, int>::type = 0>
23878 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
23879 {
23880 return lhs != basic_json(rhs);
23881 }
23882
23887 template<typename ScalarType, typename std::enable_if<
23888 std::is_scalar<ScalarType>::value, int>::type = 0>
23889 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
23890 {
23891 return basic_json(lhs) != rhs;
23892 }
23893
23920 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
23921 {
23922 const auto lhs_type = lhs.type();
23923 const auto rhs_type = rhs.type();
23924
23925 if (lhs_type == rhs_type)
23926 {
23927 switch (lhs_type)
23928 {
23929 case value_t::array:
23930 // note parentheses are necessary, see
23931 // https://github.com/nlohmann/json/issues/1530
23932 return (*lhs.m_value.array) < (*rhs.m_value.array);
23933
23934 case value_t::object:
23935 return (*lhs.m_value.object) < (*rhs.m_value.object);
23936
23937 case value_t::null:
23938 return false;
23939
23940 case value_t::string:
23941 return (*lhs.m_value.string) < (*rhs.m_value.string);
23942
23943 case value_t::boolean:
23944 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
23945
23946 case value_t::number_integer:
23947 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
23948
23949 case value_t::number_unsigned:
23950 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
23951
23952 case value_t::number_float:
23953 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
23954
23955 case value_t::binary:
23956 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
23957
23958 case value_t::discarded:
23959 default:
23960 return false;
23961 }
23962 }
23963 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
23964 {
23965 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
23966 }
23967 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
23968 {
23969 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
23970 }
23971 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
23972 {
23973 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
23974 }
23975 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
23976 {
23977 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
23978 }
23979 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
23980 {
23981 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
23982 }
23983 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
23984 {
23985 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
23986 }
23987
23988 // We only reach this line if we cannot compare values. In that case,
23989 // we compare types. Note we have to call the operator explicitly,
23990 // because MSVC has problems otherwise.
23991 return operator<(lhs_type, rhs_type);
23992 }
23993
23998 template<typename ScalarType, typename std::enable_if<
23999 std::is_scalar<ScalarType>::value, int>::type = 0>
24000 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
24001 {
24002 return lhs < basic_json(rhs);
24003 }
24004
24009 template<typename ScalarType, typename std::enable_if<
24010 std::is_scalar<ScalarType>::value, int>::type = 0>
24011 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
24012 {
24013 return basic_json(lhs) < rhs;
24014 }
24015
24035 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
24036 {
24037 return !(rhs < lhs);
24038 }
24039
24044 template<typename ScalarType, typename std::enable_if<
24045 std::is_scalar<ScalarType>::value, int>::type = 0>
24046 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
24047 {
24048 return lhs <= basic_json(rhs);
24049 }
24050
24055 template<typename ScalarType, typename std::enable_if<
24056 std::is_scalar<ScalarType>::value, int>::type = 0>
24057 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
24058 {
24059 return basic_json(lhs) <= rhs;
24060 }
24061
24081 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
24082 {
24083 return !(lhs <= rhs);
24084 }
24085
24090 template<typename ScalarType, typename std::enable_if<
24091 std::is_scalar<ScalarType>::value, int>::type = 0>
24092 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
24093 {
24094 return lhs > basic_json(rhs);
24095 }
24096
24101 template<typename ScalarType, typename std::enable_if<
24102 std::is_scalar<ScalarType>::value, int>::type = 0>
24103 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
24104 {
24105 return basic_json(lhs) > rhs;
24106 }
24107
24127 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
24128 {
24129 return !(lhs < rhs);
24130 }
24131
24136 template<typename ScalarType, typename std::enable_if<
24137 std::is_scalar<ScalarType>::value, int>::type = 0>
24138 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
24139 {
24140 return lhs >= basic_json(rhs);
24141 }
24142
24147 template<typename ScalarType, typename std::enable_if<
24148 std::is_scalar<ScalarType>::value, int>::type = 0>
24149 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
24150 {
24151 return basic_json(lhs) >= rhs;
24152 }
24153
24155
24157 // serialization //
24159
24162#ifndef JSON_NO_IO
24194 friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
24195 {
24196 // read width member and use it as indentation parameter if nonzero
24197 const bool pretty_print = o.width() > 0;
24198 const auto indentation = pretty_print ? o.width() : 0;
24199
24200 // reset width to 0 for subsequent calls to this stream
24201 o.width(0);
24202
24203 // do the actual serialization
24204 serializer s(detail::output_adapter<char>(o), o.fill());
24205 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
24206 return o;
24207 }
24208
24217 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
24218 friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
24219 {
24220 return o << j;
24221 }
24222#endif // JSON_NO_IO
24224
24225
24227 // deserialization //
24229
24232
24284 template<typename InputType>
24286 static basic_json parse(InputType&& i,
24287 const parser_callback_t cb = nullptr,
24288 const bool allow_exceptions = true,
24289 const bool ignore_comments = false)
24290 {
24291 basic_json result;
24292 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
24293 return result;
24294 }
24295
24322 template<typename IteratorType>
24324 static basic_json parse(IteratorType first,
24325 IteratorType last,
24326 const parser_callback_t cb = nullptr,
24327 const bool allow_exceptions = true,
24328 const bool ignore_comments = false)
24329 {
24330 basic_json result;
24331 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
24332 return result;
24333 }
24334
24336 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
24337 static basic_json parse(detail::span_input_adapter&& i,
24338 const parser_callback_t cb = nullptr,
24339 const bool allow_exceptions = true,
24340 const bool ignore_comments = false)
24341 {
24342 basic_json result;
24343 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
24344 return result;
24345 }
24346
24377 template<typename InputType>
24378 static bool accept(InputType&& i,
24379 const bool ignore_comments = false)
24380 {
24381 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
24382 }
24383
24384 template<typename IteratorType>
24385 static bool accept(IteratorType first, IteratorType last,
24386 const bool ignore_comments = false)
24387 {
24388 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
24389 }
24390
24392 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
24393 static bool accept(detail::span_input_adapter&& i,
24394 const bool ignore_comments = false)
24395 {
24396 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
24397 }
24398
24439 template <typename InputType, typename SAX>
24441 static bool sax_parse(InputType&& i, SAX* sax,
24443 const bool strict = true,
24444 const bool ignore_comments = false)
24445 {
24446 auto ia = detail::input_adapter(std::forward<InputType>(i));
24447 return format == input_format_t::json
24448 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24449 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24450 }
24451
24452 template<class IteratorType, class SAX>
24454 static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
24456 const bool strict = true,
24457 const bool ignore_comments = false)
24458 {
24459 auto ia = detail::input_adapter(std::move(first), std::move(last));
24460 return format == input_format_t::json
24461 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24462 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24463 }
24464
24465 template <typename SAX>
24466 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
24468 static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
24470 const bool strict = true,
24471 const bool ignore_comments = false)
24472 {
24473 auto ia = i.get();
24474 return format == input_format_t::json
24475 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24476 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24477 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24478 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24479 }
24480#ifndef JSON_NO_IO
24489 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
24490 friend std::istream& operator<<(basic_json& j, std::istream& i)
24491 {
24492 return operator>>(i, j);
24493 }
24494
24520 friend std::istream& operator>>(std::istream& i, basic_json& j)
24521 {
24522 parser(detail::input_adapter(i)).parse(false, j);
24523 return i;
24524 }
24525#endif // JSON_NO_IO
24527
24529 // convenience functions //
24531
24564 const char* type_name() const noexcept
24565 {
24566 {
24567 switch (m_type)
24568 {
24569 case value_t::null:
24570 return "null";
24571 case value_t::object:
24572 return "object";
24573 case value_t::array:
24574 return "array";
24575 case value_t::string:
24576 return "string";
24577 case value_t::boolean:
24578 return "boolean";
24579 case value_t::binary:
24580 return "binary";
24581 case value_t::discarded:
24582 return "discarded";
24583 case value_t::number_integer:
24584 case value_t::number_unsigned:
24585 case value_t::number_float:
24586 default:
24587 return "number";
24588 }
24589 }
24590 }
24591
24592
24595 // member variables //
24597
24599 value_t m_type = value_t::null;
24600
24603
24604#if JSON_DIAGNOSTICS
24606 basic_json* m_parent = nullptr;
24607#endif
24608
24610 // binary serialization/deserialization //
24612
24615
24616 public:
24715 static std::vector<std::uint8_t> to_cbor(const basic_json& j)
24716 {
24717 std::vector<std::uint8_t> result;
24718 to_cbor(j, result);
24719 return result;
24720 }
24721
24726
24728 {
24730 }
24731
24810 static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
24811 {
24812 std::vector<std::uint8_t> result;
24813 to_msgpack(j, result);
24814 return result;
24815 }
24816
24821
24823 {
24825 }
24826
24913 static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
24914 const bool use_size = false,
24915 const bool use_type = false)
24916 {
24917 std::vector<std::uint8_t> result;
24918 to_ubjson(j, result, use_size, use_type);
24919 return result;
24920 }
24921
24923 const bool use_size = false, const bool use_type = false)
24924 {
24925 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
24926 }
24927
24929 const bool use_size = false, const bool use_type = false)
24930 {
24931 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
24932 }
24933
24934
24991 static std::vector<std::uint8_t> to_bson(const basic_json& j)
24992 {
24993 std::vector<std::uint8_t> result;
24994 to_bson(j, result);
24995 return result;
24996 }
24997
25010
25015 {
25017 }
25018
25019
25122 template<typename InputType>
25124 static basic_json from_cbor(InputType&& i,
25125 const bool strict = true,
25126 const bool allow_exceptions = true,
25127 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25128 {
25129 basic_json result;
25130 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25131 auto ia = detail::input_adapter(std::forward<InputType>(i));
25132 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25133 return res ? result : basic_json(value_t::discarded);
25134 }
25135
25139 template<typename IteratorType>
25141 static basic_json from_cbor(IteratorType first, IteratorType last,
25142 const bool strict = true,
25143 const bool allow_exceptions = true,
25144 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25145 {
25146 basic_json result;
25147 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25148 auto ia = detail::input_adapter(std::move(first), std::move(last));
25149 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25150 return res ? result : basic_json(value_t::discarded);
25151 }
25152
25153 template<typename T>
25155 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25156 static basic_json from_cbor(const T* ptr, std::size_t len,
25157 const bool strict = true,
25158 const bool allow_exceptions = true,
25159 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25160 {
25161 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
25162 }
25163
25164
25166 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25167 static basic_json from_cbor(detail::span_input_adapter&& i,
25168 const bool strict = true,
25169 const bool allow_exceptions = true,
25170 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25171 {
25172 basic_json result;
25173 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25174 auto ia = i.get();
25175 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25176 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25177 return res ? result : basic_json(value_t::discarded);
25178 }
25179
25266 template<typename InputType>
25268 static basic_json from_msgpack(InputType&& i,
25269 const bool strict = true,
25270 const bool allow_exceptions = true)
25271 {
25272 basic_json result;
25273 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25274 auto ia = detail::input_adapter(std::forward<InputType>(i));
25275 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25276 return res ? result : basic_json(value_t::discarded);
25277 }
25278
25282 template<typename IteratorType>
25284 static basic_json from_msgpack(IteratorType first, IteratorType last,
25285 const bool strict = true,
25286 const bool allow_exceptions = true)
25287 {
25288 basic_json result;
25289 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25290 auto ia = detail::input_adapter(std::move(first), std::move(last));
25291 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25292 return res ? result : basic_json(value_t::discarded);
25293 }
25294
25295
25296 template<typename T>
25298 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25299 static basic_json from_msgpack(const T* ptr, std::size_t len,
25300 const bool strict = true,
25301 const bool allow_exceptions = true)
25302 {
25303 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
25304 }
25305
25307 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25308 static basic_json from_msgpack(detail::span_input_adapter&& i,
25309 const bool strict = true,
25310 const bool allow_exceptions = true)
25311 {
25312 basic_json result;
25313 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25314 auto ia = i.get();
25315 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25316 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25317 return res ? result : basic_json(value_t::discarded);
25318 }
25319
25320
25383 template<typename InputType>
25385 static basic_json from_ubjson(InputType&& i,
25386 const bool strict = true,
25387 const bool allow_exceptions = true)
25388 {
25389 basic_json result;
25390 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25391 auto ia = detail::input_adapter(std::forward<InputType>(i));
25392 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25393 return res ? result : basic_json(value_t::discarded);
25394 }
25395
25399 template<typename IteratorType>
25401 static basic_json from_ubjson(IteratorType first, IteratorType last,
25402 const bool strict = true,
25403 const bool allow_exceptions = true)
25404 {
25405 basic_json result;
25406 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25407 auto ia = detail::input_adapter(std::move(first), std::move(last));
25408 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25409 return res ? result : basic_json(value_t::discarded);
25410 }
25411
25412 template<typename T>
25414 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25415 static basic_json from_ubjson(const T* ptr, std::size_t len,
25416 const bool strict = true,
25417 const bool allow_exceptions = true)
25418 {
25419 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
25420 }
25421
25423 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25424 static basic_json from_ubjson(detail::span_input_adapter&& i,
25425 const bool strict = true,
25426 const bool allow_exceptions = true)
25427 {
25428 basic_json result;
25429 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25430 auto ia = i.get();
25431 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25432 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25433 return res ? result : basic_json(value_t::discarded);
25434 }
25435
25436
25497 template<typename InputType>
25499 static basic_json from_bson(InputType&& i,
25500 const bool strict = true,
25501 const bool allow_exceptions = true)
25502 {
25503 basic_json result;
25504 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25505 auto ia = detail::input_adapter(std::forward<InputType>(i));
25506 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25507 return res ? result : basic_json(value_t::discarded);
25508 }
25509
25513 template<typename IteratorType>
25515 static basic_json from_bson(IteratorType first, IteratorType last,
25516 const bool strict = true,
25517 const bool allow_exceptions = true)
25518 {
25519 basic_json result;
25520 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25521 auto ia = detail::input_adapter(std::move(first), std::move(last));
25522 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25523 return res ? result : basic_json(value_t::discarded);
25524 }
25525
25526 template<typename T>
25528 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25529 static basic_json from_bson(const T* ptr, std::size_t len,
25530 const bool strict = true,
25531 const bool allow_exceptions = true)
25532 {
25533 return from_bson(ptr, ptr + len, strict, allow_exceptions);
25534 }
25535
25537 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25538 static basic_json from_bson(detail::span_input_adapter&& i,
25539 const bool strict = true,
25540 const bool allow_exceptions = true)
25541 {
25542 basic_json result;
25543 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25544 auto ia = i.get();
25545 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25546 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25547 return res ? result : basic_json(value_t::discarded);
25548 }
25550
25552 // JSON Pointer support //
25554
25557
25592 {
25593 return ptr.get_unchecked(this);
25594 }
25595
25620 {
25621 return ptr.get_unchecked(this);
25622 }
25623
25663 {
25664 return ptr.get_checked(this);
25665 }
25666
25706 {
25707 return ptr.get_checked(this);
25708 }
25709
25733 {
25734 basic_json result(value_t::object);
25735 json_pointer::flatten("", *this, result);
25736 return result;
25737 }
25738
25770 {
25771 return json_pointer::unflatten(*this);
25772 }
25773
25775
25777 // JSON Patch functions //
25779
25782
25830 basic_json patch(const basic_json& json_patch) const
25831 {
25832 // make a working copy to apply the patch to
25833 basic_json result = *this;
25834
25835 // the valid JSON Patch operations
25836 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
25837
25838 const auto get_op = [](const std::string & op)
25839 {
25840 if (op == "add")
25841 {
25842 return patch_operations::add;
25843 }
25844 if (op == "remove")
25845 {
25846 return patch_operations::remove;
25847 }
25848 if (op == "replace")
25849 {
25850 return patch_operations::replace;
25851 }
25852 if (op == "move")
25853 {
25854 return patch_operations::move;
25855 }
25856 if (op == "copy")
25857 {
25858 return patch_operations::copy;
25859 }
25860 if (op == "test")
25861 {
25862 return patch_operations::test;
25863 }
25864
25865 return patch_operations::invalid;
25866 };
25867
25868 // wrapper for "add" operation; add value at ptr
25869 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
25870 {
25871 // adding to the root of the target document means replacing it
25872 if (ptr.empty())
25873 {
25874 result = val;
25875 return;
25876 }
25877
25878 // make sure the top element of the pointer exists
25879 json_pointer top_pointer = ptr.top();
25880 if (top_pointer != ptr)
25881 {
25882 result.at(top_pointer);
25883 }
25884
25885 // get reference to parent of JSON pointer ptr
25886 const auto last_path = ptr.back();
25887 ptr.pop_back();
25888 basic_json& parent = result[ptr];
25889
25890 switch (parent.m_type)
25891 {
25892 case value_t::null:
25893 case value_t::object:
25894 {
25895 // use operator[] to add value
25896 parent[last_path] = val;
25897 break;
25898 }
25899
25900 case value_t::array:
25901 {
25902 if (last_path == "-")
25903 {
25904 // special case: append to back
25905 parent.push_back(val);
25906 }
25907 else
25908 {
25909 const auto idx = json_pointer::array_index(last_path);
25910 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
25911 {
25912 // avoid undefined behavior
25913 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
25914 }
25915
25916 // default case: insert add offset
25917 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
25918 }
25919 break;
25920 }
25921
25922 // if there exists a parent it cannot be primitive
25923 case value_t::string: // LCOV_EXCL_LINE
25924 case value_t::boolean: // LCOV_EXCL_LINE
25925 case value_t::number_integer: // LCOV_EXCL_LINE
25926 case value_t::number_unsigned: // LCOV_EXCL_LINE
25927 case value_t::number_float: // LCOV_EXCL_LINE
25928 case value_t::binary: // LCOV_EXCL_LINE
25929 case value_t::discarded: // LCOV_EXCL_LINE
25930 default: // LCOV_EXCL_LINE
25931 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
25932 }
25933 };
25934
25935 // wrapper for "remove" operation; remove value at ptr
25936 const auto operation_remove = [this, &result](json_pointer & ptr)
25937 {
25938 // get reference to parent of JSON pointer ptr
25939 const auto last_path = ptr.back();
25940 ptr.pop_back();
25941 basic_json& parent = result.at(ptr);
25942
25943 // remove child
25944 if (parent.is_object())
25945 {
25946 // perform range check
25947 auto it = parent.find(last_path);
25948 if (JSON_HEDLEY_LIKELY(it != parent.end()))
25949 {
25950 parent.erase(it);
25951 }
25952 else
25953 {
25954 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
25955 }
25956 }
25957 else if (parent.is_array())
25958 {
25959 // note erase performs range check
25960 parent.erase(json_pointer::array_index(last_path));
25961 }
25962 };
25963
25964 // type check: top level value must be an array
25965 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
25966 {
25967 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
25968 }
25969
25970 // iterate and apply the operations
25971 for (const auto& val : json_patch)
25972 {
25973 // wrapper to get a value for an operation
25974 const auto get_value = [&val](const std::string & op,
25975 const std::string & member,
25976 bool string_type) -> basic_json &
25977 {
25978 // find value
25979 auto it = val.m_value.object->find(member);
25980
25981 // context-sensitive error message
25982 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
25983
25984 // check if desired value is present
25985 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
25986 {
25987 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25988 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
25989 }
25990
25991 // check if result is of type string
25992 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
25993 {
25994 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
25995 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
25996 }
25997
25998 // no error: return value
25999 return it->second;
26000 };
26001
26002 // type check: every element of the array must be an object
26003 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
26004 {
26005 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
26006 }
26007
26008 // collect mandatory members
26009 const auto op = get_value("op", "op", true).template get<std::string>();
26010 const auto path = get_value(op, "path", true).template get<std::string>();
26011 json_pointer ptr(path);
26012
26013 switch (get_op(op))
26014 {
26015 case patch_operations::add:
26016 {
26017 operation_add(ptr, get_value("add", "value", false));
26018 break;
26019 }
26020
26021 case patch_operations::remove:
26022 {
26023 operation_remove(ptr);
26024 break;
26025 }
26026
26027 case patch_operations::replace:
26028 {
26029 // the "path" location must exist - use at()
26030 result.at(ptr) = get_value("replace", "value", false);
26031 break;
26032 }
26033
26034 case patch_operations::move:
26035 {
26036 const auto from_path = get_value("move", "from", true).template get<std::string>();
26037 json_pointer from_ptr(from_path);
26038
26039 // the "from" location must exist - use at()
26040 basic_json v = result.at(from_ptr);
26041
26042 // The move operation is functionally identical to a
26043 // "remove" operation on the "from" location, followed
26044 // immediately by an "add" operation at the target
26045 // location with the value that was just removed.
26046 operation_remove(from_ptr);
26047 operation_add(ptr, v);
26048 break;
26049 }
26050
26051 case patch_operations::copy:
26052 {
26053 const auto from_path = get_value("copy", "from", true).template get<std::string>();
26054 const json_pointer from_ptr(from_path);
26055
26056 // the "from" location must exist - use at()
26057 basic_json v = result.at(from_ptr);
26058
26059 // The copy is functionally identical to an "add"
26060 // operation at the target location using the value
26061 // specified in the "from" member.
26062 operation_add(ptr, v);
26063 break;
26064 }
26065
26066 case patch_operations::test:
26067 {
26068 bool success = false;
26069 JSON_TRY
26070 {
26071 // check if "value" matches the one at "path"
26072 // the "path" location must exist - use at()
26073 success = (result.at(ptr) == get_value("test", "value", false));
26074 }
26076 {
26077 // ignore out of range errors: success remains false
26078 }
26079
26080 // throw an exception if test fails
26081 if (JSON_HEDLEY_UNLIKELY(!success))
26082 {
26083 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
26084 }
26085
26086 break;
26087 }
26088
26089 case patch_operations::invalid:
26090 default:
26091 {
26092 // op must be "add", "remove", "replace", "move", "copy", or
26093 // "test"
26094 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
26095 }
26096 }
26097 }
26098
26099 return result;
26100 }
26101
26136 static basic_json diff(const basic_json& source, const basic_json& target,
26137 const std::string& path = "")
26138 {
26139 // the patch
26140 basic_json result(value_t::array);
26141
26142 // if the values are the same, return empty patch
26143 if (source == target)
26144 {
26145 return result;
26146 }
26147
26148 if (source.type() != target.type())
26149 {
26150 // different types: replace value
26151 result.push_back(
26152 {
26153 {"op", "replace"}, {"path", path}, {"value", target}
26154 });
26155 return result;
26156 }
26157
26158 switch (source.type())
26159 {
26160 case value_t::array:
26161 {
26162 // first pass: traverse common elements
26163 std::size_t i = 0;
26164 while (i < source.size() && i < target.size())
26165 {
26166 // recursive call to compare array values at index i
26167 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
26168 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26169 ++i;
26170 }
26171
26172 // i now reached the end of at least one array
26173 // in a second pass, traverse the remaining elements
26174
26175 // remove my remaining elements
26176 const auto end_index = static_cast<difference_type>(result.size());
26177 while (i < source.size())
26178 {
26179 // add operations in reverse order to avoid invalid
26180 // indices
26181 result.insert(result.begin() + end_index, object(
26182 {
26183 {"op", "remove"},
26184 {"path", path + "/" + std::to_string(i)}
26185 }));
26186 ++i;
26187 }
26188
26189 // add other remaining elements
26190 while (i < target.size())
26191 {
26192 result.push_back(
26193 {
26194 {"op", "add"},
26195 {"path", path + "/-"},
26196 {"value", target[i]}
26197 });
26198 ++i;
26199 }
26200
26201 break;
26202 }
26203
26204 case value_t::object:
26205 {
26206 // first pass: traverse this object's elements
26207 for (auto it = source.cbegin(); it != source.cend(); ++it)
26208 {
26209 // escape the key name to be used in a JSON patch
26210 const auto path_key = path + "/" + detail::escape(it.key());
26211
26212 if (target.find(it.key()) != target.end())
26213 {
26214 // recursive call to compare object values at key it
26215 auto temp_diff = diff(it.value(), target[it.key()], path_key);
26216 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26217 }
26218 else
26219 {
26220 // found a key that is not in o -> remove it
26221 result.push_back(object(
26222 {
26223 {"op", "remove"}, {"path", path_key}
26224 }));
26225 }
26226 }
26227
26228 // second pass: traverse other object's elements
26229 for (auto it = target.cbegin(); it != target.cend(); ++it)
26230 {
26231 if (source.find(it.key()) == source.end())
26232 {
26233 // found a key that is not in this -> add it
26234 const auto path_key = path + "/" + detail::escape(it.key());
26235 result.push_back(
26236 {
26237 {"op", "add"}, {"path", path_key},
26238 {"value", it.value()}
26239 });
26240 }
26241 }
26242
26243 break;
26244 }
26245
26246 case value_t::null:
26247 case value_t::string:
26248 case value_t::boolean:
26249 case value_t::number_integer:
26250 case value_t::number_unsigned:
26251 case value_t::number_float:
26252 case value_t::binary:
26253 case value_t::discarded:
26254 default:
26255 {
26256 // both primitive type: replace value
26257 result.push_back(
26258 {
26259 {"op", "replace"}, {"path", path}, {"value", target}
26260 });
26261 break;
26262 }
26263 }
26264
26265 return result;
26266 }
26267
26269
26271 // JSON Merge Patch functions //
26273
26276
26319 void merge_patch(const basic_json& apply_patch)
26320 {
26321 if (apply_patch.is_object())
26322 {
26323 if (!is_object())
26324 {
26325 *this = object();
26326 }
26327 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
26328 {
26329 if (it.value().is_null())
26330 {
26331 erase(it.key());
26332 }
26333 else
26334 {
26335 operator[](it.key()).merge_patch(it.value());
26336 }
26337 }
26338 }
26339 else
26340 {
26341 *this = apply_patch;
26342 }
26343 }
26344
26346};
26347
26359{
26360 return j.dump();
26361}
26362} // namespace nlohmann
26363
26365// nonmember support //
26367
26368// specialization of std::swap, and std::hash
26369namespace std
26370{
26371
26373template<>
26374struct hash<nlohmann::json>
26375{
26381 std::size_t operator()(const nlohmann::json& j) const
26382 {
26383 return nlohmann::detail::hash(j);
26384 }
26385};
26386
26390template<>
26392{
26398 nlohmann::detail::value_t rhs) const noexcept
26399 {
26400 return nlohmann::detail::operator<(lhs, rhs);
26401 }
26402};
26403
26404// C++20 prohibit function specialization in the std namespace.
26405#ifndef JSON_HAS_CPP_20
26406
26412template<>
26413inline void swap<nlohmann::json>(nlohmann::json& j1, nlohmann::json& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
26414 is_nothrow_move_constructible<nlohmann::json>::value&& // NOLINT(misc-redundant-expression)
26415 is_nothrow_move_assignable<nlohmann::json>::value
26416 )
26417{
26418 j1.swap(j2);
26419}
26420
26421#endif
26422
26423} // namespace std
26424
26439inline nlohmann::json operator "" _json(const char* s, std::size_t n)
26440{
26441 return nlohmann::json::parse(s, s + n);
26442}
26443
26458inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
26459{
26460 return nlohmann::json::json_pointer(std::string(s, n));
26461}
26462
26463// #include <nlohmann/detail/macro_unscope.hpp>
26464
26465
26466// restore clang diagnostic settings
26467#if defined(__clang__)
26468 #pragma clang diagnostic pop
26469#endif
26470
26471// clean up
26472#undef JSON_ASSERT
26473#undef JSON_INTERNAL_CATCH
26474#undef JSON_CATCH
26475#undef JSON_THROW
26476#undef JSON_TRY
26477#undef JSON_PRIVATE_UNLESS_TESTED
26478#undef JSON_HAS_CPP_11
26479#undef JSON_HAS_CPP_14
26480#undef JSON_HAS_CPP_17
26481#undef JSON_HAS_CPP_20
26482#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
26483#undef NLOHMANN_BASIC_JSON_TPL
26484#undef JSON_EXPLICIT
26485
26486// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
26487
26488
26489#undef JSON_HEDLEY_ALWAYS_INLINE
26490#undef JSON_HEDLEY_ARM_VERSION
26491#undef JSON_HEDLEY_ARM_VERSION_CHECK
26492#undef JSON_HEDLEY_ARRAY_PARAM
26493#undef JSON_HEDLEY_ASSUME
26494#undef JSON_HEDLEY_BEGIN_C_DECLS
26495#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
26496#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
26497#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
26498#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
26499#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
26500#undef JSON_HEDLEY_CLANG_HAS_FEATURE
26501#undef JSON_HEDLEY_CLANG_HAS_WARNING
26502#undef JSON_HEDLEY_COMPCERT_VERSION
26503#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
26504#undef JSON_HEDLEY_CONCAT
26505#undef JSON_HEDLEY_CONCAT3
26506#undef JSON_HEDLEY_CONCAT3_EX
26507#undef JSON_HEDLEY_CONCAT_EX
26508#undef JSON_HEDLEY_CONST
26509#undef JSON_HEDLEY_CONSTEXPR
26510#undef JSON_HEDLEY_CONST_CAST
26511#undef JSON_HEDLEY_CPP_CAST
26512#undef JSON_HEDLEY_CRAY_VERSION
26513#undef JSON_HEDLEY_CRAY_VERSION_CHECK
26514#undef JSON_HEDLEY_C_DECL
26515#undef JSON_HEDLEY_DEPRECATED
26516#undef JSON_HEDLEY_DEPRECATED_FOR
26517#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
26518#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
26519#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
26520#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
26521#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
26522#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
26523#undef JSON_HEDLEY_DIAGNOSTIC_POP
26524#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
26525#undef JSON_HEDLEY_DMC_VERSION
26526#undef JSON_HEDLEY_DMC_VERSION_CHECK
26527#undef JSON_HEDLEY_EMPTY_BASES
26528#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
26529#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
26530#undef JSON_HEDLEY_END_C_DECLS
26531#undef JSON_HEDLEY_FLAGS
26532#undef JSON_HEDLEY_FLAGS_CAST
26533#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
26534#undef JSON_HEDLEY_GCC_HAS_BUILTIN
26535#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
26536#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
26537#undef JSON_HEDLEY_GCC_HAS_EXTENSION
26538#undef JSON_HEDLEY_GCC_HAS_FEATURE
26539#undef JSON_HEDLEY_GCC_HAS_WARNING
26540#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
26541#undef JSON_HEDLEY_GCC_VERSION
26542#undef JSON_HEDLEY_GCC_VERSION_CHECK
26543#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
26544#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
26545#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
26546#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
26547#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
26548#undef JSON_HEDLEY_GNUC_HAS_FEATURE
26549#undef JSON_HEDLEY_GNUC_HAS_WARNING
26550#undef JSON_HEDLEY_GNUC_VERSION
26551#undef JSON_HEDLEY_GNUC_VERSION_CHECK
26552#undef JSON_HEDLEY_HAS_ATTRIBUTE
26553#undef JSON_HEDLEY_HAS_BUILTIN
26554#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
26555#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
26556#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
26557#undef JSON_HEDLEY_HAS_EXTENSION
26558#undef JSON_HEDLEY_HAS_FEATURE
26559#undef JSON_HEDLEY_HAS_WARNING
26560#undef JSON_HEDLEY_IAR_VERSION
26561#undef JSON_HEDLEY_IAR_VERSION_CHECK
26562#undef JSON_HEDLEY_IBM_VERSION
26563#undef JSON_HEDLEY_IBM_VERSION_CHECK
26564#undef JSON_HEDLEY_IMPORT
26565#undef JSON_HEDLEY_INLINE
26566#undef JSON_HEDLEY_INTEL_CL_VERSION
26567#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
26568#undef JSON_HEDLEY_INTEL_VERSION
26569#undef JSON_HEDLEY_INTEL_VERSION_CHECK
26570#undef JSON_HEDLEY_IS_CONSTANT
26571#undef JSON_HEDLEY_IS_CONSTEXPR_
26572#undef JSON_HEDLEY_LIKELY
26573#undef JSON_HEDLEY_MALLOC
26574#undef JSON_HEDLEY_MCST_LCC_VERSION
26575#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
26576#undef JSON_HEDLEY_MESSAGE
26577#undef JSON_HEDLEY_MSVC_VERSION
26578#undef JSON_HEDLEY_MSVC_VERSION_CHECK
26579#undef JSON_HEDLEY_NEVER_INLINE
26580#undef JSON_HEDLEY_NON_NULL
26581#undef JSON_HEDLEY_NO_ESCAPE
26582#undef JSON_HEDLEY_NO_RETURN
26583#undef JSON_HEDLEY_NO_THROW
26584#undef JSON_HEDLEY_NULL
26585#undef JSON_HEDLEY_PELLES_VERSION
26586#undef JSON_HEDLEY_PELLES_VERSION_CHECK
26587#undef JSON_HEDLEY_PGI_VERSION
26588#undef JSON_HEDLEY_PGI_VERSION_CHECK
26589#undef JSON_HEDLEY_PREDICT
26590#undef JSON_HEDLEY_PRINTF_FORMAT
26591#undef JSON_HEDLEY_PRIVATE
26592#undef JSON_HEDLEY_PUBLIC
26593#undef JSON_HEDLEY_PURE
26594#undef JSON_HEDLEY_REINTERPRET_CAST
26595#undef JSON_HEDLEY_REQUIRE
26596#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
26597#undef JSON_HEDLEY_REQUIRE_MSG
26598#undef JSON_HEDLEY_RESTRICT
26599#undef JSON_HEDLEY_RETURNS_NON_NULL
26600#undef JSON_HEDLEY_SENTINEL
26601#undef JSON_HEDLEY_STATIC_ASSERT
26602#undef JSON_HEDLEY_STATIC_CAST
26603#undef JSON_HEDLEY_STRINGIFY
26604#undef JSON_HEDLEY_STRINGIFY_EX
26605#undef JSON_HEDLEY_SUNPRO_VERSION
26606#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
26607#undef JSON_HEDLEY_TINYC_VERSION
26608#undef JSON_HEDLEY_TINYC_VERSION_CHECK
26609#undef JSON_HEDLEY_TI_ARMCL_VERSION
26610#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
26611#undef JSON_HEDLEY_TI_CL2000_VERSION
26612#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
26613#undef JSON_HEDLEY_TI_CL430_VERSION
26614#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
26615#undef JSON_HEDLEY_TI_CL6X_VERSION
26616#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
26617#undef JSON_HEDLEY_TI_CL7X_VERSION
26618#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
26619#undef JSON_HEDLEY_TI_CLPRU_VERSION
26620#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
26621#undef JSON_HEDLEY_TI_VERSION
26622#undef JSON_HEDLEY_TI_VERSION_CHECK
26623#undef JSON_HEDLEY_UNAVAILABLE
26624#undef JSON_HEDLEY_UNLIKELY
26625#undef JSON_HEDLEY_UNPREDICTABLE
26626#undef JSON_HEDLEY_UNREACHABLE
26627#undef JSON_HEDLEY_UNREACHABLE_RETURN
26628#undef JSON_HEDLEY_VERSION
26629#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
26630#undef JSON_HEDLEY_VERSION_DECODE_MINOR
26631#undef JSON_HEDLEY_VERSION_DECODE_REVISION
26632#undef JSON_HEDLEY_VERSION_ENCODE
26633#undef JSON_HEDLEY_WARNING
26634#undef JSON_HEDLEY_WARN_UNUSED_RESULT
26635#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
26636#undef JSON_HEDLEY_FALL_THROUGH
26637
26638
26639
26640#endif // INCLUDE_NLOHMANN_JSON_HPP_
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition XrdOucJson.hh:2339
#define JSON_HEDLEY_CONST
Definition XrdOucJson.hh:1670
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition XrdOucJson.hh:954
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition XrdOucJson.hh:1300
#define JSON_PRIVATE_UNLESS_TESTED
Definition XrdOucJson.hh:2302
#define NLOHMANN_JSON_VERSION_PATCH
Definition XrdOucJson.hh:35
#define JSON_HEDLEY_LIKELY(expr)
Definition XrdOucJson.hh:1565
#define JSON_HEDLEY_NON_NULL(...)
Definition XrdOucJson.hh:1458
#define JSON_INTERNAL_CATCH(exception)
Definition XrdOucJson.hh:2269
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition XrdOucJson.hh:1899
#define JSON_CATCH(exception)
Definition XrdOucJson.hh:2268
#define JSON_ASSERT(x)
Definition XrdOucJson.hh:2295
#define JSON_THROW(exception)
Definition XrdOucJson.hh:2266
#define NLOHMANN_JSON_VERSION_MAJOR
Definition XrdOucJson.hh:33
#define NLOHMANN_BASIC_JSON_TPL
Definition XrdOucJson.hh:2348
#define JSON_HEDLEY_UNLIKELY(expr)
Definition XrdOucJson.hh:1566
#define JSON_TRY
Definition XrdOucJson.hh:2267
#define NLOHMANN_JSON_VERSION_MINOR
Definition XrdOucJson.hh:34
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition XrdOucJson.hh:955
#define JSON_EXPLICIT
Definition XrdOucJson.hh:2512
#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
Definition XrdOucJson.hh:1248
#define JSON_HEDLEY_PURE
Definition XrdOucJson.hh:1639
a class to store JSON values
Definition XrdOucJson.hh:17582
ValueType & get_to(ValueType &v) const
Definition XrdOucJson.hh:20710
void insert(const_iterator first, const_iterator last)
inserts elements
Definition XrdOucJson.hh:23353
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition XrdOucJson.hh:20270
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition XrdOucJson.hh:18838
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition XrdOucJson.hh:22005
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition XrdOucJson.hh:22465
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition XrdOucJson.hh:22290
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
Definition XrdOucJson.hh:20324
number_unsigned_t number_unsigned
number (unsigned integer)
Definition XrdOucJson.hh:18394
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition XrdOucJson.hh:25619
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition XrdOucJson.hh:25591
friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
comparison: equal
Definition XrdOucJson.hh:23833
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition XrdOucJson.hh:21384
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition XrdOucJson.hh:20093
NumberIntegerType number_integer_t
a type for a number (integer)
Definition XrdOucJson.hh:18116
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition XrdOucJson.hh:23751
NLOHMANN_BASIC_JSON_TPL basic_json_t
workaround type for MSVC
Definition XrdOucJson.hh:17603
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 XrdOucJson.hh:24441
ReferenceType get_ref()
get a reference value (implicit)
Definition XrdOucJson.hh:20757
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition XrdOucJson.hh:24286
reference emplace_back(Args &&... args)
add an object to an array
Definition XrdOucJson.hh:23039
const_iterator find(KeyT &&key) const
find an element in a JSON object
Definition XrdOucJson.hh:21938
basic_json(const value_t v)
create an empty value with a given type
Definition XrdOucJson.hh:18879
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition XrdOucJson.hh:20258
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition XrdOucJson.hh:22688
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition XrdOucJson.hh:26136
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 XrdOucJson.hh:24991
void erase(const size_type idx)
remove element from a JSON array given an index
Definition XrdOucJson.hh:21868
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition XrdOucJson.hh:22319
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition XrdOucJson.hh:21040
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition XrdOucJson.hh:20989
iterator begin() noexcept
returns an iterator to the first element
Definition XrdOucJson.hh:22075
binary_t & get_binary()
Definition XrdOucJson.hh:20833
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition XrdOucJson.hh:19458
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition XrdOucJson.hh:24810
friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition XrdOucJson.hh:23844
json_value(object_t &&value)
constructor for rvalue objects
Definition XrdOucJson.hh:18499
basic_json(const JsonRef &ref)
Definition XrdOucJson.hh:19568
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition XrdOucJson.hh:24715
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 XrdOucJson.hh:19725
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition XrdOucJson.hh:19321
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition XrdOucJson.hh:18407
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
Definition XrdOucJson.hh:22261
void assert_invariant(bool check_parents=true) const noexcept
checks the class invariants
Definition XrdOucJson.hh:18658
json_value(string_t &&value)
constructor for rvalue strings
Definition XrdOucJson.hh:18487
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition XrdOucJson.hh:22186
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition XrdOucJson.hh:18403
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition XrdOucJson.hh:20318
reference back()
access the last element
Definition XrdOucJson.hh:21554
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition XrdOucJson.hh:20294
const binary_t & get_binary() const
Definition XrdOucJson.hh:20844
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition XrdOucJson.hh:20300
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition XrdOucJson.hh:24378
StringType string_t
a type for a string
Definition XrdOucJson.hh:18018
size_type size() const noexcept
returns the number of elements
Definition XrdOucJson.hh:22610
void push_back(const basic_json &val)
add an object to an array
Definition XrdOucJson.hh:22883
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition XrdOucJson.hh:17759
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition XrdOucJson.hh:21456
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition XrdOucJson.hh:23395
std::size_t size_type
a type to represent container sizes
Definition XrdOucJson.hh:17702
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition XrdOucJson.hh:20697
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition XrdOucJson.hh:17700
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition XrdOucJson.hh:19218
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition XrdOucJson.hh:21177
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition XrdOucJson.hh:18405
reference operator+=(basic_json &&val)
add an object to an array
Definition XrdOucJson.hh:22873
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition XrdOucJson.hh:19013
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition XrdOucJson.hh:17710
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition XrdOucJson.hh:25515
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition XrdOucJson.hh:17708
constexpr const binary_t * get_impl_ptr(const binary_t *) const noexcept
get a pointer to the value (binary)
Definition XrdOucJson.hh:20348
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition XrdOucJson.hh:25124
BooleanType boolean_t
a type for a boolean
Definition XrdOucJson.hh:18044
void push_back(initializer_list_t init)
add an object to an object
Definition XrdOucJson.hh:22991
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition XrdOucJson.hh:20247
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 XrdOucJson.hh:19823
static bool accept(IteratorType first, IteratorType last, const bool ignore_comments=false)
Definition XrdOucJson.hh:24385
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition XrdOucJson.hh:21621
static void to_bson(const basic_json &j, detail::output_adapter< std::uint8_t > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition XrdOucJson.hh:25006
friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
comparison: not equal
Definition XrdOucJson.hh:23878
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition XrdOucJson.hh:25499
constexpr bool is_structured() const noexcept
return whether type is structured
Definition XrdOucJson.hh:19934
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition XrdOucJson.hh:24057
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition XrdOucJson.hh:22085
friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
comparison: less than
Definition XrdOucJson.hh:24000
reference at(size_type idx)
access specified array element with bounds checking
Definition XrdOucJson.hh:20891
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
binary (stored with pointer to save storage)
Definition XrdOucJson.hh:19275
reference front()
access the first element
Definition XrdOucJson.hh:21510
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition XrdOucJson.hh:19907
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition XrdOucJson.hh:20065
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
Definition XrdOucJson.hh:24727
void swap(object_t &other)
exchanges the values
Definition XrdOucJson.hh:23593
constexpr bool is_object() const noexcept
return whether value is an object
Definition XrdOucJson.hh:20115
const_reference front() const
access the first element
Definition XrdOucJson.hh:21518
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition XrdOucJson.hh:19876
NumberFloatType number_float_t
a type for a number (floating-point)
Definition XrdOucJson.hh:18255
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition XrdOucJson.hh:17717
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition XrdOucJson.hh:24194
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition XrdOucJson.hh:24035
bool empty() const noexcept
checks whether the container is empty.
Definition XrdOucJson.hh:22530
json_value(value_t t)
constructor for empty values of a given type
Definition XrdOucJson.hh:18409
basic_json(const basic_json &other)
copy constructor
Definition XrdOucJson.hh:19595
~basic_json() noexcept
destructor
Definition XrdOucJson.hh:19759
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 XrdOucJson.hh:24913
basic_json(basic_json &&other) noexcept
move constructor
Definition XrdOucJson.hh:19687
friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition XrdOucJson.hh:24103
BasicJsonType get_impl(detail::priority_tag< 2 >) const
get special-case overload
Definition XrdOucJson.hh:20541
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
Definition XrdOucJson.hh:24928
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition XrdOucJson.hh:23867
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition XrdOucJson.hh:23211
friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition XrdOucJson.hh:24011
json_value m_value
the value of the current element
Definition XrdOucJson.hh:24602
boolean_t boolean
boolean
Definition XrdOucJson.hh:18390
void swap(typename binary_t::container_type &other)
exchanges the values
Definition XrdOucJson.hh:23673
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition XrdOucJson.hh:24127
void swap(array_t &other)
exchanges the values
Definition XrdOucJson.hh:23560
ValueType get_impl(detail::priority_tag< 0 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
Definition XrdOucJson.hh:20474
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition XrdOucJson.hh:22253
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition XrdOucJson.hh:19255
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition XrdOucJson.hh:22383
json_value(const string_t &value)
constructor for strings
Definition XrdOucJson.hh:18481
json_value(const binary_t &value)
constructor for binary arrays (internal type)
Definition XrdOucJson.hh:18529
ReferenceType get_ref() const
get a reference value (implicit)
Definition XrdOucJson.hh:20770
json_value(const array_t &value)
constructor for arrays
Definition XrdOucJson.hh:18505
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition XrdOucJson.hh:23259
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition XrdOucJson.hh:20653
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition XrdOucJson.hh:25705
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition XrdOucJson.hh:22156
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition XrdOucJson.hh:26319
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition XrdOucJson.hh:20411
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition XrdOucJson.hh:22473
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
Definition XrdOucJson.hh:23312
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition XrdOucJson.hh:17965
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition XrdOucJson.hh:20721
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition XrdOucJson.hh:24081
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
Definition XrdOucJson.hh:20312
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition XrdOucJson.hh:20288
void destroy(value_t t)
Definition XrdOucJson.hh:18540
json_value(const object_t &value)
constructor for objects
Definition XrdOucJson.hh:18493
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition XrdOucJson.hh:21736
json_value(typename binary_t::container_type &&value)
constructor for rvalue binary arrays
Definition XrdOucJson.hh:18523
json_value(boolean_t v) noexcept
constructor for booleans
Definition XrdOucJson.hh:18401
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition XrdOucJson.hh:19978
iterator end() noexcept
returns an iterator to one past the last element
Definition XrdOucJson.hh:22146
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 XrdOucJson.hh:23497
void clear() noexcept
clears the contents
Definition XrdOucJson.hh:22767
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition XrdOucJson.hh:24149
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition XrdOucJson.hh:25284
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition XrdOucJson.hh:20181
static JSON_HEDLEY_RETURNS_NON_NULL T * create(Args &&... args)
helper for exception-safe object creation
Definition XrdOucJson.hh:18334
binary_t * binary
binary (stored with pointer to save storage)
Definition XrdOucJson.hh:18388
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition XrdOucJson.hh:19365
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition XrdOucJson.hh:23182
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition XrdOucJson.hh:25401
reference operator[](size_type idx)
access specified array element
Definition XrdOucJson.hh:21086
friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than
Definition XrdOucJson.hh:24092
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
Serializes the given JSON object j to BSON and forwards the corresponding BSON-representation to the ...
Definition XrdOucJson.hh:25014
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
Definition XrdOucJson.hh:23446
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition XrdOucJson.hh:25662
void swap(binary_t &other)
exchanges the values
Definition XrdOucJson.hh:23659
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition XrdOucJson.hh:17719
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition XrdOucJson.hh:25385
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition XrdOucJson.hh:17644
friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition XrdOucJson.hh:23889
static void to_ubjson(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
Definition XrdOucJson.hh:24922
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition XrdOucJson.hh:22224
void swap(string_t &other)
exchanges the values
Definition XrdOucJson.hh:23626
const_reference back() const
access the last element
Definition XrdOucJson.hh:21564
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition XrdOucJson.hh:23920
ValueType get_impl(detail::priority_tag< 1 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >())))
get a value (explicit); special case
Definition XrdOucJson.hh:20516
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
binary (stored with pointer to save storage)
Definition XrdOucJson.hh:19265
constexpr bool is_string() const noexcept
return whether value is a string
Definition XrdOucJson.hh:20159
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition XrdOucJson.hh:20306
constexpr bool is_array() const noexcept
return whether value is an array
Definition XrdOucJson.hh:20137
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition XrdOucJson.hh:23121
basic_json flatten() const
return flattened JSON value
Definition XrdOucJson.hh:25732
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
Definition XrdOucJson.hh:20336
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition XrdOucJson.hh:20276
friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than or equal
Definition XrdOucJson.hh:24138
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition XrdOucJson.hh:24564
void push_back(basic_json &&val)
add an object to an array
Definition XrdOucJson.hh:22846
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition XrdOucJson.hh:25141
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition XrdOucJson.hh:21972
json_value(const typename binary_t::container_type &value)
constructor for binary arrays
Definition XrdOucJson.hh:18517
json_value()=default
default constructor (for null values)
constexpr bool is_number() const noexcept
return whether value is a number
Definition XrdOucJson.hh:20008
number_float_t number_float
number (floating-point)
Definition XrdOucJson.hh:18396
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition XrdOucJson.hh:20282
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition XrdOucJson.hh:24218
std::less< StringType > object_comparator_t
Definition XrdOucJson.hh:17829
string_t * string
string (stored with pointer to save storage)
Definition XrdOucJson.hh:18386
reference operator+=(initializer_list_t init)
add an object to an object
Definition XrdOucJson.hh:23009
::nlohmann::detail::output_adapter_t< CharType > output_adapter_t
Definition XrdOucJson.hh:17632
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition XrdOucJson.hh:20037
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition XrdOucJson.hh:17652
static void to_cbor(const basic_json &j, detail::output_adapter< std::uint8_t > o)
Definition XrdOucJson.hh:24722
detail::value_t value_t
Definition XrdOucJson.hh:17642
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition XrdOucJson.hh:20330
json_value(binary_t &&value)
constructor for rvalue binary arrays (internal type)
Definition XrdOucJson.hh:18535
friend class ::nlohmann::detail::parser
Definition XrdOucJson.hh:17588
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
Definition XrdOucJson.hh:24822
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition XrdOucJson.hh:21226
iterator set_parents(iterator it, typename iterator::difference_type count)
Definition XrdOucJson.hh:18716
iterator find(KeyT &&key)
find an element in a JSON object
Definition XrdOucJson.hh:21921
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition XrdOucJson.hh:18903
const_reference operator[](size_type idx) const
access specified array element
Definition XrdOucJson.hh:21139
array_t * array
array (stored with pointer to save storage)
Definition XrdOucJson.hh:18384
AllocatorType< basic_json > allocator_type
the allocator type
Definition XrdOucJson.hh:17705
basic_json get_impl(detail::priority_tag< 3 >) const
get special-case overload
Definition XrdOucJson.hh:20564
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition XrdOucJson.hh:18326
JSONSerializer< T, SFINAE > json_serializer
Definition XrdOucJson.hh:17646
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition XrdOucJson.hh:22935
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a pair of character iterators
Definition XrdOucJson.hh:24324
number_integer_t number_integer
number (integer)
Definition XrdOucJson.hh:18392
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition XrdOucJson.hh:22036
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition XrdOucJson.hh:25268
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition XrdOucJson.hh:25830
string_t value(const typename object_t::key_type &key, const char *default_value) const
overload for a default value of type const char*
Definition XrdOucJson.hh:21406
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 XrdOucJson.hh:18975
void set_parents()
Definition XrdOucJson.hh:18679
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition XrdOucJson.hh:25769
reference set_parent(reference j, std::size_t old_capacity=std::size_t(-1))
Definition XrdOucJson.hh:18729
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition XrdOucJson.hh:18187
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition XrdOucJson.hh:22960
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition XrdOucJson.hh:22115
friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
comparison: less than or equal
Definition XrdOucJson.hh:24046
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition XrdOucJson.hh:24520
static ::nlohmann::detail::parser< basic_json, InputAdapterType > parser(InputAdapterType adapter, detail::parser_callback_t< basic_json >cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
Definition XrdOucJson.hh:17610
json_value(array_t &&value)
constructor for rvalue arrays
Definition XrdOucJson.hh:18511
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 XrdOucJson.hh:19137
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition XrdOucJson.hh:20938
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition XrdOucJson.hh:23160
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition XrdOucJson.hh:20208
constexpr auto get_impl(detail::priority_tag< 4 >) const noexcept -> decltype(std::declval< const basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition XrdOucJson.hh:20577
constexpr bool is_null() const noexcept
return whether value is null
Definition XrdOucJson.hh:19956
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition XrdOucJson.hh:23530
binary_t * get_impl_ptr(binary_t *) noexcept
get a pointer to the value (binary)
Definition XrdOucJson.hh:20342
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > > > object_t
a type for an object
Definition XrdOucJson.hh:17919
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 XrdOucJson.hh:20612
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition XrdOucJson.hh:23089
static void to_msgpack(const basic_json &j, detail::output_adapter< std::uint8_t > o)
Definition XrdOucJson.hh:24817
reference operator+=(const basic_json &val)
add an object to an array
Definition XrdOucJson.hh:22909
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition XrdOucJson.hh:21833
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition XrdOucJson.hh:20365
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition XrdOucJson.hh:19392
static allocator_type get_allocator()
returns the allocator associated with the container
Definition XrdOucJson.hh:17727
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition XrdOucJson.hh:20264
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 XrdOucJson.hh:20424
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition XrdOucJson.hh:22216
an internal type for a backed binary type
Definition XrdOucJson.hh:5033
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition XrdOucJson.hh:5052
BinaryType container_type
the type of the underlying container
Definition XrdOucJson.hh:5036
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition XrdOucJson.hh:5044
bool m_has_subtype
Definition XrdOucJson.hh:5174
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition XrdOucJson.hh:5048
bool operator!=(const byte_container_with_subtype &rhs) const
Definition XrdOucJson.hh:5070
void clear_subtype() noexcept
clears the binary subtype
Definition XrdOucJson.hh:5166
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition XrdOucJson.hh:5040
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition XrdOucJson.hh:5058
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition XrdOucJson.hh:5142
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition XrdOucJson.hh:5093
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition XrdOucJson.hh:5121
std::uint64_t subtype_type
the type of the subtype
Definition XrdOucJson.hh:5038
subtype_type m_subtype
Definition XrdOucJson.hh:5173
bool operator==(const byte_container_with_subtype &rhs) const
Definition XrdOucJson.hh:5064
deserialization of CBOR, MessagePack, and UBJSON values
Definition XrdOucJson.hh:8354
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition XrdOucJson.hh:8356
bool get_msgpack_array(const std::size_t len)
Definition XrdOucJson.hh:10045
binary_reader & operator=(const binary_reader &)=delete
bool get_bson_string(const NumberType len, string_t &result)
Parses a zero-terminated string of length len from the BSON input.
Definition XrdOucJson.hh:8508
bool parse_bson_element_internal(const char_int_type element_type, const std::size_t element_type_parse_position)
Read a BSON document element of the given element_type.
Definition XrdOucJson.hh:8555
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
Definition XrdOucJson.hh:8671
char_int_type get_ignore_noop()
Definition XrdOucJson.hh:10618
bool get_ubjson_high_precision_number()
Definition XrdOucJson.hh:10533
binary_reader(InputAdapterType &&adapter) noexcept
create a binary reader
Definition XrdOucJson.hh:8370
typename BasicJsonType::number_integer_t number_integer_t
Definition XrdOucJson.hh:8355
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
Definition XrdOucJson.hh:8478
bool get_cbor_array(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition XrdOucJson.hh:9378
bool get_msgpack_binary(binary_t &result)
reads a MessagePack byte array
Definition XrdOucJson.hh:9934
bool get_cbor_object(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition XrdOucJson.hh:9416
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
Definition XrdOucJson.hh:10123
SAX json_sax_t
Definition XrdOucJson.hh:8360
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
Definition XrdOucJson.hh:8633
bool parse_cbor_internal(const bool get_char, const cbor_tag_handler_t tag_handler)
Definition XrdOucJson.hh:8701
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
Definition XrdOucJson.hh:10686
bool get_cbor_string(string_t &result)
reads a CBOR string
Definition XrdOucJson.hh:9189
InputAdapterType ia
input adapter
Definition XrdOucJson.hh:10803
bool get_binary(const input_format_t format, const NumberType len, binary_t &result)
create a byte array by reading bytes from the input
Definition XrdOucJson.hh:10719
bool parse_ubjson_internal(const bool get_char=true)
Definition XrdOucJson.hh:10104
bool unexpect_eof(const input_format_t format, const char *context) const
Definition XrdOucJson.hh:10743
binary_reader & operator=(binary_reader &&)=default
bool get_ubjson_size_type(std::pair< std::size_t, char_int_type > &result)
determine the type and size for a container
Definition XrdOucJson.hh:10254
std::string get_token_string() const
Definition XrdOucJson.hh:10756
bool get_ubjson_value(const char_int_type prefix)
Definition XrdOucJson.hh:10295
typename BasicJsonType::string_t string_t
Definition XrdOucJson.hh:8358
bool get_msgpack_object(const std::size_t len)
Definition XrdOucJson.hh:10067
bool get_bson_binary(const NumberType len, binary_t &result)
Parses a byte array input of length len from the BSON input.
Definition XrdOucJson.hh:8529
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
Definition XrdOucJson.hh:10769
std::size_t chars_read
the number of characters read
Definition XrdOucJson.hh:10809
typename std::char_traits< char_type >::int_type char_int_type
Definition XrdOucJson.hh:8362
binary_reader(const binary_reader &)=delete
char_int_type current
the current character
Definition XrdOucJson.hh:10806
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition XrdOucJson.hh:8391
json_sax_t * sax
the SAX parser
Definition XrdOucJson.hh:10815
bool get_ubjson_size_value(std::size_t &result)
Definition XrdOucJson.hh:10177
typename InputAdapterType::char_type char_type
Definition XrdOucJson.hh:8361
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
Definition XrdOucJson.hh:8453
bool get_number(const input_format_t format, NumberType &result)
Definition XrdOucJson.hh:10643
bool get_cbor_binary(binary_t &result)
reads a CBOR byte array
Definition XrdOucJson.hh:9284
binary_reader(binary_reader &&)=default
typename BasicJsonType::binary_t binary_t
Definition XrdOucJson.hh:8359
char_int_type get()
get next character from the input
Definition XrdOucJson.hh:10609
const bool is_little_endian
whether we can assume little endianess
Definition XrdOucJson.hh:10812
bool get_msgpack_string(string_t &result)
reads a MessagePack string
Definition XrdOucJson.hh:9852
bool get_ubjson_object()
Definition XrdOucJson.hh:10458
bool parse_msgpack_internal()
Definition XrdOucJson.hh:9472
typename BasicJsonType::number_float_t number_float_t
Definition XrdOucJson.hh:8357
bool get_ubjson_array()
Definition XrdOucJson.hh:10396
serialization to CBOR and MessagePack values
Definition XrdOucJson.hh:13601
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
Definition XrdOucJson.hh:14677
void write_number_with_ubjson_prefix(const NumberType n, const bool add_prefix)
Definition XrdOucJson.hh:14868
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition XrdOucJson.hh:14299
static std::size_t calc_bson_entry_header_size(const string_t &name, const BasicJsonType &j)
Definition XrdOucJson.hh:14507
static constexpr CharType get_ubjson_float_prefix(double)
Definition XrdOucJson.hh:15094
void write_bson_entry_header(const string_t &name, const std::uint8_t element_type)
Writes the given element_type and name to the output adapter.
Definition XrdOucJson.hh:14522
static std::size_t calc_bson_element_size(const string_t &name, const BasicJsonType &j)
Calculates the size necessary to serialize the JSON value j with its name.
Definition XrdOucJson.hh:14711
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
Definition XrdOucJson.hh:14544
void write_bson_object(const typename BasicJsonType::object_t &value)
Definition XrdOucJson.hh:14821
typename BasicJsonType::string_t string_t
Definition XrdOucJson.hh:13602
static constexpr CharType get_cbor_float_prefix(float)
Definition XrdOucJson.hh:14837
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition XrdOucJson.hh:15194
typename BasicJsonType::binary_t binary_t
Definition XrdOucJson.hh:13603
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition XrdOucJson.hh:13612
static constexpr CharType get_msgpack_float_prefix(double)
Definition XrdOucJson.hh:14856
CharType ubjson_prefix(const BasicJsonType &j) const noexcept
determine the type prefix of container values
Definition XrdOucJson.hh:15008
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
Definition XrdOucJson.hh:14594
static CharType to_char_type(std::uint8_t x) noexcept
Definition XrdOucJson.hh:15172
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
Definition XrdOucJson.hh:14562
void write_bson_object_entry(const string_t &name, const typename BasicJsonType::object_t &value)
Writes a BSON element with key name and object value.
Definition XrdOucJson.hh:14644
static constexpr CharType get_ubjson_float_prefix(float)
Definition XrdOucJson.hh:15089
void write_number(const NumberType n)
Definition XrdOucJson.hh:15115
void write_bson_element(const string_t &name, const BasicJsonType &j)
Serializes the JSON value j to BSON and associates it with the key name.
Definition XrdOucJson.hh:14759
void write_bson_binary(const string_t &name, const binary_t &value)
Writes a BSON element with key name and binary value value.
Definition XrdOucJson.hh:14696
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
Definition XrdOucJson.hh:14576
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t &value)
Definition XrdOucJson.hh:14669
void write_bson(const BasicJsonType &j)
Definition XrdOucJson.hh:13621
void write_cbor(const BasicJsonType &j)
Definition XrdOucJson.hh:13650
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
Definition XrdOucJson.hh:14612
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition XrdOucJson.hh:15165
typename BasicJsonType::number_float_t number_float_t
Definition XrdOucJson.hh:13604
void write_bson_unsigned(const string_t &name, const BasicJsonType &j)
Writes a BSON element with key name and unsigned value.
Definition XrdOucJson.hh:14622
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
Calculates the size of the BSON serialization of the given JSON-object j.
Definition XrdOucJson.hh:14806
static constexpr CharType get_msgpack_float_prefix(float)
Definition XrdOucJson.hh:14851
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
Definition XrdOucJson.hh:14534
void write_msgpack(const BasicJsonType &j)
Definition XrdOucJson.hh:13974
void write_compact_float(const number_float_t n, detail::input_format_t format)
Definition XrdOucJson.hh:15131
static std::size_t calc_bson_string_size(const string_t &value)
Definition XrdOucJson.hh:14554
static std::size_t calc_bson_integer_size(const std::int64_t value)
Definition XrdOucJson.hh:14584
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
Definition XrdOucJson.hh:14654
static constexpr CharType get_cbor_float_prefix(double)
Definition XrdOucJson.hh:14842
general exception of the basic_json class
Definition XrdOucJson.hh:2650
const int id
the id of the exception
Definition XrdOucJson.hh:2659
static std::string diagnostics(const BasicJsonType &leaf_element)
Definition XrdOucJson.hh:2671
static std::string name(const std::string &ename, int id_)
Definition XrdOucJson.hh:2665
std::runtime_error m
an exception object as storage for error messages
Definition XrdOucJson.hh:2736
const char * what() const noexcept override
returns the explanatory string
Definition XrdOucJson.hh:2653
Definition XrdOucJson.hh:5369
std::FILE * m_file
the file pointer to read from
Definition XrdOucJson.hh:5392
file_input_adapter(const file_input_adapter &)=delete
file_input_adapter(file_input_adapter &&) noexcept=default
char char_type
Definition XrdOucJson.hh:5371
std::char_traits< char >::int_type get_character() noexcept
Definition XrdOucJson.hh:5385
Definition XrdOucJson.hh:5406
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition XrdOucJson.hh:5429
~input_stream_adapter()
Definition XrdOucJson.hh:5410
input_stream_adapter & operator=(input_stream_adapter &)=delete
input_stream_adapter(const input_stream_adapter &)=delete
std::istream * is
the associated input stream
Definition XrdOucJson.hh:5452
char char_type
Definition XrdOucJson.hh:5408
input_stream_adapter & operator=(input_stream_adapter &&)=delete
std::streambuf * sb
Definition XrdOucJson.hh:5453
std::char_traits< char >::int_type get_character()
Definition XrdOucJson.hh:5439
input_stream_adapter(std::istream &i)
Definition XrdOucJson.hh:5420
exception indicating errors with iterators
Definition XrdOucJson.hh:2873
static invalid_iterator create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition XrdOucJson.hh:2876
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition XrdOucJson.hh:11531
bool operator<(const iter_impl &other) const
comparison: smaller
Definition XrdOucJson.hh:11994
iter_impl operator-(difference_type i) const
subtract from iterator
Definition XrdOucJson.hh:12124
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition XrdOucJson.hh:11985
iter_impl const operator--(int)
post-decrement (it–)
Definition XrdOucJson.hh:11897
void set_end() noexcept
set the iterator past the last value
Definition XrdOucJson.hh:11721
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition XrdOucJson.hh:11558
iter_impl & operator--()
pre-decrement (–it)
Definition XrdOucJson.hh:11908
difference_type operator-(const iter_impl &other) const
return difference
Definition XrdOucJson.hh:12135
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition XrdOucJson.hh:11640
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition XrdOucJson.hh:11567
reference operator*() const
return a reference to the value pointed to by the iterator
Definition XrdOucJson.hh:11760
iter_impl(iter_impl &&) noexcept=default
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition XrdOucJson.hh:12047
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition XrdOucJson.hh:11562
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition XrdOucJson.hh:11665
pointer operator->() const
dereference the iterator
Definition XrdOucJson.hh:11804
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition XrdOucJson.hh:11630
iter_impl const operator++(int)
post-increment (it++)
Definition XrdOucJson.hh:11846
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition XrdOucJson.hh:11655
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition XrdOucJson.hh:12227
iter_impl operator+(difference_type i) const
add to iterator
Definition XrdOucJson.hh:12102
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition XrdOucJson.hh:12113
const object_t::key_type & key() const
return the key of an object iterator
Definition XrdOucJson.hh:12202
bool operator==(const IterImpl &other) const
comparison: equal
Definition XrdOucJson.hh:11949
bool operator>(const iter_impl &other) const
comparison: greater than
Definition XrdOucJson.hh:12038
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition XrdOucJson.hh:11556
reference value() const
return the value of an iterator
Definition XrdOucJson.hh:12218
typename BasicJsonType::object_t object_t
Definition XrdOucJson.hh:11540
friend other_iter_impl
allow basic_json to access private members
Definition XrdOucJson.hh:11535
iter_impl & operator++()
pre-increment (++it)
Definition XrdOucJson.hh:11857
friend BasicJsonType
Definition XrdOucJson.hh:11536
reference operator[](difference_type n) const
access to successor
Definition XrdOucJson.hh:12164
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition XrdOucJson.hh:12029
std::bidirectional_iterator_tag iterator_category
Definition XrdOucJson.hh:11553
iter_impl & operator+=(difference_type i)
add to iterator
Definition XrdOucJson.hh:12056
typename BasicJsonType::array_t array_t
Definition XrdOucJson.hh:11541
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition XrdOucJson.hh:12093
Definition XrdOucJson.hh:4373
IteratorType anchor
the iterator
Definition XrdOucJson.hh:4384
std::input_iterator_tag iterator_category
Definition XrdOucJson.hh:4379
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition XrdOucJson.hh:4380
const string_type empty_str
an empty string (to return a reference for primitive values)
Definition XrdOucJson.hh:4392
iteration_proxy_value(IteratorType it) noexcept
Definition XrdOucJson.hh:4395
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition XrdOucJson.hh:4421
std::size_t array_index_last
last stringified array index
Definition XrdOucJson.hh:4388
string_type array_index_str
a string representation of the array index
Definition XrdOucJson.hh:4390
IteratorType::reference value() const
return value of the iterator
Definition XrdOucJson.hh:4463
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition XrdOucJson.hh:4406
std::size_t array_index
an index for arrays (used to create key names)
Definition XrdOucJson.hh:4386
iteration_proxy_value & operator*()
dereference operator (needed for range-based for)
Definition XrdOucJson.hh:4400
std::ptrdiff_t difference_type
Definition XrdOucJson.hh:4375
const string_type & key() const
return key of the iterator
Definition XrdOucJson.hh:4427
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition XrdOucJson.hh:4415
proxy class for the items() function
Definition XrdOucJson.hh:4471
iteration_proxy_value< IteratorType > begin() noexcept
return iterator begin (needed for range-based for)
Definition XrdOucJson.hh:4482
iteration_proxy_value< IteratorType > end() noexcept
return iterator end (needed for range-based for)
Definition XrdOucJson.hh:4488
IteratorType::reference container
the container to iterate
Definition XrdOucJson.hh:4474
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition XrdOucJson.hh:4478
Definition XrdOucJson.hh:5461
typename std::iterator_traits< IteratorType >::value_type char_type
Definition XrdOucJson.hh:5463
IteratorType end
Definition XrdOucJson.hh:5483
IteratorType current
Definition XrdOucJson.hh:5482
iterator_input_adapter(IteratorType first, IteratorType last)
Definition XrdOucJson.hh:5465
std::char_traits< char_type >::int_type get_character()
Definition XrdOucJson.hh:5469
bool empty() const
Definition XrdOucJson.hh:5488
Definition XrdOucJson.hh:13367
value_type const * value_ref
Definition XrdOucJson.hh:13418
json_ref(json_ref &&) noexcept=default
value_type owned_value
Definition XrdOucJson.hh:13417
value_type const & operator*() const
Definition XrdOucJson.hh:13406
BasicJsonType value_type
Definition XrdOucJson.hh:13369
json_ref(Args &&... args)
Definition XrdOucJson.hh:13386
json_ref(const value_type &value)
Definition XrdOucJson.hh:13375
value_type const * operator->() const
Definition XrdOucJson.hh:13411
json_ref(std::initializer_list< json_ref > init)
Definition XrdOucJson.hh:13379
json_ref(value_type &&value)
Definition XrdOucJson.hh:13371
value_type moved_or_copied() const
Definition XrdOucJson.hh:13397
a template for a reverse iterator class
Definition XrdOucJson.hh:12269
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition XrdOucJson.hh:12278
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition XrdOucJson.hh:12297
typename Base::reference reference
the reference type for the pointed-to element
Definition XrdOucJson.hh:12275
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition XrdOucJson.hh:12321
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition XrdOucJson.hh:12309
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition XrdOucJson.hh:12273
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition XrdOucJson.hh:12282
reference operator[](difference_type n) const
access to successor
Definition XrdOucJson.hh:12333
std::ptrdiff_t difference_type
Definition XrdOucJson.hh:12271
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition XrdOucJson.hh:12327
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition XrdOucJson.hh:12315
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition XrdOucJson.hh:12285
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition XrdOucJson.hh:12339
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition XrdOucJson.hh:12303
reference value() const
return the value of an iterator
Definition XrdOucJson.hh:12346
json_reverse_iterator & operator++()
pre-increment (++it)
Definition XrdOucJson.hh:12291
Definition XrdOucJson.hh:6454
bool end_array()
Definition XrdOucJson.hh:6517
typename BasicJsonType::string_t string_t
Definition XrdOucJson.hh:6459
bool binary(binary_t &)
Definition XrdOucJson.hh:6492
bool boolean(bool)
Definition XrdOucJson.hh:6467
typename BasicJsonType::number_integer_t number_integer_t
Definition XrdOucJson.hh:6456
typename BasicJsonType::number_float_t number_float_t
Definition XrdOucJson.hh:6458
typename BasicJsonType::binary_t binary_t
Definition XrdOucJson.hh:6460
bool key(string_t &)
Definition XrdOucJson.hh:6502
bool start_object(std::size_t=std::size_t(-1))
Definition XrdOucJson.hh:6497
bool start_array(std::size_t=std::size_t(-1))
Definition XrdOucJson.hh:6512
bool end_object()
Definition XrdOucJson.hh:6507
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition XrdOucJson.hh:6522
bool number_integer(number_integer_t)
Definition XrdOucJson.hh:6472
bool string(string_t &)
Definition XrdOucJson.hh:6487
bool number_unsigned(number_unsigned_t)
Definition XrdOucJson.hh:6477
bool null()
Definition XrdOucJson.hh:6462
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition XrdOucJson.hh:6457
bool number_float(number_float_t, const string_t &)
Definition XrdOucJson.hh:6482
typename BasicJsonType::string_t string_t
Definition XrdOucJson.hh:6152
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
bool start_object(std::size_t len)
Definition XrdOucJson.hh:6214
bool key(string_t &val)
Definition XrdOucJson.hh:6232
constexpr bool is_errored() const
Definition XrdOucJson.hh:6347
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition XrdOucJson.hh:6150
typename BasicJsonType::number_integer_t number_integer_t
Definition XrdOucJson.hh:6149
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
Definition XrdOucJson.hh:6369
bool null()
Definition XrdOucJson.hh:6172
typename BasicJsonType::parser_callback_t parser_callback_t
Definition XrdOucJson.hh:6154
bool start_array(std::size_t len)
Definition XrdOucJson.hh:6285
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition XrdOucJson.hh:6153
bool binary(binary_t &val)
Definition XrdOucJson.hh:6208
bool number_integer(number_integer_t val)
Definition XrdOucJson.hh:6184
BasicJsonType & root
the parsed JSON value
Definition XrdOucJson.hh:6433
typename BasicJsonType::number_float_t number_float_t
Definition XrdOucJson.hh:6151
bool end_array()
Definition XrdOucJson.hh:6302
typename BasicJsonType::parse_event_t parse_event_t
Definition XrdOucJson.hh:6155
bool boolean(bool val)
Definition XrdOucJson.hh:6178
bool number_unsigned(number_unsigned_t val)
Definition XrdOucJson.hh:6190
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
bool string(string_t &val)
Definition XrdOucJson.hh:6202
bool number_float(number_float_t val, const string_t &)
Definition XrdOucJson.hh:6196
bool end_object()
Definition XrdOucJson.hh:6249
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition XrdOucJson.hh:6335
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition XrdOucJson.hh:6157
SAX implementation to create a JSON value from SAX events.
Definition XrdOucJson.hh:5973
bool start_array(std::size_t len)
Definition XrdOucJson.hh:6065
json_sax_dom_parser(const json_sax_dom_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition XrdOucJson.hh:5979
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
bool number_unsigned(number_unsigned_t val)
Definition XrdOucJson.hh:6015
typename BasicJsonType::number_integer_t number_integer_t
Definition XrdOucJson.hh:5975
bool boolean(bool val)
Definition XrdOucJson.hh:6003
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition XrdOucJson.hh:6085
JSON_HEDLEY_RETURNS_NON_NULL BasicJsonType * handle_value(Value &&v)
Definition XrdOucJson.hh:6111
bool string(string_t &val)
Definition XrdOucJson.hh:6027
bool end_object()
Definition XrdOucJson.hh:6058
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition XrdOucJson.hh:5976
bool start_object(std::size_t len)
Definition XrdOucJson.hh:6039
bool null()
Definition XrdOucJson.hh:5997
bool binary(binary_t &val)
Definition XrdOucJson.hh:6033
constexpr bool is_errored() const
Definition XrdOucJson.hh:6097
bool key(string_t &val)
Definition XrdOucJson.hh:6051
json_sax_dom_parser(json_sax_dom_parser &&)=default
typename BasicJsonType::number_float_t number_float_t
Definition XrdOucJson.hh:5977
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
BasicJsonType & root
the parsed JSON value
Definition XrdOucJson.hh:6134
bool number_float(number_float_t val, const string_t &)
Definition XrdOucJson.hh:6021
bool end_array()
Definition XrdOucJson.hh:6077
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition XrdOucJson.hh:5986
typename BasicJsonType::string_t string_t
Definition XrdOucJson.hh:5978
bool number_integer(number_integer_t val)
Definition XrdOucJson.hh:6009
Definition XrdOucJson.hh:6561
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition XrdOucJson.hh:6588
token_type
token types for the parser
Definition XrdOucJson.hh:6565
@ value_float
an floating point number – use get_number_float() for actual value
@ begin_array
the character for array begin [
@ value_string
a string – use get_string() for actual value
@ end_array
the character for array end ]
@ uninitialized
indicating the scanner is uninitialized
@ parse_error
indicating a parse error
@ value_integer
a signed integer – use get_number_integer() for actual value
@ value_separator
the value separator ,
@ end_object
the character for object end }
@ begin_object
the character for object begin {
@ value_unsigned
an unsigned integer – use get_number_unsigned() for actual value
@ end_of_input
indicating the end of the input buffer
@ literal_or_value
a literal or the begin of a value (only for diagnostics)
lexical analysis
Definition XrdOucJson.hh:6638
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition XrdOucJson.hh:7956
number_float_t value_float
Definition XrdOucJson.hh:8151
const bool ignore_comments
whether comments should be ignored (true) or signaled as errors (false)
Definition XrdOucJson.hh:8128
void add(char_int_type c)
add a character to token_buffer
Definition XrdOucJson.hh:7927
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition XrdOucJson.hh:7846
token_type scan()
Definition XrdOucJson.hh:8035
bool next_unget
whether the next get() call should just return current
Definition XrdOucJson.hh:8134
char_int_type current
the current character
Definition XrdOucJson.hh:8131
typename BasicJsonType::number_float_t number_float_t
Definition XrdOucJson.hh:6641
void skip_whitespace()
Definition XrdOucJson.hh:8026
typename std::char_traits< char_type >::int_type char_int_type
Definition XrdOucJson.hh:6644
static JSON_HEDLEY_PURE char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition XrdOucJson.hh:6669
number_integer_t value_integer
Definition XrdOucJson.hh:8149
InputAdapterType ia
input adapter
Definition XrdOucJson.hh:8125
typename BasicJsonType::number_integer_t number_integer_t
Definition XrdOucJson.hh:6639
lexer & operator=(lexer &&)=default
static void strtof(float &f, const char *str, char **endptr) noexcept
Definition XrdOucJson.hh:7438
const char_int_type decimal_point_char
the decimal point
Definition XrdOucJson.hh:8154
bool skip_bom()
skip the UTF-8 byte order mark
Definition XrdOucJson.hh:8012
const char * error_message
a description of occurred lexer errors
Definition XrdOucJson.hh:8146
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition XrdOucJson.hh:6649
position_t position
the start position of the current token
Definition XrdOucJson.hh:8137
constexpr position_t get_position() const noexcept
return position of last read token
Definition XrdOucJson.hh:7966
std::vector< char_type > token_string
raw input token string (for error messages)
Definition XrdOucJson.hh:8140
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition XrdOucJson.hh:7938
typename lexer_base< BasicJsonType >::token_type token_type
Definition XrdOucJson.hh:6647
typename InputAdapterType::char_type char_type
Definition XrdOucJson.hh:6643
char_int_type get()
Definition XrdOucJson.hh:7863
token_type scan_number()
scan a number literal
Definition XrdOucJson.hh:7495
lexer & operator=(lexer &)=delete
void unget()
unget current character (read it again on next get)
Definition XrdOucJson.hh:7900
token_type scan_string()
scan a string literal
Definition XrdOucJson.hh:6780
lexer(const lexer &)=delete
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition XrdOucJson.hh:7944
string_t token_buffer
buffer for variable-length tokens (numbers, strings)
Definition XrdOucJson.hh:8143
token_type scan_literal(const char_type *literal_text, const std::size_t length, token_type return_type)
Definition XrdOucJson.hh:7826
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition XrdOucJson.hh:7950
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition XrdOucJson.hh:6695
std::string get_token_string() const
Definition XrdOucJson.hh:7974
number_unsigned_t value_unsigned
Definition XrdOucJson.hh:8150
lexer(lexer &&)=default
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition XrdOucJson.hh:6640
bool next_byte_in_range(std::initializer_list< char_int_type > ranges)
check if the next byte(s) are inside a given range
Definition XrdOucJson.hh:6743
typename BasicJsonType::string_t string_t
Definition XrdOucJson.hh:6642
bool scan_comment()
scan a comment
Definition XrdOucJson.hh:7370
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition XrdOucJson.hh:7999
exception indicating other library errors
Definition XrdOucJson.hh:3015
static other_error create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition XrdOucJson.hh:3018
exception indicating access out of the defined range
Definition XrdOucJson.hh:2976
static out_of_range create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition XrdOucJson.hh:2979
Definition XrdOucJson.hh:13563
output_adapter(std::vector< CharType > &vec)
Definition XrdOucJson.hh:13565
output_adapter(std::basic_ostream< CharType > &s)
Definition XrdOucJson.hh:13569
output_adapter(StringType &s)
Definition XrdOucJson.hh:13573
output adapter for output streams
Definition XrdOucJson.hh:13515
void write_character(CharType c) override
Definition XrdOucJson.hh:13521
std::basic_ostream< CharType > & stream
Definition XrdOucJson.hh:13533
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition XrdOucJson.hh:13517
output adapter for basic_string
Definition XrdOucJson.hh:13540
void write_character(CharType c) override
Definition XrdOucJson.hh:13546
StringType & str
Definition XrdOucJson.hh:13558
output_string_adapter(StringType &s) noexcept
Definition XrdOucJson.hh:13542
output adapter for byte vectors
Definition XrdOucJson.hh:13490
std::vector< CharType > & v
Definition XrdOucJson.hh:13508
output_vector_adapter(std::vector< CharType > &vec) noexcept
Definition XrdOucJson.hh:13492
void write_character(CharType c) override
Definition XrdOucJson.hh:13496
exception indicating a parse error
Definition XrdOucJson.hh:2785
parse_error(int id_, std::size_t byte_, const char *what_arg)
Definition XrdOucJson.hh:2825
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, const BasicJsonType &context)
Definition XrdOucJson.hh:2805
const std::size_t byte
byte index of the parse error
Definition XrdOucJson.hh:2822
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, const BasicJsonType &context)
create a parse error exception
Definition XrdOucJson.hh:2797
static std::string position_string(const position_t &pos)
Definition XrdOucJson.hh:2828
syntax analysis
Definition XrdOucJson.hh:10884
lexer_t m_lexer
the lexer
Definition XrdOucJson.hh:11324
bool sax_parse(SAX *sax, const bool strict=true)
Definition XrdOucJson.hh:10984
token_type get_token()
get next token from lexer
Definition XrdOucJson.hh:11284
token_type last_token
the type of the last read token
Definition XrdOucJson.hh:11322
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition XrdOucJson.hh:10894
bool accept(const bool strict=true)
public accept interface
Definition XrdOucJson.hh:10976
typename BasicJsonType::string_t string_t
Definition XrdOucJson.hh:10888
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition XrdOucJson.hh:10886
typename lexer_t::token_type token_type
Definition XrdOucJson.hh:10890
bool sax_parse_internal(SAX *sax)
Definition XrdOucJson.hh:11003
const parser_callback_t< BasicJsonType > callback
callback function
Definition XrdOucJson.hh:11320
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition XrdOucJson.hh:10916
std::string exception_message(const token_type expected, const std::string &context)
Definition XrdOucJson.hh:11289
typename BasicJsonType::number_float_t number_float_t
Definition XrdOucJson.hh:10887
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition XrdOucJson.hh:11326
typename BasicJsonType::number_integer_t number_integer_t
Definition XrdOucJson.hh:10885
Definition XrdOucJson.hh:11358
primitive_iterator_t operator+(difference_type n) noexcept
Definition XrdOucJson.hh:11408
primitive_iterator_t & operator++() noexcept
Definition XrdOucJson.hh:11420
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition XrdOucJson.hh:11393
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition XrdOucJson.hh:11452
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition XrdOucJson.hh:11387
friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition XrdOucJson.hh:11403
void set_begin() noexcept
set iterator to a defined beginning
Definition XrdOucJson.hh:11375
primitive_iterator_t const operator++(int) noexcept
Definition XrdOucJson.hh:11426
static constexpr difference_type end_value
Definition XrdOucJson.hh:11362
friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition XrdOucJson.hh:11398
friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition XrdOucJson.hh:11415
primitive_iterator_t & operator--() noexcept
Definition XrdOucJson.hh:11433
void set_end() noexcept
set iterator to a defined past the end
Definition XrdOucJson.hh:11381
constexpr difference_type get_value() const noexcept
Definition XrdOucJson.hh:11369
primitive_iterator_t const operator--(int) noexcept
Definition XrdOucJson.hh:11439
std::ptrdiff_t difference_type
Definition XrdOucJson.hh:11360
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition XrdOucJson.hh:11446
static constexpr difference_type begin_value
Definition XrdOucJson.hh:11361
Definition XrdOucJson.hh:16370
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition XrdOucJson.hh:17281
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition XrdOucJson.hh:16374
const std::lconv * loc
the locale
Definition XrdOucJson.hh:17266
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition XrdOucJson.hh:17263
static constexpr std::uint8_t UTF8_ACCEPT
Definition XrdOucJson.hh:16376
serializer(serializer &&)=delete
serializer & operator=(serializer &&)=delete
const char decimal_point
the locale's decimal point character
Definition XrdOucJson.hh:17270
std::uint8_t state
Definition XrdOucJson.hh:16712
std::size_t bytes
Definition XrdOucJson.hh:16713
typename BasicJsonType::number_float_t number_float_t
Definition XrdOucJson.hh:16372
const char thousands_sep
the locale's thousand separator character
Definition XrdOucJson.hh:17268
serializer & operator=(const serializer &)=delete
std::size_t undumped_chars
Definition XrdOucJson.hh:16717
static constexpr std::uint8_t UTF8_REJECT
Definition XrdOucJson.hh:16377
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition XrdOucJson.hh:16425
const char indent_char
the indentation character
Definition XrdOucJson.hh:17276
std::size_t bytes_after_last_accept
Definition XrdOucJson.hh:16716
std::array< char, 512 > string_buffer
string buffer
Definition XrdOucJson.hh:17273
typename BasicJsonType::binary_t::value_type binary_char_t
Definition XrdOucJson.hh:16375
JSON_PRIVATE_UNLESS_TESTED const bool ensure_ascii
Definition XrdOucJson.hh:16710
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition XrdOucJson.hh:16385
typename BasicJsonType::string_t string_t
Definition XrdOucJson.hh:16371
serializer(const serializer &)=delete
typename BasicJsonType::number_integer_t number_integer_t
Definition XrdOucJson.hh:16373
string_t indent_string
the indentation string
Definition XrdOucJson.hh:17278
Definition XrdOucJson.hh:5787
contiguous_bytes_input_adapter && get()
Definition XrdOucJson.hh:5805
span_input_adapter(CharT b, std::size_t l)
Definition XrdOucJson.hh:5795
contiguous_bytes_input_adapter ia
Definition XrdOucJson.hh:5811
span_input_adapter(IteratorType first, IteratorType last)
Definition XrdOucJson.hh:5802
exception indicating executing a member function with a wrong type
Definition XrdOucJson.hh:2928
static type_error create(int id_, const std::string &what_arg, const BasicJsonType &context)
Definition XrdOucJson.hh:2931
Definition XrdOucJson.hh:5621
void fill_buffer()
Definition XrdOucJson.hh:5649
std::char_traits< char >::int_type get_character() noexcept
Definition XrdOucJson.hh:5628
std::size_t utf8_bytes_index
index to the utf8_codes array for the next valid byte
Definition XrdOucJson.hh:5658
BaseInputAdapter base_adapter
Definition XrdOucJson.hh:5646
char char_type
Definition XrdOucJson.hh:5623
std::size_t utf8_bytes_filled
number of valid bytes in the utf8_codes array
Definition XrdOucJson.hh:5660
wide_string_input_adapter(BaseInputAdapter base)
Definition XrdOucJson.hh:5625
std::array< std::char_traits< char >::int_type, 4 > utf8_bytes
a buffer for UTF-8 bytes
Definition XrdOucJson.hh:5655
JSON Pointer.
Definition XrdOucJson.hh:12381
std::vector< std::string > reference_tokens
the reference tokens
Definition XrdOucJson.hh:13348
JSON_PRIVATE_UNLESS_TESTED JSON pointer has no BasicJsonType()))
json_pointer & operator/=(std::string token)
append an unescaped reference token at the end of this JSON pointer
Definition XrdOucJson.hh:12482
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition XrdOucJson.hh:12458
std::string to_string() const
return a string representation of the JSON pointer
Definition XrdOucJson.hh:12426
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
Definition XrdOucJson.hh:12963
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for equality
Definition XrdOucJson.hh:13324
result reference_tokens
Definition XrdOucJson.hh:12747
void pop_back()
remove last reference token
Definition XrdOucJson.hh:12608
const std::string & back() const
return last reference token
Definition XrdOucJson.hh:12632
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
Definition XrdOucJson.hh:13011
bool empty() const noexcept
return whether pointer points to the root document
Definition XrdOucJson.hh:12679
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for inequality
Definition XrdOucJson.hh:13341
void push_back(const std::string &token)
append an unescaped token at the end of the reference pointer
Definition XrdOucJson.hh:12654
json_pointer(const std::string &s="")
create JSON pointer
Definition XrdOucJson.hh:12408
return result
Definition XrdOucJson.hh:12748
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 XrdOucJson.hh:12524
bool contains(const BasicJsonType *ptr) const
Definition XrdOucJson.hh:13059
static BasicJsonType unflatten(const BasicJsonType &value)
Definition XrdOucJson.hh:13286
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 XrdOucJson.hh:12545
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
Definition XrdOucJson.hh:12760
static void flatten(const std::string &reference_string, const BasicJsonType &value, BasicJsonType &result)
Definition XrdOucJson.hh:13215
void push_back(std::string &&token)
append an unescaped token at the end of the reference pointer
Definition XrdOucJson.hh:12660
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition XrdOucJson.hh:12906
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition XrdOucJson.hh:12504
static BasicJsonType::size_type array_index(const std::string &s)
Definition XrdOucJson.hh:12695
json_pointer result
Definition XrdOucJson.hh:12746
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition XrdOucJson.hh:12839
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 XrdOucJson.hh:12565
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition XrdOucJson.hh:12583
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
Definition XrdOucJson.hh:13147
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition XrdOucJson.hh:4533
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition XrdOucJson.hh:16047
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition XrdOucJson.hh:16199
Target reinterpret_bits(const Source source)
Definition XrdOucJson.hh:15267
boundaries compute_boundaries(FloatType value)
Definition XrdOucJson.hh:15408
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition XrdOucJson.hh:15711
constexpr int kGamma
Definition XrdOucJson.hh:15531
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition XrdOucJson.hh:15765
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition XrdOucJson.hh:16147
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition XrdOucJson.hh:15806
constexpr int kAlpha
Definition XrdOucJson.hh:15530
cached_power get_cached_power_for_binary_exponent(int e)
Definition XrdOucJson.hh:15547
typename std::enable_if< B, T >::type enable_if_t
Definition XrdOucJson.hh:3063
typename T::reference reference_t
Definition XrdOucJson.hh:3490
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition XrdOucJson.hh:147
static void unescape(std::string &s)
string unescaping as described in RFC 6901 (Sect. 4)
Definition XrdOucJson.hh:2572
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition XrdOucJson.hh:3502
void to_json(BasicJsonType &j, T b) noexcept
Definition XrdOucJson.hh:4785
value_t
the JSON type enumeration
Definition XrdOucJson.hh:121
@ number_integer
number value (signed integer)
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition XrdOucJson.hh:3894
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition XrdOucJson.hh:3167
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition XrdOucJson.hh:8225
typename T::pointer pointer_t
Definition XrdOucJson.hh:3487
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition XrdOucJson.hh:8198
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition XrdOucJson.hh:10875
typename T::difference_type difference_type_t
Definition XrdOucJson.hh:3484
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition XrdOucJson.hh:3329
void int_to_string(string_type &target, std::size_t value)
Definition XrdOucJson.hh:4366
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition XrdOucJson.hh:4049
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition XrdOucJson.hh:8210
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition XrdOucJson.hh:8182
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition XrdOucJson.hh:8202
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition XrdOucJson.hh:8186
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition XrdOucJson.hh:16284
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition XrdOucJson.hh:4908
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition XrdOucJson.hh:3342
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition XrdOucJson.hh:3049
cbor_tag_handler_t
how to treat CBOR tags
Definition XrdOucJson.hh:8326
@ store
store tags as binary type
@ error
throw a parse_error exception in case of a tag
parse_event_t
Definition XrdOucJson.hh:10858
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
error_handler_t
how to treat decoding errors
Definition XrdOucJson.hh:16362
@ strict
throw a type_error exception in case of invalid UTF-8
@ ignore
ignore invalid UTF-8 sequences
@ replace
replace invalid UTF-8 sequences with U+FFFD
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition XrdOucJson.hh:8206
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition XrdOucJson.hh:5703
typename T::key_type key_type_t
Definition XrdOucJson.hh:3478
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition XrdOucJson.hh:5203
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition XrdOucJson.hh:5221
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition XrdOucJson.hh:3151
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition XrdOucJson.hh:8190
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition XrdOucJson.hh:3338
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition XrdOucJson.hh:3335
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition XrdOucJson.hh:8217
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 > >, priority_tag< 0 >)
Definition XrdOucJson.hh:4238
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition XrdOucJson.hh:3908
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition XrdOucJson.hh:3323
typename make_void< Ts... >::type void_t
Definition XrdOucJson.hh:3226
make_integer_sequence< size_t, N > make_index_sequence
Definition XrdOucJson.hh:3159
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition XrdOucJson.hh:13485
typename T::mapped_type mapped_type_t
Definition XrdOucJson.hh:3475
std::string escape(std::string s)
string escaping as described in RFC 6901 (Sect. 4)
Definition XrdOucJson.hh:2558
typename T::iterator iterator_t
Definition XrdOucJson.hh:3496
input_format_t
the supported input formats
Definition XrdOucJson.hh:5357
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition XrdOucJson.hh:4232
decltype(std::declval< T >().template get< U >()) get_template_function
Definition XrdOucJson.hh:3505
std::array< T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType &&j, identity_tag< std::array< T, sizeof...(Idx)> >, index_sequence< Idx... >)
Definition XrdOucJson.hh:4132
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition XrdOucJson.hh:5760
decltype(std::declval< T & >().null()) null_function_t
Definition XrdOucJson.hh:8178
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition XrdOucJson.hh:4497
void replace_substring(std::string &s, const std::string &f, const std::string &t)
replace all occurrences of a substring by another string
Definition XrdOucJson.hh:2540
typename T::iterator_category iterator_category_t
Definition XrdOucJson.hh:3493
static bool little_endianess(int num=1) noexcept
determine system byte order
Definition XrdOucJson.hh:8339
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition XrdOucJson.hh:8194
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition XrdOucJson.hh:8220
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition XrdOucJson.hh:8213
T conditional_static_cast(U value)
Definition XrdOucJson.hh:3872
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition XrdOucJson.hh:3499
typename T::value_type value_type_t
Definition XrdOucJson.hh:3481
namespace for Niels Lohmann
Definition XrdOucJson.hh:89
basic_json<> json
default JSON class
Definition XrdOucJson.hh:3408
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition XrdOucJson.hh:26358
Definition XrdOucJson.hh:4517
default JSONSerializer template argument
Definition XrdOucJson.hh:4949
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 XrdOucJson.hh:4962
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 XrdOucJson.hh:4982
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 XrdOucJson.hh:4999
Definition XrdOucJson.hh:3567
Definition XrdOucJson.hh:3310
Default type
Definition XrdOucJson.hh:3312
std::false_type value_t
Definition XrdOucJson.hh:3311
Definition XrdOucJson.hh:15395
diyfp plus
Definition XrdOucJson.hh:15398
diyfp w
Definition XrdOucJson.hh:15396
diyfp minus
Definition XrdOucJson.hh:15397
Definition XrdOucJson.hh:15534
std::uint64_t f
Definition XrdOucJson.hh:15535
int k
Definition XrdOucJson.hh:15537
int e
Definition XrdOucJson.hh:15536
Definition XrdOucJson.hh:15277
static constexpr int kPrecision
Definition XrdOucJson.hh:15278
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition XrdOucJson.hh:15366
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition XrdOucJson.hh:15383
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition XrdOucJson.hh:15301
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition XrdOucJson.hh:15283
int e
Definition XrdOucJson.hh:15281
std::uint64_t f
Definition XrdOucJson.hh:15280
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition XrdOucJson.hh:15289
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition XrdOucJson.hh:4697
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition XrdOucJson.hh:4726
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition XrdOucJson.hh:4710
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition XrdOucJson.hh:4685
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition XrdOucJson.hh:4675
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition XrdOucJson.hh:4614
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition XrdOucJson.hh:4623
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition XrdOucJson.hh:4568
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition XrdOucJson.hh:4636
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition XrdOucJson.hh:4662
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition XrdOucJson.hh:4649
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition XrdOucJson.hh:4755
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition XrdOucJson.hh:4745
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition XrdOucJson.hh:4766
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition XrdOucJson.hh:4590
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition XrdOucJson.hh:4601
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition XrdOucJson.hh:4581
Definition XrdOucJson.hh:4562
Definition XrdOucJson.hh:4315
auto operator()(const BasicJsonType &j, T &&val) const noexcept(noexcept(from_json(j, std::forward< T >(val)))) -> decltype(from_json(j, std::forward< T >(val)))
Definition XrdOucJson.hh:4317
typename BasicJsonType::template json_serializer< T, void > serializer
Definition XrdOucJson.hh:3524
Definition XrdOucJson.hh:3509
typename BasicJsonType::template json_serializer< T, void > serializer
Definition XrdOucJson.hh:3539
Definition XrdOucJson.hh:3534
typename BasicJsonType::template json_serializer< T, void > serializer
Definition XrdOucJson.hh:3554
Definition XrdOucJson.hh:3549
Definition XrdOucJson.hh:3198
Definition XrdOucJson.hh:3091
T value_type
Definition XrdOucJson.hh:3092
static constexpr std::size_t size() noexcept
Definition XrdOucJson.hh:3093
an iterator value
Definition XrdOucJson.hh:11473
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition XrdOucJson.hh:11479
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition XrdOucJson.hh:11477
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition XrdOucJson.hh:11475
Definition XrdOucJson.hh:3452
Definition XrdOucJson.hh:3758
Definition XrdOucJson.hh:3665
Definition XrdOucJson.hh:3716
Definition XrdOucJson.hh:3831
Definition XrdOucJson.hh:3844
Definition XrdOucJson.hh:3638
Definition XrdOucJson.hh:3847
Definition XrdOucJson.hh:3600
Definition XrdOucJson.hh:3580
Definition XrdOucJson.hh:3326
Definition XrdOucJson.hh:3517
static constexpr bool value
Definition XrdOucJson.hh:3518
Definition XrdOucJson.hh:5679
typename std::iterator_traits< T >::value_type value_type
Definition XrdOucJson.hh:5680
Definition XrdOucJson.hh:3616
Definition XrdOucJson.hh:3465
Definition XrdOucJson.hh:3860
char x[2]
Definition XrdOucJson.hh:3861
Definition XrdOucJson.hh:3856
@ value
Definition XrdOucJson.hh:3867
char one
Definition XrdOucJson.hh:3857
static one test(decltype(&C::capacity))
Definition XrdOucJson.hh:8260
typename BasicJsonType::string_t string_t
Definition XrdOucJson.hh:8268
typename BasicJsonType::exception exception_t
Definition XrdOucJson.hh:8270
typename BasicJsonType::number_integer_t number_integer_t
Definition XrdOucJson.hh:8265
typename BasicJsonType::number_float_t number_float_t
Definition XrdOucJson.hh:8267
typename BasicJsonType::binary_t binary_t
Definition XrdOucJson.hh:8269
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition XrdOucJson.hh:8266
Definition XrdOucJson.hh:8229
typename BasicJsonType::number_float_t number_float_t
Definition XrdOucJson.hh:8236
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition XrdOucJson.hh:8235
typename BasicJsonType::exception exception_t
Definition XrdOucJson.hh:8239
static constexpr bool value
Definition XrdOucJson.hh:8242
typename BasicJsonType::number_integer_t number_integer_t
Definition XrdOucJson.hh:8234
typename BasicJsonType::string_t string_t
Definition XrdOucJson.hh:8237
typename BasicJsonType::binary_t binary_t
Definition XrdOucJson.hh:8238
static adapter_type create(IteratorType first, IteratorType last)
Definition XrdOucJson.hh:5695
typename std::iterator_traits< iterator_type >::value_type char_type
Definition XrdOucJson.hh:5691
typename std::iterator_traits< iterator_type >::value_type char_type
Definition XrdOucJson.hh:5668
static adapter_type create(IteratorType first, IteratorType last)
Definition XrdOucJson.hh:5671
iterator_input_adapter< iterator_type > adapter_type
Definition XrdOucJson.hh:5669
IteratorType iterator_type
Definition XrdOucJson.hh:5667
std::random_access_iterator_tag iterator_category
Definition XrdOucJson.hh:3269
Definition XrdOucJson.hh:3257
Definition XrdOucJson.hh:3238
Definition XrdOucJson.hh:3223
void type
Definition XrdOucJson.hh:3224
Definition XrdOucJson.hh:3574
Definition XrdOucJson.hh:3296
nonesuch(nonesuch const &)=delete
void operator=(nonesuch &&)=delete
nonesuch(nonesuch const &&)=delete
void operator=(nonesuch const &)=delete
abstract output adapter interface
Definition XrdOucJson.hh:13471
virtual void write_characters(const CharType *s, std::size_t length)=0
virtual void write_character(CharType c)=0
output_adapter_protocol(output_adapter_protocol &&) noexcept=default
output_adapter_protocol(const output_adapter_protocol &)=default
struct to capture the start position of the current token
Definition XrdOucJson.hh:2592
std::size_t lines_read
the number of lines read
Definition XrdOucJson.hh:2598
std::size_t chars_read_current_line
the number of characters read in the current line
Definition XrdOucJson.hh:2596
std::size_t chars_read_total
the total number of characters read
Definition XrdOucJson.hh:2594
Definition XrdOucJson.hh:3174
Definition XrdOucJson.hh:3180
static constexpr T value
Definition XrdOucJson.hh:3181
Definition XrdOucJson.hh:4920
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition XrdOucJson.hh:4922
Definition XrdOucJson.hh:3111
Definition XrdOucJson.hh:3130
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition XrdOucJson.hh:3132
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition XrdOucJson.hh:5560
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition XrdOucJson.hh:5502
Definition XrdOucJson.hh:5496
SAX interface.
Definition XrdOucJson.hh:5842
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
virtual bool string(string_t &val)=0
a string was read
virtual bool null()=0
a null value was read
typename BasicJsonType::number_integer_t number_integer_t
Definition XrdOucJson.hh:5843
typename BasicJsonType::binary_t binary_t
Definition XrdOucJson.hh:5847
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 XrdOucJson.hh:5844
virtual bool binary(binary_t &val)=0
a binary string was read
typename BasicJsonType::number_float_t number_float_t
Definition XrdOucJson.hh:5845
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
json_sax(json_sax &&) noexcept=default
virtual bool boolean(bool val)=0
a boolean value was read
json_sax(const json_sax &)=default
virtual bool end_object()=0
the end of an object was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
typename BasicJsonType::string_t string_t
Definition XrdOucJson.hh:5846
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
Definition XrdOucJson.hh:17313
T & at(const Key &key)
Definition XrdOucJson.hh:17354
ordered_map(std::initializer_list< T > init, const Allocator &alloc=Allocator())
Definition XrdOucJson.hh:17328
std::vector< std::pair< const Key, T >, Allocator > Container
Definition XrdOucJson.hh:17316
T mapped_type
Definition XrdOucJson.hh:17315
const T & at(const Key &key) const
Definition XrdOucJson.hh:17367
iterator find(const Key &key)
Definition XrdOucJson.hh:17425
iterator erase(iterator pos)
Definition XrdOucJson.hh:17399
void insert(InputIt first, InputIt last)
Definition XrdOucJson.hh:17472
std::pair< iterator, bool > insert(value_type &&value)
Definition XrdOucJson.hh:17449
const_iterator find(const Key &key) const
Definition XrdOucJson.hh:17437
Key key_type
Definition XrdOucJson.hh:17314
size_type erase(const Key &key)
Definition XrdOucJson.hh:17380
T & operator[](const Key &key)
Definition XrdOucJson.hh:17344
ordered_map(const Allocator &alloc=Allocator())
Definition XrdOucJson.hh:17324
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition XrdOucJson.hh:17469
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition XrdOucJson.hh:17326
std::pair< iterator, bool > insert(const value_type &value)
Definition XrdOucJson.hh:17454
size_type count(const Key &key) const
Definition XrdOucJson.hh:17413
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition XrdOucJson.hh:17331
const T & operator[](const Key &key) const
Definition XrdOucJson.hh:17349
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition XrdOucJson.hh:26381
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition XrdOucJson.hh:26397