TerraForge3D  2.3.1
3D Terrain And Landscape Generator
json.hpp
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 const auto l_index = static_cast<std::size_t>(lhs);
156 const auto r_index = static_cast<std::size_t>(rhs);
157 return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
158}
159} // namespace detail
160} // namespace nlohmann
161
162// #include <nlohmann/detail/string_escape.hpp>
163
164
165#include <string>
166// #include <nlohmann/detail/macro_scope.hpp>
167
168
169#include <utility> // pair
170// #include <nlohmann/thirdparty/hedley/hedley.hpp>
171
172
173/* Hedley - https://nemequ.github.io/hedley
174 * Created by Evan Nemerson <evan@nemerson.com>
175 *
176 * To the extent possible under law, the author(s) have dedicated all
177 * copyright and related and neighboring rights to this software to
178 * the public domain worldwide. This software is distributed without
179 * any warranty.
180 *
181 * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
182 * SPDX-License-Identifier: CC0-1.0
183 */
184
185#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
186#if defined(JSON_HEDLEY_VERSION)
187#undef JSON_HEDLEY_VERSION
188#endif
189#define JSON_HEDLEY_VERSION 15
190
191#if defined(JSON_HEDLEY_STRINGIFY_EX)
192#undef JSON_HEDLEY_STRINGIFY_EX
193#endif
194#define JSON_HEDLEY_STRINGIFY_EX(x) #x
195
196#if defined(JSON_HEDLEY_STRINGIFY)
197#undef JSON_HEDLEY_STRINGIFY
198#endif
199#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
200
201#if defined(JSON_HEDLEY_CONCAT_EX)
202#undef JSON_HEDLEY_CONCAT_EX
203#endif
204#define JSON_HEDLEY_CONCAT_EX(a,b) a##b
205
206#if defined(JSON_HEDLEY_CONCAT)
207#undef JSON_HEDLEY_CONCAT
208#endif
209#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
210
211#if defined(JSON_HEDLEY_CONCAT3_EX)
212#undef JSON_HEDLEY_CONCAT3_EX
213#endif
214#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
215
216#if defined(JSON_HEDLEY_CONCAT3)
217#undef JSON_HEDLEY_CONCAT3
218#endif
219#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
220
221#if defined(JSON_HEDLEY_VERSION_ENCODE)
222#undef JSON_HEDLEY_VERSION_ENCODE
223#endif
224#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
225
226#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
227#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
228#endif
229#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
230
231#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
232#undef JSON_HEDLEY_VERSION_DECODE_MINOR
233#endif
234#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
235
236#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
237#undef JSON_HEDLEY_VERSION_DECODE_REVISION
238#endif
239#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
240
241#if defined(JSON_HEDLEY_GNUC_VERSION)
242#undef JSON_HEDLEY_GNUC_VERSION
243#endif
244#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
245#define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
246#elif defined(__GNUC__)
247#define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
248#endif
249
250#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
251#undef JSON_HEDLEY_GNUC_VERSION_CHECK
252#endif
253#if defined(JSON_HEDLEY_GNUC_VERSION)
254#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
255#else
256#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
257#endif
258
259#if defined(JSON_HEDLEY_MSVC_VERSION)
260#undef JSON_HEDLEY_MSVC_VERSION
261#endif
262#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
263#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
264#elif defined(_MSC_FULL_VER) && !defined(__ICL)
265#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
266#elif defined(_MSC_VER) && !defined(__ICL)
267#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
268#endif
269
270#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
271#undef JSON_HEDLEY_MSVC_VERSION_CHECK
272#endif
273#if !defined(JSON_HEDLEY_MSVC_VERSION)
274#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
275#elif defined(_MSC_VER) && (_MSC_VER >= 1400)
276#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
277#elif defined(_MSC_VER) && (_MSC_VER >= 1200)
278#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
279#else
280#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
281#endif
282
283#if defined(JSON_HEDLEY_INTEL_VERSION)
284#undef JSON_HEDLEY_INTEL_VERSION
285#endif
286#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
287#define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
288#elif defined(__INTEL_COMPILER) && !defined(__ICL)
289#define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
290#endif
291
292#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
293#undef JSON_HEDLEY_INTEL_VERSION_CHECK
294#endif
295#if defined(JSON_HEDLEY_INTEL_VERSION)
296#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
297#else
298#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
299#endif
300
301#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
302#undef JSON_HEDLEY_INTEL_CL_VERSION
303#endif
304#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
305#define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
306#endif
307
308#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
309#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
310#endif
311#if defined(JSON_HEDLEY_INTEL_CL_VERSION)
312#define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
313#else
314#define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
315#endif
316
317#if defined(JSON_HEDLEY_PGI_VERSION)
318#undef JSON_HEDLEY_PGI_VERSION
319#endif
320#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
321#define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
322#endif
323
324#if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
325#undef JSON_HEDLEY_PGI_VERSION_CHECK
326#endif
327#if defined(JSON_HEDLEY_PGI_VERSION)
328#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
329#else
330#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
331#endif
332
333#if defined(JSON_HEDLEY_SUNPRO_VERSION)
334#undef JSON_HEDLEY_SUNPRO_VERSION
335#endif
336#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
337#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)
338#elif defined(__SUNPRO_C)
339#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
340#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
341#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)
342#elif defined(__SUNPRO_CC)
343#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
344#endif
345
346#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
347#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
348#endif
349#if defined(JSON_HEDLEY_SUNPRO_VERSION)
350#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
351#else
352#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
353#endif
354
355#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
356#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
357#endif
358#if defined(__EMSCRIPTEN__)
359#define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
360#endif
361
362#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
363#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
364#endif
365#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
366#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
367#else
368#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
369#endif
370
371#if defined(JSON_HEDLEY_ARM_VERSION)
372#undef JSON_HEDLEY_ARM_VERSION
373#endif
374#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
375#define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
376#elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
377#define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
378#endif
379
380#if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
381#undef JSON_HEDLEY_ARM_VERSION_CHECK
382#endif
383#if defined(JSON_HEDLEY_ARM_VERSION)
384#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
385#else
386#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
387#endif
388
389#if defined(JSON_HEDLEY_IBM_VERSION)
390#undef JSON_HEDLEY_IBM_VERSION
391#endif
392#if defined(__ibmxl__)
393#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
394#elif defined(__xlC__) && defined(__xlC_ver__)
395#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
396#elif defined(__xlC__)
397#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
398#endif
399
400#if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
401#undef JSON_HEDLEY_IBM_VERSION_CHECK
402#endif
403#if defined(JSON_HEDLEY_IBM_VERSION)
404#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
405#else
406#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
407#endif
408
409#if defined(JSON_HEDLEY_TI_VERSION)
410#undef JSON_HEDLEY_TI_VERSION
411#endif
412#if \
413 defined(__TI_COMPILER_VERSION__) && \
414 ( \
415 defined(__TMS470__) || defined(__TI_ARM__) || \
416 defined(__MSP430__) || \
417 defined(__TMS320C2000__) \
418 )
419#if (__TI_COMPILER_VERSION__ >= 16000000)
420#define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
421#endif
422#endif
423
424#if defined(JSON_HEDLEY_TI_VERSION_CHECK)
425#undef JSON_HEDLEY_TI_VERSION_CHECK
426#endif
427#if defined(JSON_HEDLEY_TI_VERSION)
428#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
429#else
430#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
431#endif
432
433#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
434#undef JSON_HEDLEY_TI_CL2000_VERSION
435#endif
436#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
437#define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
438#endif
439
440#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
441#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
442#endif
443#if defined(JSON_HEDLEY_TI_CL2000_VERSION)
444#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
445#else
446#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
447#endif
448
449#if defined(JSON_HEDLEY_TI_CL430_VERSION)
450#undef JSON_HEDLEY_TI_CL430_VERSION
451#endif
452#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
453#define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
454#endif
455
456#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
457#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
458#endif
459#if defined(JSON_HEDLEY_TI_CL430_VERSION)
460#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
461#else
462#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
463#endif
464
465#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
466#undef JSON_HEDLEY_TI_ARMCL_VERSION
467#endif
468#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
469#define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
470#endif
471
472#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
473#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
474#endif
475#if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
476#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
477#else
478#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
479#endif
480
481#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
482#undef JSON_HEDLEY_TI_CL6X_VERSION
483#endif
484#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
485#define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
486#endif
487
488#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
489#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
490#endif
491#if defined(JSON_HEDLEY_TI_CL6X_VERSION)
492#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
493#else
494#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
495#endif
496
497#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
498#undef JSON_HEDLEY_TI_CL7X_VERSION
499#endif
500#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
501#define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
502#endif
503
504#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
505#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
506#endif
507#if defined(JSON_HEDLEY_TI_CL7X_VERSION)
508#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
509#else
510#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
511#endif
512
513#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
514#undef JSON_HEDLEY_TI_CLPRU_VERSION
515#endif
516#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
517#define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
518#endif
519
520#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
521#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
522#endif
523#if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
524#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
525#else
526#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
527#endif
528
529#if defined(JSON_HEDLEY_CRAY_VERSION)
530#undef JSON_HEDLEY_CRAY_VERSION
531#endif
532#if defined(_CRAYC)
533#if defined(_RELEASE_PATCHLEVEL)
534#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
535#else
536#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
537#endif
538#endif
539
540#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
541#undef JSON_HEDLEY_CRAY_VERSION_CHECK
542#endif
543#if defined(JSON_HEDLEY_CRAY_VERSION)
544#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
545#else
546#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
547#endif
548
549#if defined(JSON_HEDLEY_IAR_VERSION)
550#undef JSON_HEDLEY_IAR_VERSION
551#endif
552#if defined(__IAR_SYSTEMS_ICC__)
553#if __VER__ > 1000
554#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
555#else
556#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
557#endif
558#endif
559
560#if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
561#undef JSON_HEDLEY_IAR_VERSION_CHECK
562#endif
563#if defined(JSON_HEDLEY_IAR_VERSION)
564#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
565#else
566#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
567#endif
568
569#if defined(JSON_HEDLEY_TINYC_VERSION)
570#undef JSON_HEDLEY_TINYC_VERSION
571#endif
572#if defined(__TINYC__)
573#define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
574#endif
575
576#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
577#undef JSON_HEDLEY_TINYC_VERSION_CHECK
578#endif
579#if defined(JSON_HEDLEY_TINYC_VERSION)
580#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
581#else
582#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
583#endif
584
585#if defined(JSON_HEDLEY_DMC_VERSION)
586#undef JSON_HEDLEY_DMC_VERSION
587#endif
588#if defined(__DMC__)
589#define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
590#endif
591
592#if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
593#undef JSON_HEDLEY_DMC_VERSION_CHECK
594#endif
595#if defined(JSON_HEDLEY_DMC_VERSION)
596#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
597#else
598#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
599#endif
600
601#if defined(JSON_HEDLEY_COMPCERT_VERSION)
602#undef JSON_HEDLEY_COMPCERT_VERSION
603#endif
604#if defined(__COMPCERT_VERSION__)
605#define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
606#endif
607
608#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
609#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
610#endif
611#if defined(JSON_HEDLEY_COMPCERT_VERSION)
612#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
613#else
614#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
615#endif
616
617#if defined(JSON_HEDLEY_PELLES_VERSION)
618#undef JSON_HEDLEY_PELLES_VERSION
619#endif
620#if defined(__POCC__)
621#define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
622#endif
623
624#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
625#undef JSON_HEDLEY_PELLES_VERSION_CHECK
626#endif
627#if defined(JSON_HEDLEY_PELLES_VERSION)
628#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
629#else
630#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
631#endif
632
633#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
634#undef JSON_HEDLEY_MCST_LCC_VERSION
635#endif
636#if defined(__LCC__) && defined(__LCC_MINOR__)
637#define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
638#endif
639
640#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
641#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
642#endif
643#if defined(JSON_HEDLEY_MCST_LCC_VERSION)
644#define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
645#else
646#define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
647#endif
648
649#if defined(JSON_HEDLEY_GCC_VERSION)
650#undef JSON_HEDLEY_GCC_VERSION
651#endif
652#if \
653 defined(JSON_HEDLEY_GNUC_VERSION) && \
654 !defined(__clang__) && \
655 !defined(JSON_HEDLEY_INTEL_VERSION) && \
656 !defined(JSON_HEDLEY_PGI_VERSION) && \
657 !defined(JSON_HEDLEY_ARM_VERSION) && \
658 !defined(JSON_HEDLEY_CRAY_VERSION) && \
659 !defined(JSON_HEDLEY_TI_VERSION) && \
660 !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
661 !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
662 !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
663 !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
664 !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
665 !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
666 !defined(__COMPCERT__) && \
667 !defined(JSON_HEDLEY_MCST_LCC_VERSION)
668#define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
669#endif
670
671#if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
672#undef JSON_HEDLEY_GCC_VERSION_CHECK
673#endif
674#if defined(JSON_HEDLEY_GCC_VERSION)
675#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
676#else
677#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
678#endif
679
680#if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
681#undef JSON_HEDLEY_HAS_ATTRIBUTE
682#endif
683#if \
684 defined(__has_attribute) && \
685 ( \
686 (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
687 )
688# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
689#else
690# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
691#endif
692
693#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
694#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
695#endif
696#if defined(__has_attribute)
697#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
698#else
699#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
700#endif
701
702#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
703#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
704#endif
705#if defined(__has_attribute)
706#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
707#else
708#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
709#endif
710
711#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
712#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
713#endif
714#if \
715 defined(__has_cpp_attribute) && \
716 defined(__cplusplus) && \
717 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
718#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
719#else
720#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
721#endif
722
723#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
724#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
725#endif
726#if !defined(__cplusplus) || !defined(__has_cpp_attribute)
727#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
728#elif \
729 !defined(JSON_HEDLEY_PGI_VERSION) && \
730 !defined(JSON_HEDLEY_IAR_VERSION) && \
731 (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
732 (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
733#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
734#else
735#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
736#endif
737
738#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
739#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
740#endif
741#if defined(__has_cpp_attribute) && defined(__cplusplus)
742#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
743#else
744#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
745#endif
746
747#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
748#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
749#endif
750#if defined(__has_cpp_attribute) && defined(__cplusplus)
751#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
752#else
753#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
754#endif
755
756#if defined(JSON_HEDLEY_HAS_BUILTIN)
757#undef JSON_HEDLEY_HAS_BUILTIN
758#endif
759#if defined(__has_builtin)
760#define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
761#else
762#define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
763#endif
764
765#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
766#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
767#endif
768#if defined(__has_builtin)
769#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
770#else
771#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
772#endif
773
774#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
775#undef JSON_HEDLEY_GCC_HAS_BUILTIN
776#endif
777#if defined(__has_builtin)
778#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
779#else
780#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
781#endif
782
783#if defined(JSON_HEDLEY_HAS_FEATURE)
784#undef JSON_HEDLEY_HAS_FEATURE
785#endif
786#if defined(__has_feature)
787#define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
788#else
789#define JSON_HEDLEY_HAS_FEATURE(feature) (0)
790#endif
791
792#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
793#undef JSON_HEDLEY_GNUC_HAS_FEATURE
794#endif
795#if defined(__has_feature)
796#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
797#else
798#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
799#endif
800
801#if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
802#undef JSON_HEDLEY_GCC_HAS_FEATURE
803#endif
804#if defined(__has_feature)
805#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
806#else
807#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
808#endif
809
810#if defined(JSON_HEDLEY_HAS_EXTENSION)
811#undef JSON_HEDLEY_HAS_EXTENSION
812#endif
813#if defined(__has_extension)
814#define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
815#else
816#define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
817#endif
818
819#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
820#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
821#endif
822#if defined(__has_extension)
823#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
824#else
825#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
826#endif
827
828#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
829#undef JSON_HEDLEY_GCC_HAS_EXTENSION
830#endif
831#if defined(__has_extension)
832#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
833#else
834#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
835#endif
836
837#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
838#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
839#endif
840#if defined(__has_declspec_attribute)
841#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
842#else
843#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
844#endif
845
846#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
847#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
848#endif
849#if defined(__has_declspec_attribute)
850#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
851#else
852#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
853#endif
854
855#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
856#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
857#endif
858#if defined(__has_declspec_attribute)
859#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
860#else
861#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
862#endif
863
864#if defined(JSON_HEDLEY_HAS_WARNING)
865#undef JSON_HEDLEY_HAS_WARNING
866#endif
867#if defined(__has_warning)
868#define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
869#else
870#define JSON_HEDLEY_HAS_WARNING(warning) (0)
871#endif
872
873#if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
874#undef JSON_HEDLEY_GNUC_HAS_WARNING
875#endif
876#if defined(__has_warning)
877#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
878#else
879#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
880#endif
881
882#if defined(JSON_HEDLEY_GCC_HAS_WARNING)
883#undef JSON_HEDLEY_GCC_HAS_WARNING
884#endif
885#if defined(__has_warning)
886#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
887#else
888#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
889#endif
890
891#if \
892 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
893 defined(__clang__) || \
894 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
895 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
896 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
897 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
898 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
899 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
900 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
901 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
902 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
903 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
904 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
905 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
906 JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
907 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
908 JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
909 (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
910#define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
911#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
912#define JSON_HEDLEY_PRAGMA(value) __pragma(value)
913#else
914#define JSON_HEDLEY_PRAGMA(value)
915#endif
916
917#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
918#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
919#endif
920#if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
921#undef JSON_HEDLEY_DIAGNOSTIC_POP
922#endif
923#if defined(__clang__)
924#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
925#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
926#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
927#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
928#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
929#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
930#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
931#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
932#elif \
933 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
934 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
935#define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
936#define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
937#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
938#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
939#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
940#elif \
941 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
942 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
943 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
944 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
945 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
946 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
947#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
948#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
949#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
950#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
951#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
952#else
953#define JSON_HEDLEY_DIAGNOSTIC_PUSH
954#define JSON_HEDLEY_DIAGNOSTIC_POP
955#endif
956
957/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
958 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
959#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
960#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
961#endif
962#if defined(__cplusplus)
963# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
964# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
965# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
966# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
967 JSON_HEDLEY_DIAGNOSTIC_PUSH \
968 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
969 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
970 _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
971 xpr \
972 JSON_HEDLEY_DIAGNOSTIC_POP
973# else
974# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
975 JSON_HEDLEY_DIAGNOSTIC_PUSH \
976 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
977 _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
978 xpr \
979 JSON_HEDLEY_DIAGNOSTIC_POP
980# endif
981# else
982# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
983 JSON_HEDLEY_DIAGNOSTIC_PUSH \
984 _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
985 xpr \
986 JSON_HEDLEY_DIAGNOSTIC_POP
987# endif
988# endif
989#endif
990#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
991#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
992#endif
993
994#if defined(JSON_HEDLEY_CONST_CAST)
995#undef JSON_HEDLEY_CONST_CAST
996#endif
997#if defined(__cplusplus)
998# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
999#elif \
1000 JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
1001 JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
1002 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1003# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
1004 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1005 JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
1006 ((T) (expr)); \
1007 JSON_HEDLEY_DIAGNOSTIC_POP \
1008 }))
1009#else
1010# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
1011#endif
1012
1013#if defined(JSON_HEDLEY_REINTERPRET_CAST)
1014#undef JSON_HEDLEY_REINTERPRET_CAST
1015#endif
1016#if defined(__cplusplus)
1017#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
1018#else
1019#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
1020#endif
1021
1022#if defined(JSON_HEDLEY_STATIC_CAST)
1023#undef JSON_HEDLEY_STATIC_CAST
1024#endif
1025#if defined(__cplusplus)
1026#define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
1027#else
1028#define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
1029#endif
1030
1031#if defined(JSON_HEDLEY_CPP_CAST)
1032#undef JSON_HEDLEY_CPP_CAST
1033#endif
1034#if defined(__cplusplus)
1035# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
1036# define JSON_HEDLEY_CPP_CAST(T, expr) \
1037 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1038 _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
1039 ((T) (expr)) \
1040 JSON_HEDLEY_DIAGNOSTIC_POP
1041# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
1042# define JSON_HEDLEY_CPP_CAST(T, expr) \
1043 JSON_HEDLEY_DIAGNOSTIC_PUSH \
1044 _Pragma("diag_suppress=Pe137") \
1045 JSON_HEDLEY_DIAGNOSTIC_POP
1046# else
1047# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
1048# endif
1049#else
1050# define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
1051#endif
1052
1053#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
1054#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1055#endif
1056#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
1057#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
1058#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1059#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1060#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1061#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1062#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1063#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1064#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1065#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1066#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1067#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1068#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1069#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1070#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1071#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1072#elif \
1073 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1074 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1075 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1076 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1077 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1078 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1079 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1080 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1081 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1082 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1083 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1084#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1085#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1086#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1087#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1088#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1089#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1090#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1091#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1092#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1093#else
1094#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1095#endif
1096
1097#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1098#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1099#endif
1100#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1101#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1102#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1103#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1104#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1105#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1106#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1107#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1108#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1109#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1110#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1111#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1112#elif \
1113 JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1114 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1115 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1116 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1117#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1118#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1119#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1120#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1121#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1122#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1123#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1124#else
1125#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1126#endif
1127
1128#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1129#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1130#endif
1131#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1132#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1133#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1134#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1135#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1136#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1137#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1138#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1139#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1140#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1141#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1142#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1143#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1144#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1145#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1146#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1147#elif \
1148 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1149 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1150 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1151#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1152#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1153#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1154#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1155#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1156#else
1157#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1158#endif
1159
1160#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1161#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1162#endif
1163#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1164#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1165#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1166#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1167#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1168#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1169#else
1170#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1171#endif
1172
1173#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1174#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1175#endif
1176#if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1177#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1178#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1179#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1180#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1181#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1182#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1183#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1184#else
1185#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1186#endif
1187
1188#if defined(JSON_HEDLEY_DEPRECATED)
1189#undef JSON_HEDLEY_DEPRECATED
1190#endif
1191#if defined(JSON_HEDLEY_DEPRECATED_FOR)
1192#undef JSON_HEDLEY_DEPRECATED_FOR
1193#endif
1194#if \
1195 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1196 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1197#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1198#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1199#elif \
1200 (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1201 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1202 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1203 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1204 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1205 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1206 JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1207 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1208 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1209 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1210 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1211 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1212#define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1213#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1214#elif defined(__cplusplus) && (__cplusplus >= 201402L)
1215#define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1216#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1217#elif \
1218 JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1219 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1220 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1221 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1222 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1223 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1224 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1225 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1226 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1227 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1228 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1229 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1230 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1231 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1232 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1233 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1234#define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1235#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1236#elif \
1237 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1238 JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1239 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1240#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1241#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1242#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1243#define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1244#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1245#else
1246#define JSON_HEDLEY_DEPRECATED(since)
1247#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1248#endif
1249
1250#if defined(JSON_HEDLEY_UNAVAILABLE)
1251#undef JSON_HEDLEY_UNAVAILABLE
1252#endif
1253#if \
1254 JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1255 JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1256 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1257 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1258#define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1259#else
1260#define JSON_HEDLEY_UNAVAILABLE(available_since)
1261#endif
1262
1263#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1264#undef JSON_HEDLEY_WARN_UNUSED_RESULT
1265#endif
1266#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1267#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1268#endif
1269#if \
1270 JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1271 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1272 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1273 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1274 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1275 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1276 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1277 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1278 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1279 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1280 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1281 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1282 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1283 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1284 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1285 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1286 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1287#define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1288#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1289#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1290#define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1291#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1292#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1293#define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1294#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1295#elif defined(_Check_return_) /* SAL */
1296#define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1297#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1298#else
1299#define JSON_HEDLEY_WARN_UNUSED_RESULT
1300#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1301#endif
1302
1303#if defined(JSON_HEDLEY_SENTINEL)
1304#undef JSON_HEDLEY_SENTINEL
1305#endif
1306#if \
1307 JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1308 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1309 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1310 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1311 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1312#define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1313#else
1314#define JSON_HEDLEY_SENTINEL(position)
1315#endif
1316
1317#if defined(JSON_HEDLEY_NO_RETURN)
1318#undef JSON_HEDLEY_NO_RETURN
1319#endif
1320#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1321#define JSON_HEDLEY_NO_RETURN __noreturn
1322#elif \
1323 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1324 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1325#define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1326#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1327#define JSON_HEDLEY_NO_RETURN _Noreturn
1328#elif defined(__cplusplus) && (__cplusplus >= 201103L)
1329#define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1330#elif \
1331 JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1332 JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1333 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1334 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1335 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1336 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1337 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1338 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1339 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1340 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1341 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1342 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1343 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1344 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1345 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1346 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1347 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1348#define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1349#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1350#define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1351#elif \
1352 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1353 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1354#define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1355#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1356#define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1357#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1358#define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1359#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1360#define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1361#else
1362#define JSON_HEDLEY_NO_RETURN
1363#endif
1364
1365#if defined(JSON_HEDLEY_NO_ESCAPE)
1366#undef JSON_HEDLEY_NO_ESCAPE
1367#endif
1368#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1369#define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1370#else
1371#define JSON_HEDLEY_NO_ESCAPE
1372#endif
1373
1374#if defined(JSON_HEDLEY_UNREACHABLE)
1375#undef JSON_HEDLEY_UNREACHABLE
1376#endif
1377#if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1378#undef JSON_HEDLEY_UNREACHABLE_RETURN
1379#endif
1380#if defined(JSON_HEDLEY_ASSUME)
1381#undef JSON_HEDLEY_ASSUME
1382#endif
1383#if \
1384 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1385 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1386 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1387#define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1388#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1389#define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1390#elif \
1391 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1392 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1393#if defined(__cplusplus)
1394#define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1395#else
1396#define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1397#endif
1398#endif
1399#if \
1400 (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1401 JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1402 JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1403 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1404 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1405 JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1406 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1407#define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1408#elif defined(JSON_HEDLEY_ASSUME)
1409#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1410#endif
1411#if !defined(JSON_HEDLEY_ASSUME)
1412#if defined(JSON_HEDLEY_UNREACHABLE)
1413#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1414#else
1415#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1416#endif
1417#endif
1418#if defined(JSON_HEDLEY_UNREACHABLE)
1419#if \
1420 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1421 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1422#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1423#else
1424#define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1425#endif
1426#else
1427#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1428#endif
1429#if !defined(JSON_HEDLEY_UNREACHABLE)
1430#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1431#endif
1432
1433JSON_HEDLEY_DIAGNOSTIC_PUSH
1434#if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1435#pragma clang diagnostic ignored "-Wpedantic"
1436#endif
1437#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1438#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1439#endif
1440#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1441#if defined(__clang__)
1442#pragma clang diagnostic ignored "-Wvariadic-macros"
1443#elif defined(JSON_HEDLEY_GCC_VERSION)
1444#pragma GCC diagnostic ignored "-Wvariadic-macros"
1445#endif
1446#endif
1447#if defined(JSON_HEDLEY_NON_NULL)
1448#undef JSON_HEDLEY_NON_NULL
1449#endif
1450#if \
1451 JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1452 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1453 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1454 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1455#define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1456#else
1457#define JSON_HEDLEY_NON_NULL(...)
1458#endif
1459JSON_HEDLEY_DIAGNOSTIC_POP
1460
1461#if defined(JSON_HEDLEY_PRINTF_FORMAT)
1462#undef JSON_HEDLEY_PRINTF_FORMAT
1463#endif
1464#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1465#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1466#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1467#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1468#elif \
1469 JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1470 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1471 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1472 JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1473 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1474 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1475 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1476 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1477 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1478 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1479 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1480 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1481 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1482 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1483 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1484 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1485 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1486#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1487#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1488#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1489#else
1490#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1491#endif
1492
1493#if defined(JSON_HEDLEY_CONSTEXPR)
1494#undef JSON_HEDLEY_CONSTEXPR
1495#endif
1496#if defined(__cplusplus)
1497#if __cplusplus >= 201103L
1498#define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1499#endif
1500#endif
1501#if !defined(JSON_HEDLEY_CONSTEXPR)
1502#define JSON_HEDLEY_CONSTEXPR
1503#endif
1504
1505#if defined(JSON_HEDLEY_PREDICT)
1506#undef JSON_HEDLEY_PREDICT
1507#endif
1508#if defined(JSON_HEDLEY_LIKELY)
1509#undef JSON_HEDLEY_LIKELY
1510#endif
1511#if defined(JSON_HEDLEY_UNLIKELY)
1512#undef JSON_HEDLEY_UNLIKELY
1513#endif
1514#if defined(JSON_HEDLEY_UNPREDICTABLE)
1515#undef JSON_HEDLEY_UNPREDICTABLE
1516#endif
1517#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1518#define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1519#endif
1520#if \
1521 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1522 JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1523 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1524# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1525# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1526# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1527# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1528# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1529#elif \
1530 (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1531 JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1532 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1533 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1534 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1535 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1536 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1537 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1538 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1539 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1540 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1541 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1542 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1543 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1544 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1545 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1546# define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1547 (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1548# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1549 (__extension__ ({ \
1550 double hedley_probability_ = (probability); \
1551 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1552 }))
1553# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1554 (__extension__ ({ \
1555 double hedley_probability_ = (probability); \
1556 ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1557 }))
1558# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1559# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1560#else
1561# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1562# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1563# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1564# define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1565# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1566#endif
1567#if !defined(JSON_HEDLEY_UNPREDICTABLE)
1568#define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1569#endif
1570
1571#if defined(JSON_HEDLEY_MALLOC)
1572#undef JSON_HEDLEY_MALLOC
1573#endif
1574#if \
1575 JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1576 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1577 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1578 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1579 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1580 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1581 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1582 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1583 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1584 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1585 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1586 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1587 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1588 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1589 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1590 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1591 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1592 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1593#define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1594#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1595#define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1596#elif \
1597 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1598 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1599#define JSON_HEDLEY_MALLOC __declspec(restrict)
1600#else
1601#define JSON_HEDLEY_MALLOC
1602#endif
1603
1604#if defined(JSON_HEDLEY_PURE)
1605#undef JSON_HEDLEY_PURE
1606#endif
1607#if \
1608 JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1609 JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1610 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1611 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1612 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1613 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1614 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1615 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1616 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1617 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1618 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1619 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1620 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1621 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1622 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1623 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1624 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1625 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1626 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1627# define JSON_HEDLEY_PURE __attribute__((__pure__))
1628#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1629# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1630#elif defined(__cplusplus) && \
1631 ( \
1632 JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1633 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1634 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1635 )
1636# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1637#else
1638# define JSON_HEDLEY_PURE
1639#endif
1640
1641#if defined(JSON_HEDLEY_CONST)
1642#undef JSON_HEDLEY_CONST
1643#endif
1644#if \
1645 JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1646 JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1647 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1648 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1649 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1650 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1651 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1652 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1653 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1654 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1655 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1656 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1657 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1658 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1659 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1660 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1661 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1662 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1663 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1664#define JSON_HEDLEY_CONST __attribute__((__const__))
1665#elif \
1666 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1667#define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1668#else
1669#define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1670#endif
1671
1672#if defined(JSON_HEDLEY_RESTRICT)
1673#undef JSON_HEDLEY_RESTRICT
1674#endif
1675#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1676#define JSON_HEDLEY_RESTRICT restrict
1677#elif \
1678 JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1679 JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1680 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1681 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1682 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1683 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1684 JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1685 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1686 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1687 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1688 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1689 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1690 JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1691 defined(__clang__) || \
1692 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1693#define JSON_HEDLEY_RESTRICT __restrict
1694#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1695#define JSON_HEDLEY_RESTRICT _Restrict
1696#else
1697#define JSON_HEDLEY_RESTRICT
1698#endif
1699
1700#if defined(JSON_HEDLEY_INLINE)
1701#undef JSON_HEDLEY_INLINE
1702#endif
1703#if \
1704 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1705 (defined(__cplusplus) && (__cplusplus >= 199711L))
1706#define JSON_HEDLEY_INLINE inline
1707#elif \
1708 defined(JSON_HEDLEY_GCC_VERSION) || \
1709 JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1710#define JSON_HEDLEY_INLINE __inline__
1711#elif \
1712 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1713 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1714 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1715 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1716 JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1717 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1718 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1719 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1720 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1721 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1722#define JSON_HEDLEY_INLINE __inline
1723#else
1724#define JSON_HEDLEY_INLINE
1725#endif
1726
1727#if defined(JSON_HEDLEY_ALWAYS_INLINE)
1728#undef JSON_HEDLEY_ALWAYS_INLINE
1729#endif
1730#if \
1731 JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1732 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1733 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1734 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1735 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1736 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1737 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1738 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1739 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1740 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1741 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1742 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1743 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1744 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1745 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1746 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1747 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1748 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1749 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1750# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1751#elif \
1752 JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1753 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1754# define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1755#elif defined(__cplusplus) && \
1756 ( \
1757 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1758 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1759 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1760 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1761 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1762 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1763 )
1764# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1765#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1766# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1767#else
1768# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1769#endif
1770
1771#if defined(JSON_HEDLEY_NEVER_INLINE)
1772#undef JSON_HEDLEY_NEVER_INLINE
1773#endif
1774#if \
1775 JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1776 JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1777 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1778 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1779 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1780 JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1781 JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1782 (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1783 JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1784 (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1785 JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1786 (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1787 JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1788 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1789 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1790 JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1791 JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1792 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1793 JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1794#define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1795#elif \
1796 JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1797 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1798#define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1799#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1800#define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1801#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1802#define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1803#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1804#define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1805#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1806#define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1807#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1808#define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1809#else
1810#define JSON_HEDLEY_NEVER_INLINE
1811#endif
1812
1813#if defined(JSON_HEDLEY_PRIVATE)
1814#undef JSON_HEDLEY_PRIVATE
1815#endif
1816#if defined(JSON_HEDLEY_PUBLIC)
1817#undef JSON_HEDLEY_PUBLIC
1818#endif
1819#if defined(JSON_HEDLEY_IMPORT)
1820#undef JSON_HEDLEY_IMPORT
1821#endif
1822#if defined(_WIN32) || defined(__CYGWIN__)
1823# define JSON_HEDLEY_PRIVATE
1824# define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1825# define JSON_HEDLEY_IMPORT __declspec(dllimport)
1826#else
1827# if \
1828 JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1829 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1830 JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1831 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1832 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1833 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1834 ( \
1835 defined(__TI_EABI__) && \
1836 ( \
1837 (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1838 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1839 ) \
1840 ) || \
1841 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1842# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1843# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1844# else
1845# define JSON_HEDLEY_PRIVATE
1846# define JSON_HEDLEY_PUBLIC
1847# endif
1848# define JSON_HEDLEY_IMPORT extern
1849#endif
1850
1851#if defined(JSON_HEDLEY_NO_THROW)
1852#undef JSON_HEDLEY_NO_THROW
1853#endif
1854#if \
1855 JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1856 JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1857 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1858 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1859#define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1860#elif \
1861 JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1862 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1863 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1864#define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1865#else
1866#define JSON_HEDLEY_NO_THROW
1867#endif
1868
1869#if defined(JSON_HEDLEY_FALL_THROUGH)
1870#undef JSON_HEDLEY_FALL_THROUGH
1871#endif
1872#if \
1873 JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1874 JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
1875 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1876#define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1877#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1878#define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1879#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1880#define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1881#elif defined(__fallthrough) /* SAL */
1882#define JSON_HEDLEY_FALL_THROUGH __fallthrough
1883#else
1884#define JSON_HEDLEY_FALL_THROUGH
1885#endif
1886
1887#if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1888#undef JSON_HEDLEY_RETURNS_NON_NULL
1889#endif
1890#if \
1891 JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1892 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1893 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1894#define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1895#elif defined(_Ret_notnull_) /* SAL */
1896#define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1897#else
1898#define JSON_HEDLEY_RETURNS_NON_NULL
1899#endif
1900
1901#if defined(JSON_HEDLEY_ARRAY_PARAM)
1902#undef JSON_HEDLEY_ARRAY_PARAM
1903#endif
1904#if \
1905 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1906 !defined(__STDC_NO_VLA__) && \
1907 !defined(__cplusplus) && \
1908 !defined(JSON_HEDLEY_PGI_VERSION) && \
1909 !defined(JSON_HEDLEY_TINYC_VERSION)
1910#define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1911#else
1912#define JSON_HEDLEY_ARRAY_PARAM(name)
1913#endif
1914
1915#if defined(JSON_HEDLEY_IS_CONSTANT)
1916#undef JSON_HEDLEY_IS_CONSTANT
1917#endif
1918#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1919#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1920#endif
1921/* JSON_HEDLEY_IS_CONSTEXPR_ is for
1922 HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1923#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1924#undef JSON_HEDLEY_IS_CONSTEXPR_
1925#endif
1926#if \
1927 JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1928 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1929 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1930 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1931 JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1932 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1933 JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1934 (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1935 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1936 JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1937#define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1938#endif
1939#if !defined(__cplusplus)
1940# if \
1941 JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1942 JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1943 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1944 JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1945 JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1946 JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1947 JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1948#if defined(__INTPTR_TYPE__)
1949#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1950#else
1951#include <stdint.h>
1952#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1953#endif
1954# elif \
1955 ( \
1956 defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1957 !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1958 !defined(JSON_HEDLEY_PGI_VERSION) && \
1959 !defined(JSON_HEDLEY_IAR_VERSION)) || \
1960 (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1961 JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1962 JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1963 JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1964 JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1965#if defined(__INTPTR_TYPE__)
1966#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1967#else
1968#include <stdint.h>
1969#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1970#endif
1971# elif \
1972 defined(JSON_HEDLEY_GCC_VERSION) || \
1973 defined(JSON_HEDLEY_INTEL_VERSION) || \
1974 defined(JSON_HEDLEY_TINYC_VERSION) || \
1975 defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1976 JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1977 defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1978 defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1979 defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1980 defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1981 defined(__clang__)
1982# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1983 sizeof(void) != \
1984 sizeof(*( \
1985 1 ? \
1986 ((void*) ((expr) * 0L) ) : \
1987((struct { char v[sizeof(void) * 2]; } *) 1) \
1988 ) \
1989 ) \
1990 )
1991# endif
1992#endif
1993#if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1994#if !defined(JSON_HEDLEY_IS_CONSTANT)
1995#define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1996#endif
1997#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1998#else
1999#if !defined(JSON_HEDLEY_IS_CONSTANT)
2000#define JSON_HEDLEY_IS_CONSTANT(expr) (0)
2001#endif
2002#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
2003#endif
2004
2005#if defined(JSON_HEDLEY_BEGIN_C_DECLS)
2006#undef JSON_HEDLEY_BEGIN_C_DECLS
2007#endif
2008#if defined(JSON_HEDLEY_END_C_DECLS)
2009#undef JSON_HEDLEY_END_C_DECLS
2010#endif
2011#if defined(JSON_HEDLEY_C_DECL)
2012#undef JSON_HEDLEY_C_DECL
2013#endif
2014#if defined(__cplusplus)
2015#define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
2016#define JSON_HEDLEY_END_C_DECLS }
2017#define JSON_HEDLEY_C_DECL extern "C"
2018#else
2019#define JSON_HEDLEY_BEGIN_C_DECLS
2020#define JSON_HEDLEY_END_C_DECLS
2021#define JSON_HEDLEY_C_DECL
2022#endif
2023
2024#if defined(JSON_HEDLEY_STATIC_ASSERT)
2025#undef JSON_HEDLEY_STATIC_ASSERT
2026#endif
2027#if \
2028 !defined(__cplusplus) && ( \
2029 (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
2030 (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
2031 JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
2032 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
2033 defined(_Static_assert) \
2034 )
2035# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
2036#elif \
2037 (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
2038 JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
2039 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2040# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
2041#else
2042# define JSON_HEDLEY_STATIC_ASSERT(expr, message)
2043#endif
2044
2045#if defined(JSON_HEDLEY_NULL)
2046#undef JSON_HEDLEY_NULL
2047#endif
2048#if defined(__cplusplus)
2049#if __cplusplus >= 201103L
2050#define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
2051#elif defined(NULL)
2052#define JSON_HEDLEY_NULL NULL
2053#else
2054#define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
2055#endif
2056#elif defined(NULL)
2057#define JSON_HEDLEY_NULL NULL
2058#else
2059#define JSON_HEDLEY_NULL ((void*) 0)
2060#endif
2061
2062#if defined(JSON_HEDLEY_MESSAGE)
2063#undef JSON_HEDLEY_MESSAGE
2064#endif
2065#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2066# define JSON_HEDLEY_MESSAGE(msg) \
2067 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2068 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2069 JSON_HEDLEY_PRAGMA(message msg) \
2070 JSON_HEDLEY_DIAGNOSTIC_POP
2071#elif \
2072 JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2073 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2074# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2075#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2076# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2077#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2078# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2079#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2080# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2081#else
2082# define JSON_HEDLEY_MESSAGE(msg)
2083#endif
2084
2085#if defined(JSON_HEDLEY_WARNING)
2086#undef JSON_HEDLEY_WARNING
2087#endif
2088#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2089# define JSON_HEDLEY_WARNING(msg) \
2090 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2091 JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2092 JSON_HEDLEY_PRAGMA(clang warning msg) \
2093 JSON_HEDLEY_DIAGNOSTIC_POP
2094#elif \
2095 JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2096 JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2097 JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2098# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2099#elif \
2100 JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2101 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2102# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2103#else
2104# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2105#endif
2106
2107#if defined(JSON_HEDLEY_REQUIRE)
2108#undef JSON_HEDLEY_REQUIRE
2109#endif
2110#if defined(JSON_HEDLEY_REQUIRE_MSG)
2111#undef JSON_HEDLEY_REQUIRE_MSG
2112#endif
2113#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2114# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2115# define JSON_HEDLEY_REQUIRE(expr) \
2116 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2117 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2118 __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2119 JSON_HEDLEY_DIAGNOSTIC_POP
2120# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2121 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2122 _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2123 __attribute__((diagnose_if(!(expr), msg, "error"))) \
2124 JSON_HEDLEY_DIAGNOSTIC_POP
2125# else
2126# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2127# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2128# endif
2129#else
2130# define JSON_HEDLEY_REQUIRE(expr)
2131# define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2132#endif
2133
2134#if defined(JSON_HEDLEY_FLAGS)
2135#undef JSON_HEDLEY_FLAGS
2136#endif
2137#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2138#define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2139#else
2140#define JSON_HEDLEY_FLAGS
2141#endif
2142
2143#if defined(JSON_HEDLEY_FLAGS_CAST)
2144#undef JSON_HEDLEY_FLAGS_CAST
2145#endif
2146#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2147# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2148 JSON_HEDLEY_DIAGNOSTIC_PUSH \
2149 _Pragma("warning(disable:188)") \
2150 ((T) (expr)); \
2151 JSON_HEDLEY_DIAGNOSTIC_POP \
2152 }))
2153#else
2154# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2155#endif
2156
2157#if defined(JSON_HEDLEY_EMPTY_BASES)
2158#undef JSON_HEDLEY_EMPTY_BASES
2159#endif
2160#if \
2161 (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2162 JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2163#define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2164#else
2165#define JSON_HEDLEY_EMPTY_BASES
2166#endif
2167
2168/* Remaining macros are deprecated. */
2169
2170#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2171#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2172#endif
2173#if defined(__clang__)
2174#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2175#else
2176#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2177#endif
2178
2179#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2180#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2181#endif
2182#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2183
2184#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2185#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2186#endif
2187#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2188
2189#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2190#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2191#endif
2192#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2193
2194#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2195#undef JSON_HEDLEY_CLANG_HAS_FEATURE
2196#endif
2197#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2198
2199#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2200#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2201#endif
2202#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2203
2204#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2205#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2206#endif
2207#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2208
2209#if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2210#undef JSON_HEDLEY_CLANG_HAS_WARNING
2211#endif
2212#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2213
2214#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2215
2216
2217// This file contains all internal macro definitions
2218// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2219
2220// exclude unsupported compilers
2221#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2222#if defined(__clang__)
2223#if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2224#error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2225#endif
2226#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2227#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2228#error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2229#endif
2230#endif
2231#endif
2232
2233// C++ language standard detection
2234// if the user manually specified the used c++ version this is skipped
2235#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2236#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2237#define JSON_HAS_CPP_20
2238#define JSON_HAS_CPP_17
2239#define JSON_HAS_CPP_14
2240#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2241#define JSON_HAS_CPP_17
2242#define JSON_HAS_CPP_14
2243#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2244#define JSON_HAS_CPP_14
2245#endif
2246// the cpp 11 flag is always specified because it is the minimal required version
2247#define JSON_HAS_CPP_11
2248#endif
2249
2250// disable documentation warnings on clang
2251#if defined(__clang__)
2252#pragma clang diagnostic push
2253#pragma clang diagnostic ignored "-Wdocumentation"
2254#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2255#endif
2256
2257// allow to disable exceptions
2258#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2259#define JSON_THROW(exception) throw exception
2260#define JSON_TRY try
2261#define JSON_CATCH(exception) catch(exception)
2262#define JSON_INTERNAL_CATCH(exception) catch(exception)
2263#else
2264#include <cstdlib>
2265#define JSON_THROW(exception) std::abort()
2266#define JSON_TRY if(true)
2267#define JSON_CATCH(exception) if(false)
2268#define JSON_INTERNAL_CATCH(exception) if(false)
2269#endif
2270
2271// override exception macros
2272#if defined(JSON_THROW_USER)
2273#undef JSON_THROW
2274#define JSON_THROW JSON_THROW_USER
2275#endif
2276#if defined(JSON_TRY_USER)
2277#undef JSON_TRY
2278#define JSON_TRY JSON_TRY_USER
2279#endif
2280#if defined(JSON_CATCH_USER)
2281#undef JSON_CATCH
2282#define JSON_CATCH JSON_CATCH_USER
2283#undef JSON_INTERNAL_CATCH
2284#define JSON_INTERNAL_CATCH JSON_CATCH_USER
2285#endif
2286#if defined(JSON_INTERNAL_CATCH_USER)
2287#undef JSON_INTERNAL_CATCH
2288#define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2289#endif
2290
2291// allow to override assert
2292#if !defined(JSON_ASSERT)
2293#include <cassert> // assert
2294#define JSON_ASSERT(x) assert(x)
2295#endif
2296
2297// allow to access some private functions (needed by the test suite)
2298#if defined(JSON_TESTS_PRIVATE)
2299#define JSON_PRIVATE_UNLESS_TESTED public
2300#else
2301#define JSON_PRIVATE_UNLESS_TESTED private
2302#endif
2303
2309#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2310 template<typename BasicJsonType> \
2311 inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2312 { \
2313 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2314 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2315 auto it = std::find_if(std::begin(m), std::end(m), \
2316 [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2317 { \
2318 return ej_pair.first == e; \
2319 }); \
2320 j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2321 } \
2322 template<typename BasicJsonType> \
2323 inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2324 { \
2325 static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2326 static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2327 auto it = std::find_if(std::begin(m), std::end(m), \
2328 [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2329 { \
2330 return ej_pair.second == j; \
2331 }); \
2332 e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2333 }
2334
2335// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2336// may be removed in the future once the class is split.
2337
2338#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2339 template<template<typename, typename, typename...> class ObjectType, \
2340 template<typename, typename...> class ArrayType, \
2341 class StringType, class BooleanType, class NumberIntegerType, \
2342 class NumberUnsignedType, class NumberFloatType, \
2343 template<typename> class AllocatorType, \
2344 template<typename, typename = void> class JSONSerializer, \
2345 class BinaryType>
2346
2347#define NLOHMANN_BASIC_JSON_TPL \
2348 basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2349 NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2350 AllocatorType, JSONSerializer, BinaryType>
2351
2352// Macros to simplify conversion from/to types
2353
2354#define NLOHMANN_JSON_EXPAND( x ) x
2355#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
2356#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2357 NLOHMANN_JSON_PASTE64, \
2358 NLOHMANN_JSON_PASTE63, \
2359 NLOHMANN_JSON_PASTE62, \
2360 NLOHMANN_JSON_PASTE61, \
2361 NLOHMANN_JSON_PASTE60, \
2362 NLOHMANN_JSON_PASTE59, \
2363 NLOHMANN_JSON_PASTE58, \
2364 NLOHMANN_JSON_PASTE57, \
2365 NLOHMANN_JSON_PASTE56, \
2366 NLOHMANN_JSON_PASTE55, \
2367 NLOHMANN_JSON_PASTE54, \
2368 NLOHMANN_JSON_PASTE53, \
2369 NLOHMANN_JSON_PASTE52, \
2370 NLOHMANN_JSON_PASTE51, \
2371 NLOHMANN_JSON_PASTE50, \
2372 NLOHMANN_JSON_PASTE49, \
2373 NLOHMANN_JSON_PASTE48, \
2374 NLOHMANN_JSON_PASTE47, \
2375 NLOHMANN_JSON_PASTE46, \
2376 NLOHMANN_JSON_PASTE45, \
2377 NLOHMANN_JSON_PASTE44, \
2378 NLOHMANN_JSON_PASTE43, \
2379 NLOHMANN_JSON_PASTE42, \
2380 NLOHMANN_JSON_PASTE41, \
2381 NLOHMANN_JSON_PASTE40, \
2382 NLOHMANN_JSON_PASTE39, \
2383 NLOHMANN_JSON_PASTE38, \
2384 NLOHMANN_JSON_PASTE37, \
2385 NLOHMANN_JSON_PASTE36, \
2386 NLOHMANN_JSON_PASTE35, \
2387 NLOHMANN_JSON_PASTE34, \
2388 NLOHMANN_JSON_PASTE33, \
2389 NLOHMANN_JSON_PASTE32, \
2390 NLOHMANN_JSON_PASTE31, \
2391 NLOHMANN_JSON_PASTE30, \
2392 NLOHMANN_JSON_PASTE29, \
2393 NLOHMANN_JSON_PASTE28, \
2394 NLOHMANN_JSON_PASTE27, \
2395 NLOHMANN_JSON_PASTE26, \
2396 NLOHMANN_JSON_PASTE25, \
2397 NLOHMANN_JSON_PASTE24, \
2398 NLOHMANN_JSON_PASTE23, \
2399 NLOHMANN_JSON_PASTE22, \
2400 NLOHMANN_JSON_PASTE21, \
2401 NLOHMANN_JSON_PASTE20, \
2402 NLOHMANN_JSON_PASTE19, \
2403 NLOHMANN_JSON_PASTE18, \
2404 NLOHMANN_JSON_PASTE17, \
2405 NLOHMANN_JSON_PASTE16, \
2406 NLOHMANN_JSON_PASTE15, \
2407 NLOHMANN_JSON_PASTE14, \
2408 NLOHMANN_JSON_PASTE13, \
2409 NLOHMANN_JSON_PASTE12, \
2410 NLOHMANN_JSON_PASTE11, \
2411 NLOHMANN_JSON_PASTE10, \
2412 NLOHMANN_JSON_PASTE9, \
2413 NLOHMANN_JSON_PASTE8, \
2414 NLOHMANN_JSON_PASTE7, \
2415 NLOHMANN_JSON_PASTE6, \
2416 NLOHMANN_JSON_PASTE5, \
2417 NLOHMANN_JSON_PASTE4, \
2418 NLOHMANN_JSON_PASTE3, \
2419 NLOHMANN_JSON_PASTE2, \
2420 NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2421#define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2422#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2423#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2424#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2425#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2426#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)
2427#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)
2428#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)
2429#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)
2430#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)
2431#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)
2432#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)
2433#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)
2434#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)
2435#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)
2436#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)
2437#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)
2438#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)
2439#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)
2440#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)
2441#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)
2442#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)
2443#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)
2444#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)
2445#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)
2446#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)
2447#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)
2448#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)
2449#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)
2450#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)
2451#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)
2452#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)
2453#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)
2454#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)
2455#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)
2456#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)
2457#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)
2458#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)
2459#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)
2460#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)
2461#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)
2462#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)
2463#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)
2464#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)
2465#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)
2466#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)
2467#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)
2468#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)
2469#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)
2470#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)
2471#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)
2472#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)
2473#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)
2474#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)
2475#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)
2476#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)
2477#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)
2478#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)
2479#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)
2480#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)
2481#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)
2482#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)
2483#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)
2484
2485#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2486#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2487
2493#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2494 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__)) } \
2495 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__)) }
2496
2502#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2503 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__)) } \
2504 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__)) }
2505
2506#ifndef JSON_USE_IMPLICIT_CONVERSIONS
2507#define JSON_USE_IMPLICIT_CONVERSIONS 1
2508#endif
2509
2510#if JSON_USE_IMPLICIT_CONVERSIONS
2511#define JSON_EXPLICIT
2512#else
2513#define JSON_EXPLICIT explicit
2514#endif
2515
2516#ifndef JSON_DIAGNOSTICS
2517#define JSON_DIAGNOSTICS 0
2518#endif
2519
2520
2521namespace nlohmann
2522{
2523namespace detail
2524{
2525
2539inline void replace_substring(std::string &s, const std::string &f,
2540 const std::string &t)
2541{
2542 JSON_ASSERT(!f.empty());
2543
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{
2651public:
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
2661protected:
2662 JSON_HEDLEY_NON_NULL(3)
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
2676 for (const auto *current = &leaf_element; current->m_parent != nullptr; current = current->m_parent)
2677 {
2678 switch (current->m_parent->type())
2679 {
2680 case value_t::array:
2681 {
2682 for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
2683 {
2684 if (&current->m_parent->m_value.array->operator[](i) == current)
2685 {
2686 tokens.emplace_back(std::to_string(i));
2687 break;
2688 }
2689 }
2690
2691 break;
2692 }
2693
2694 case value_t::object:
2695 {
2696 for (const auto &element : *current->m_parent->m_value.object)
2697 {
2698 if (&element.second == current)
2699 {
2700 tokens.emplace_back(element.first.c_str());
2701 break;
2702 }
2703 }
2704
2705 break;
2706 }
2707
2708 case value_t::null: // LCOV_EXCL_LINE
2709 case value_t::string: // LCOV_EXCL_LINE
2710 case value_t::boolean: // LCOV_EXCL_LINE
2711 case value_t::number_integer: // LCOV_EXCL_LINE
2712 case value_t::number_unsigned: // LCOV_EXCL_LINE
2713 case value_t::number_float: // LCOV_EXCL_LINE
2714 case value_t::binary: // LCOV_EXCL_LINE
2715 case value_t::discarded: // LCOV_EXCL_LINE
2716 default: // LCOV_EXCL_LINE
2717 break; // LCOV_EXCL_LINE
2718 }
2719 }
2720
2721 if (tokens.empty())
2722 {
2723 return "";
2724 }
2725
2726 return "(" + std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
2727 [](const std::string & a, const std::string & b)
2728 {
2729 return a + "/" + detail::escape(b);
2730 }) + ") ";
2731#else
2732 static_cast<void>(leaf_element);
2733 return "";
2734#endif
2735 }
2736
2737private:
2739 std::runtime_error m;
2740};
2741
2788{
2789public:
2799 template<typename BasicJsonType>
2800 static parse_error create(int id_, const position_t &pos, const std::string &what_arg, const BasicJsonType &context)
2801 {
2802 std::string w = exception::name("parse_error", id_) + "parse error" +
2803 position_string(pos) + ": " + exception::diagnostics(context) + what_arg;
2804 return parse_error(id_, pos.chars_read_total, w.c_str());
2805 }
2806
2807 template<typename BasicJsonType>
2808 static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, const BasicJsonType &context)
2809 {
2810 std::string w = exception::name("parse_error", id_) + "parse error" +
2811 (byte_ != 0 ? (" at byte " + std::to_string(byte_)) : "") +
2812 ": " + exception::diagnostics(context) + what_arg;
2813 return parse_error(id_, byte_, w.c_str());
2814 }
2815
2825 const std::size_t byte;
2826
2827private:
2828 parse_error(int id_, std::size_t byte_, const char *what_arg)
2829 : exception(id_, what_arg), byte(byte_) {}
2830
2831 static std::string position_string(const position_t &pos)
2832 {
2833 return " at line " + std::to_string(pos.lines_read + 1) +
2834 ", column " + std::to_string(pos.chars_read_current_line);
2835 }
2836};
2837
2876{
2877public:
2878 template<typename BasicJsonType>
2879 static invalid_iterator create(int id_, const std::string &what_arg, const BasicJsonType &context)
2880 {
2881 std::string w = exception::name("invalid_iterator", id_) + exception::diagnostics(context) + what_arg;
2882 return invalid_iterator(id_, w.c_str());
2883 }
2884
2885private:
2886 JSON_HEDLEY_NON_NULL(3)
2887 invalid_iterator(int id_, const char *what_arg)
2888 : exception(id_, what_arg) {}
2889};
2890
2930class type_error : public exception
2931{
2932public:
2933 template<typename BasicJsonType>
2934 static type_error create(int id_, const std::string &what_arg, const BasicJsonType &context)
2935 {
2936 std::string w = exception::name("type_error", id_) + exception::diagnostics(context) + what_arg;
2937 return type_error(id_, w.c_str());
2938 }
2939
2940private:
2941 JSON_HEDLEY_NON_NULL(3)
2942 type_error(int id_, const char *what_arg) : exception(id_, what_arg) {}
2943};
2944
2979{
2980public:
2981 template<typename BasicJsonType>
2982 static out_of_range create(int id_, const std::string &what_arg, const BasicJsonType &context)
2983 {
2984 std::string w = exception::name("out_of_range", id_) + exception::diagnostics(context) + what_arg;
2985 return out_of_range(id_, w.c_str());
2986 }
2987
2988private:
2989 JSON_HEDLEY_NON_NULL(3)
2990 out_of_range(int id_, const char *what_arg) : exception(id_, what_arg) {}
2991};
2992
3018{
3019public:
3020 template<typename BasicJsonType>
3021 static other_error create(int id_, const std::string &what_arg, const BasicJsonType &context)
3022 {
3023 std::string w = exception::name("other_error", id_) + exception::diagnostics(context) + what_arg;
3024 return other_error(id_, w.c_str());
3025 }
3026
3027private:
3028 JSON_HEDLEY_NON_NULL(3)
3029 other_error(int id_, const char *what_arg) : exception(id_, what_arg) {}
3030};
3031} // namespace detail
3032} // namespace nlohmann
3033
3034// #include <nlohmann/detail/macro_scope.hpp>
3035
3036// #include <nlohmann/detail/meta/cpp_future.hpp>
3037
3038
3039#include <cstddef> // size_t
3040#include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
3041#include <utility> // index_sequence, make_index_sequence, index_sequence_for
3042
3043// #include <nlohmann/detail/macro_scope.hpp>
3044
3045
3046namespace nlohmann
3047{
3048namespace detail
3049{
3050
3051template<typename T>
3052using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
3053
3054#ifdef JSON_HAS_CPP_14
3055
3056// the following utilities are natively available in C++14
3057using std::enable_if_t;
3058using std::index_sequence;
3059using std::make_index_sequence;
3060using std::index_sequence_for;
3061
3062#else
3063
3064// alias templates to reduce boilerplate
3065template<bool B, typename T = void>
3066using enable_if_t = typename std::enable_if<B, T>::type;
3067
3068// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
3069// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
3070
3072
3073// integer_sequence
3074//
3075// Class template representing a compile-time integer sequence. An instantiation
3076// of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
3077// type through its template arguments (which is a common need when
3078// working with C++11 variadic templates). `absl::integer_sequence` is designed
3079// to be a drop-in replacement for C++14's `std::integer_sequence`.
3080//
3081// Example:
3082//
3083// template< class T, T... Ints >
3084// void user_function(integer_sequence<T, Ints...>);
3085//
3086// int main()
3087// {
3088// // user_function's `T` will be deduced to `int` and `Ints...`
3089// // will be deduced to `0, 1, 2, 3, 4`.
3090// user_function(make_integer_sequence<int, 5>());
3091// }
3092template <typename T, T... Ints>
3094{
3095 using value_type = T;
3096 static constexpr std::size_t size() noexcept
3097 {
3098 return sizeof...(Ints);
3099 }
3100};
3101
3102// index_sequence
3103//
3104// A helper template for an `integer_sequence` of `size_t`,
3105// `absl::index_sequence` is designed to be a drop-in replacement for C++14's
3106// `std::index_sequence`.
3107template <size_t... Ints>
3108using index_sequence = integer_sequence<size_t, Ints...>;
3109
3110namespace utility_internal
3111{
3112
3113template <typename Seq, size_t SeqSize, size_t Rem>
3114struct Extend;
3115
3116// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
3117template <typename T, T... Ints, size_t SeqSize>
3118struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
3119{
3120 using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
3121};
3122
3123template <typename T, T... Ints, size_t SeqSize>
3124struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
3125{
3126 using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
3127};
3128
3129// Recursion helper for 'make_integer_sequence<T, N>'.
3130// 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
3131template <typename T, size_t N>
3132struct Gen
3133{
3134 using type =
3135 typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
3136};
3137
3138template <typename T>
3139struct Gen<T, 0>
3140{
3141 using type = integer_sequence<T>;
3142};
3143
3144} // namespace utility_internal
3145
3146// Compile-time sequences of integers
3147
3148// make_integer_sequence
3149//
3150// This template alias is equivalent to
3151// `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3152// replacement for C++14's `std::make_integer_sequence`.
3153template <typename T, T N>
3154using make_integer_sequence = typename utility_internal::Gen<T, N>::type;
3155
3156// make_index_sequence
3157//
3158// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3159// and is designed to be a drop-in replacement for C++14's
3160// `std::make_index_sequence`.
3161template <size_t N>
3162using make_index_sequence = make_integer_sequence<size_t, N>;
3163
3164// index_sequence_for
3165//
3166// Converts a typename pack into an index sequence of the same length, and
3167// is designed to be a drop-in replacement for C++14's
3168// `std::index_sequence_for()`
3169template <typename... Ts>
3170using index_sequence_for = make_index_sequence<sizeof...(Ts)>;
3171
3173
3174#endif
3175
3176// dispatch utility (taken from ranges-v3)
3177template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3178template<> struct priority_tag<0> {};
3179
3180// taken from ranges-v3
3181template<typename T>
3183{
3184 static constexpr T value{};
3185};
3186
3187template<typename T>
3188constexpr T static_const<T>::value;
3189
3190} // namespace detail
3191} // namespace nlohmann
3192
3193// #include <nlohmann/detail/meta/identity_tag.hpp>
3194
3195
3196namespace nlohmann
3197{
3198namespace detail
3199{
3200// dispatching helper struct
3201template <class T> struct identity_tag {};
3202} // namespace detail
3203} // namespace nlohmann
3204
3205// #include <nlohmann/detail/meta/type_traits.hpp>
3206
3207
3208#include <limits> // numeric_limits
3209#include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3210#include <utility> // declval
3211#include <tuple> // tuple
3212
3213// #include <nlohmann/detail/iterators/iterator_traits.hpp>
3214
3215
3216#include <iterator> // random_access_iterator_tag
3217
3218// #include <nlohmann/detail/meta/void_t.hpp>
3219
3220
3221namespace nlohmann
3222{
3223namespace detail
3224{
3225template<typename ...Ts> struct make_void
3226{
3227 using type = void;
3228};
3229template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
3230} // namespace detail
3231} // namespace nlohmann
3232
3233// #include <nlohmann/detail/meta/cpp_future.hpp>
3234
3235
3236namespace nlohmann
3237{
3238namespace detail
3239{
3240template<typename It, typename = void>
3242
3243template<typename It>
3245 It,
3246 void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3247 typename It::reference, typename It::iterator_category >>
3248{
3249 using difference_type = typename It::difference_type;
3250 using value_type = typename It::value_type;
3251 using pointer = typename It::pointer;
3252 using reference = typename It::reference;
3253 using iterator_category = typename It::iterator_category;
3254};
3255
3256// This is required as some compilers implement std::iterator_traits in a way that
3257// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3258template<typename T, typename = void>
3260{
3261};
3262
3263template<typename T>
3264struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3265 : iterator_types<T>
3266{
3267};
3268
3269template<typename T>
3270struct iterator_traits<T *, enable_if_t<std::is_object<T>::value>>
3271{
3272 using iterator_category = std::random_access_iterator_tag;
3273 using value_type = T;
3274 using difference_type = ptrdiff_t;
3275 using pointer = T*;
3276 using reference = T&;
3277};
3278} // namespace detail
3279} // namespace nlohmann
3280
3281// #include <nlohmann/detail/macro_scope.hpp>
3282
3283// #include <nlohmann/detail/meta/cpp_future.hpp>
3284
3285// #include <nlohmann/detail/meta/detected.hpp>
3286
3287
3288#include <type_traits>
3289
3290// #include <nlohmann/detail/meta/void_t.hpp>
3291
3292
3293// https://en.cppreference.com/w/cpp/experimental/is_detected
3294namespace nlohmann
3295{
3296namespace detail
3297{
3299{
3300 nonesuch() = delete;
3301 ~nonesuch() = delete;
3302 nonesuch(nonesuch const &) = delete;
3303 nonesuch(nonesuch const &&) = delete;
3304 void operator=(nonesuch const &) = delete;
3305 void operator=(nonesuch &&) = delete;
3306};
3307
3308template<class Default,
3309 class AlwaysVoid,
3310 template<class...> class Op,
3311 class... Args>
3313{
3314 using value_t = std::false_type;
3315 using type = Default;
3316};
3317
3318template<class Default, template<class...> class Op, class... Args>
3319struct detector<Default, void_t<Op<Args...>>, Op, Args...>
3320{
3321 using value_t = std::true_type;
3322 using type = Op<Args...>;
3323};
3324
3325template<template<class...> class Op, class... Args>
3326using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
3327
3328template<template<class...> class Op, class... Args>
3329struct is_detected_lazy : is_detected<Op, Args...> { };
3330
3331template<template<class...> class Op, class... Args>
3332using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
3333
3334template<class Default, template<class...> class Op, class... Args>
3335using detected_or = detector<Default, void, Op, Args...>;
3336
3337template<class Default, template<class...> class Op, class... Args>
3338using detected_or_t = typename detected_or<Default, Op, Args...>::type;
3339
3340template<class Expected, template<class...> class Op, class... Args>
3341using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
3342
3343template<class To, template<class...> class Op, class... Args>
3344using is_detected_convertible =
3345 std::is_convertible<detected_t<Op, Args...>, To>;
3346} // namespace detail
3347} // namespace nlohmann
3348
3349// #include <nlohmann/json_fwd.hpp>
3350#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3351#define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3352
3353#include <cstdint> // int64_t, uint64_t
3354#include <map> // map
3355#include <memory> // allocator
3356#include <string> // string
3357#include <vector> // vector
3358
3364namespace nlohmann
3365{
3373template<typename T = void, typename SFINAE = void>
3374struct adl_serializer;
3375
3376template<template<typename U, typename V, typename... Args> class ObjectType =
3377 std::map,
3378 template<typename U, typename... Args> class ArrayType = std::vector,
3379 class StringType = std::string, class BooleanType = bool,
3380 class NumberIntegerType = std::int64_t,
3381 class NumberUnsignedType = std::uint64_t,
3382 class NumberFloatType = double,
3383 template<typename U> class AllocatorType = std::allocator,
3384 template<typename T, typename SFINAE = void> class JSONSerializer =
3385 adl_serializer,
3386 class BinaryType = std::vector<std::uint8_t>>
3387class basic_json;
3388
3400template<typename BasicJsonType>
3401class json_pointer;
3402
3412
3413template<class Key, class T, class IgnoredLess, class Allocator>
3414struct ordered_map;
3415
3424
3425} // namespace nlohmann
3426
3427#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3428
3429
3430namespace nlohmann
3431{
3440namespace detail
3441{
3443// helpers //
3445
3446// Note to maintainers:
3447//
3448// Every trait in this file expects a non CV-qualified type.
3449// The only exceptions are in the 'aliases for detected' section
3450// (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3451//
3452// In this case, T has to be properly CV-qualified to constraint the function arguments
3453// (e.g. to_json(BasicJsonType&, const T&))
3454
3455template<typename> struct is_basic_json : std::false_type {};
3456
3457NLOHMANN_BASIC_JSON_TPL_DECLARATION
3458struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3459
3461// json_ref helpers //
3463
3464template<typename>
3465class json_ref;
3466
3467template<typename>
3468struct is_json_ref : std::false_type {};
3469
3470template<typename T>
3471struct is_json_ref<json_ref<T>> : std::true_type {};
3472
3474// aliases for detected //
3476
3477template<typename T>
3478using mapped_type_t = typename T::mapped_type;
3479
3480template<typename T>
3481using key_type_t = typename T::key_type;
3482
3483template<typename T>
3484using value_type_t = typename T::value_type;
3485
3486template<typename T>
3487using difference_type_t = typename T::difference_type;
3488
3489template<typename T>
3490using pointer_t = typename T::pointer;
3491
3492template<typename T>
3493using reference_t = typename T::reference;
3494
3495template<typename T>
3496using iterator_category_t = typename T::iterator_category;
3497
3498template<typename T>
3499using iterator_t = typename T::iterator;
3500
3501template<typename T, typename... Args>
3502using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3503
3504template<typename T, typename... Args>
3505using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3506
3507template<typename T, typename U>
3508using get_template_function = decltype(std::declval<T>().template get<U>());
3509
3510// trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3511template<typename BasicJsonType, typename T, typename = void>
3512struct has_from_json : std::false_type {};
3513
3514// trait checking if j.get<T> is valid
3515// use this trait instead of std::is_constructible or std::is_convertible,
3516// both rely on, or make use of implicit conversions, and thus fail when T
3517// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3518template <typename BasicJsonType, typename T>
3520{
3521 static constexpr bool value = is_detected<get_template_function, const BasicJsonType &, T>::value;
3522};
3523
3524template<typename BasicJsonType, typename T>
3525struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3526{
3527 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3528
3529 static constexpr bool value =
3530 is_detected_exact<void, from_json_function, serializer,
3531 const BasicJsonType &, T &>::value;
3532};
3533
3534// This trait checks if JSONSerializer<T>::from_json(json const&) exists
3535// this overload is used for non-default-constructible user-defined-types
3536template<typename BasicJsonType, typename T, typename = void>
3537struct has_non_default_from_json : std::false_type {};
3538
3539template<typename BasicJsonType, typename T>
3540struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3541{
3542 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3543
3544 static constexpr bool value =
3545 is_detected_exact<T, from_json_function, serializer,
3546 const BasicJsonType &>::value;
3547};
3548
3549// This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3550// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3551template<typename BasicJsonType, typename T, typename = void>
3552struct has_to_json : std::false_type {};
3553
3554template<typename BasicJsonType, typename T>
3555struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3556{
3557 using serializer = typename BasicJsonType::template json_serializer<T, void>;
3558
3559 static constexpr bool value =
3560 is_detected_exact<void, to_json_function, serializer, BasicJsonType &,
3561 T>::value;
3562};
3563
3564
3566// is_ functions //
3568
3569// https://en.cppreference.com/w/cpp/types/conjunction
3570template<class...> struct conjunction : std::true_type { };
3571template<class B1> struct conjunction<B1> : B1 { };
3572template<class B1, class... Bn>
3573struct conjunction<B1, Bn...>
3574: std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
3575
3576// https://en.cppreference.com/w/cpp/types/negation
3577template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3578
3579// Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3580// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3581// This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3582template <typename T>
3583struct is_default_constructible : std::is_default_constructible<T> {};
3584
3585template <typename T1, typename T2>
3586struct is_default_constructible<std::pair<T1, T2>>
3587 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3588
3589template <typename T1, typename T2>
3590struct is_default_constructible<const std::pair<T1, T2>>
3591 : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3592
3593template <typename... Ts>
3594struct is_default_constructible<std::tuple<Ts...>>
3595 : conjunction<is_default_constructible<Ts>...> {};
3596
3597template <typename... Ts>
3598struct is_default_constructible<const std::tuple<Ts...>>
3599 : conjunction<is_default_constructible<Ts>...> {};
3600
3601
3602template <typename T, typename... Args>
3603struct is_constructible : std::is_constructible<T, Args...> {};
3604
3605template <typename T1, typename T2>
3606struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3607
3608template <typename T1, typename T2>
3609struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3610
3611template <typename... Ts>
3612struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3613
3614template <typename... Ts>
3615struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3616
3617
3618template<typename T, typename = void>
3619struct is_iterator_traits : std::false_type {};
3620
3621template<typename T>
3623{
3624private:
3625 using traits = iterator_traits<T>;
3626
3627public:
3628 static constexpr auto value =
3629 is_detected<value_type_t, traits>::value &&
3630 is_detected<difference_type_t, traits>::value &&
3631 is_detected<pointer_t, traits>::value &&
3632 is_detected<iterator_category_t, traits>::value &&
3633 is_detected<reference_t, traits>::value;
3634};
3635
3636// The following implementation of is_complete_type is taken from
3637// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3638// and is written by Xiang Fan who agreed to using it in this library.
3639
3640template<typename T, typename = void>
3641struct is_complete_type : std::false_type {};
3642
3643template<typename T>
3644struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3645
3646template<typename BasicJsonType, typename CompatibleObjectType,
3647 typename = void>
3648struct is_compatible_object_type_impl : std::false_type {};
3649
3650template<typename BasicJsonType, typename CompatibleObjectType>
3652 BasicJsonType, CompatibleObjectType,
3653 enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value &&
3654 is_detected<key_type_t, CompatibleObjectType>::value >>
3655{
3656 using object_t = typename BasicJsonType::object_t;
3657
3658 // macOS's is_constructible does not play well with nonesuch...
3659 static constexpr bool value =
3660 is_constructible<typename object_t::key_type,
3661 typename CompatibleObjectType::key_type>::value &&
3662 is_constructible<typename object_t::mapped_type,
3663 typename CompatibleObjectType::mapped_type>::value;
3664};
3665
3666template<typename BasicJsonType, typename CompatibleObjectType>
3668 : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3669
3670template<typename BasicJsonType, typename ConstructibleObjectType,
3671 typename = void>
3672struct is_constructible_object_type_impl : std::false_type {};
3673
3674template<typename BasicJsonType, typename ConstructibleObjectType>
3676 BasicJsonType, ConstructibleObjectType,
3677 enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value &&
3678 is_detected<key_type_t, ConstructibleObjectType>::value >>
3679{
3680 using object_t = typename BasicJsonType::object_t;
3681
3682 static constexpr bool value =
3684 (std::is_move_assignable<ConstructibleObjectType>::value ||
3685 std::is_copy_assignable<ConstructibleObjectType>::value) &&
3686 (is_constructible<typename ConstructibleObjectType::key_type,
3687 typename object_t::key_type>::value &&
3688 std::is_same <
3689 typename object_t::mapped_type,
3690 typename ConstructibleObjectType::mapped_type >::value)) ||
3691 (has_from_json<BasicJsonType,
3692 typename ConstructibleObjectType::mapped_type>::value ||
3694 BasicJsonType,
3695 typename ConstructibleObjectType::mapped_type >::value);
3696};
3697
3698template<typename BasicJsonType, typename ConstructibleObjectType>
3700 : is_constructible_object_type_impl<BasicJsonType,
3701 ConstructibleObjectType> {};
3702
3703template<typename BasicJsonType, typename CompatibleStringType,
3704 typename = void>
3705struct is_compatible_string_type_impl : std::false_type {};
3706
3707template<typename BasicJsonType, typename CompatibleStringType>
3709 BasicJsonType, CompatibleStringType,
3710 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3711 value_type_t, CompatibleStringType>::value >>
3712{
3713 static constexpr auto value =
3715};
3716
3717template<typename BasicJsonType, typename ConstructibleStringType>
3719 : is_compatible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3720
3721template<typename BasicJsonType, typename ConstructibleStringType,
3722 typename = void>
3723struct is_constructible_string_type_impl : std::false_type {};
3724
3725template<typename BasicJsonType, typename ConstructibleStringType>
3727 BasicJsonType, ConstructibleStringType,
3728 enable_if_t<is_detected_exact<typename BasicJsonType::string_t::value_type,
3729 value_type_t, ConstructibleStringType>::value >>
3730{
3731 static constexpr auto value =
3732 is_constructible<ConstructibleStringType,
3733 typename BasicJsonType::string_t>::value;
3734};
3735
3736template<typename BasicJsonType, typename ConstructibleStringType>
3738 : is_constructible_string_type_impl<BasicJsonType, ConstructibleStringType> {};
3739
3740template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3741struct is_compatible_array_type_impl : std::false_type {};
3742
3743template<typename BasicJsonType, typename CompatibleArrayType>
3745 BasicJsonType, CompatibleArrayType,
3746 enable_if_t < is_detected<value_type_t, CompatibleArrayType>::value &&
3747 is_detected<iterator_t, CompatibleArrayType>::value &&
3748// This is needed because json_reverse_iterator has a ::iterator type...
3749// Therefore it is detected as a CompatibleArrayType.
3750// The real fix would be to have an Iterable concept.
3752 iterator_traits<CompatibleArrayType >>::value >>
3753{
3754 static constexpr bool value =
3755 is_constructible<BasicJsonType,
3756 typename CompatibleArrayType::value_type>::value;
3757};
3758
3759template<typename BasicJsonType, typename CompatibleArrayType>
3761 : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3762
3763template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3764struct is_constructible_array_type_impl : std::false_type {};
3765
3766template<typename BasicJsonType, typename ConstructibleArrayType>
3768 BasicJsonType, ConstructibleArrayType,
3769 enable_if_t<std::is_same<ConstructibleArrayType,
3770 typename BasicJsonType::value_type>::value >>
3771 : std::true_type {};
3772
3773template<typename BasicJsonType, typename ConstructibleArrayType>
3775 BasicJsonType, ConstructibleArrayType,
3776 enable_if_t < !std::is_same<ConstructibleArrayType,
3777 typename BasicJsonType::value_type>::value &&
3778 is_default_constructible<ConstructibleArrayType>::value &&
3779(std::is_move_assignable<ConstructibleArrayType>::value ||
3780 std::is_copy_assignable<ConstructibleArrayType>::value) &&
3781is_detected<value_type_t, ConstructibleArrayType>::value &&
3782is_detected<iterator_t, ConstructibleArrayType>::value &&
3784detected_t<value_type_t, ConstructibleArrayType >>::value >>
3785{
3786 static constexpr bool value =
3787 // This is needed because json_reverse_iterator has a ::iterator type,
3788 // furthermore, std::back_insert_iterator (and other iterators) have a
3789 // base class `iterator`... Therefore it is detected as a
3790 // ConstructibleArrayType. The real fix would be to have an Iterable
3791 // concept.
3793
3794 (std::is_same<typename ConstructibleArrayType::value_type,
3795 typename BasicJsonType::array_t::value_type>::value ||
3796 has_from_json<BasicJsonType,
3797 typename ConstructibleArrayType::value_type>::value ||
3799 BasicJsonType, typename ConstructibleArrayType::value_type >::value);
3800};
3801
3802template<typename BasicJsonType, typename ConstructibleArrayType>
3804 : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3805
3806template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3807 typename = void>
3808struct is_compatible_integer_type_impl : std::false_type {};
3809
3810template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3812 RealIntegerType, CompatibleNumberIntegerType,
3813 enable_if_t < std::is_integral<RealIntegerType>::value &&
3814 std::is_integral<CompatibleNumberIntegerType>::value &&
3815 !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3816{
3817 // is there an assert somewhere on overflows?
3818 using RealLimits = std::numeric_limits<RealIntegerType>;
3819 using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3820
3821 static constexpr auto value =
3822 is_constructible<RealIntegerType,
3823 CompatibleNumberIntegerType>::value &&
3824 CompatibleLimits::is_integer &&
3825 RealLimits::is_signed == CompatibleLimits::is_signed;
3826};
3827
3828template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3830 : is_compatible_integer_type_impl<RealIntegerType,
3831 CompatibleNumberIntegerType> {};
3832
3833template<typename BasicJsonType, typename CompatibleType, typename = void>
3834struct is_compatible_type_impl: std::false_type {};
3835
3836template<typename BasicJsonType, typename CompatibleType>
3838 BasicJsonType, CompatibleType,
3839 enable_if_t<is_complete_type<CompatibleType>::value >>
3840{
3841 static constexpr bool value =
3843};
3844
3845template<typename BasicJsonType, typename CompatibleType>
3847 : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3848
3849template<typename T1, typename T2>
3850struct is_constructible_tuple : std::false_type {};
3851
3852template<typename T1, typename... Args>
3853struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3854
3855// a naive helper to check if a type is an ordered_map (exploits the fact that
3856// ordered_map inherits capacity() from std::vector)
3857template <typename T>
3859{
3860 using one = char;
3861
3862 struct two
3863 {
3864 char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3865 };
3866
3867 template <typename C> static one test( decltype(&C::capacity) ) ;
3868 template <typename C> static two test(...);
3869
3870 enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3871};
3872
3873// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3874template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3875T conditional_static_cast(U value)
3876{
3877 return static_cast<T>(value);
3878}
3879
3880template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3881T conditional_static_cast(U value)
3882{
3883 return value;
3884}
3885
3886} // namespace detail
3887} // namespace nlohmann
3888
3889// #include <nlohmann/detail/value_t.hpp>
3890
3891
3892namespace nlohmann
3893{
3894namespace detail
3895{
3896template<typename BasicJsonType>
3897void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
3898{
3899 if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
3900 {
3901 JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()), j));
3902 }
3903
3904 n = nullptr;
3905}
3906
3907// overloads for basic_json template parameters
3908template < typename BasicJsonType, typename ArithmeticType,
3909 enable_if_t < std::is_arithmetic<ArithmeticType>::value &&
3910 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
3911 int > = 0 >
3912void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
3913{
3914 switch (static_cast<value_t>(j))
3915 {
3917 {
3918 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t *>());
3919 break;
3920 }
3921
3923 {
3924 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t *>());
3925 break;
3926 }
3927
3929 {
3930 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t *>());
3931 break;
3932 }
3933
3934 case value_t::null:
3935 case value_t::object:
3936 case value_t::array:
3937 case value_t::string:
3938 case value_t::boolean:
3939 case value_t::binary:
3940 case value_t::discarded:
3941 default:
3942 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
3943 }
3944}
3945
3946template<typename BasicJsonType>
3947void from_json(const BasicJsonType &j, typename BasicJsonType::boolean_t &b)
3948{
3949 if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
3950 {
3951 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(j.type_name()), j));
3952 }
3953
3954 b = *j.template get_ptr<const typename BasicJsonType::boolean_t *>();
3955}
3956
3957template<typename BasicJsonType>
3958void from_json(const BasicJsonType &j, typename BasicJsonType::string_t &s)
3959{
3960 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3961 {
3962 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3963 }
3964
3965 s = *j.template get_ptr<const typename BasicJsonType::string_t *>();
3966}
3967
3968template <
3969 typename BasicJsonType, typename ConstructibleStringType,
3970 enable_if_t <
3971 is_constructible_string_type<BasicJsonType, ConstructibleStringType>::value &&
3972 !std::is_same<typename BasicJsonType::string_t,
3973 ConstructibleStringType>::value,
3974 int > = 0 >
3975void from_json(const BasicJsonType &j, ConstructibleStringType &s)
3976{
3977 if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
3978 {
3979 JSON_THROW(type_error::create(302, "type must be string, but is " + std::string(j.type_name()), j));
3980 }
3981
3982 s = *j.template get_ptr<const typename BasicJsonType::string_t *>();
3983}
3984
3985template<typename BasicJsonType>
3986void from_json(const BasicJsonType &j, typename BasicJsonType::number_float_t &val)
3987{
3988 get_arithmetic_value(j, val);
3989}
3990
3991template<typename BasicJsonType>
3992void from_json(const BasicJsonType &j, typename BasicJsonType::number_unsigned_t &val)
3993{
3994 get_arithmetic_value(j, val);
3995}
3996
3997template<typename BasicJsonType>
3998void from_json(const BasicJsonType &j, typename BasicJsonType::number_integer_t &val)
3999{
4000 get_arithmetic_value(j, val);
4001}
4002
4003template<typename BasicJsonType, typename EnumType,
4004 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4005void from_json(const BasicJsonType &j, EnumType &e)
4006{
4007 typename std::underlying_type<EnumType>::type val;
4008 get_arithmetic_value(j, val);
4009 e = static_cast<EnumType>(val);
4010}
4011
4012// forward_list doesn't have an insert method
4013template<typename BasicJsonType, typename T, typename Allocator,
4014 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4015void from_json(const BasicJsonType &j, std::forward_list<T, Allocator> &l)
4016{
4017 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4018 {
4019 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4020 }
4021
4022 l.clear();
4023 std::transform(j.rbegin(), j.rend(),
4024 std::front_inserter(l), [](const BasicJsonType & i)
4025 {
4026 return i.template get<T>();
4027 });
4028}
4029
4030// valarray doesn't have an insert method
4031template<typename BasicJsonType, typename T,
4032 enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4033void from_json(const BasicJsonType &j, std::valarray<T> &l)
4034{
4035 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4036 {
4037 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4038 }
4039
4040 l.resize(j.size());
4041 std::transform(j.begin(), j.end(), std::begin(l),
4042 [](const BasicJsonType & elem)
4043 {
4044 return elem.template get<T>();
4045 });
4046}
4047
4048template<typename BasicJsonType, typename T, std::size_t N>
4049auto from_json(const BasicJsonType &j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4050-> decltype(j.template get<T>(), void())
4051{
4052 for (std::size_t i = 0; i < N; ++i)
4053 {
4054 arr[i] = j.at(i).template get<T>();
4055 }
4056}
4057
4058template<typename BasicJsonType>
4059void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag<3> /*unused*/)
4060{
4061 arr = *j.template get_ptr<const typename BasicJsonType::array_t *>();
4062}
4063
4064template<typename BasicJsonType, typename T, std::size_t N>
4065auto from_json_array_impl(const BasicJsonType &j, std::array<T, N> &arr,
4066 priority_tag<2> /*unused*/)
4067-> decltype(j.template get<T>(), void())
4068{
4069 for (std::size_t i = 0; i < N; ++i)
4070 {
4071 arr[i] = j.at(i).template get<T>();
4072 }
4073}
4074
4075template<typename BasicJsonType, typename ConstructibleArrayType,
4076 enable_if_t<
4077 std::is_assignable<ConstructibleArrayType &, ConstructibleArrayType>::value,
4078 int> = 0>
4079auto from_json_array_impl(const BasicJsonType &j, ConstructibleArrayType &arr, priority_tag<1> /*unused*/)
4080-> decltype(
4081 arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4082 j.template get<typename ConstructibleArrayType::value_type>(),
4083 void())
4084{
4085 using std::end;
4086 ConstructibleArrayType ret;
4087 ret.reserve(j.size());
4088 std::transform(j.begin(), j.end(),
4089 std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4090 {
4091 // get<BasicJsonType>() returns *this, this won't call a from_json
4092 // method when value_type is BasicJsonType
4093 return i.template get<typename ConstructibleArrayType::value_type>();
4094 });
4095 arr = std::move(ret);
4096}
4097
4098template<typename BasicJsonType, typename ConstructibleArrayType,
4099 enable_if_t<
4100 std::is_assignable<ConstructibleArrayType &, ConstructibleArrayType>::value,
4101 int> = 0>
4102void from_json_array_impl(const BasicJsonType &j, ConstructibleArrayType &arr,
4103 priority_tag<0> /*unused*/)
4104{
4105 using std::end;
4106 ConstructibleArrayType ret;
4107 std::transform(
4108 j.begin(), j.end(), std::inserter(ret, end(ret)),
4109 [](const BasicJsonType & i)
4110 {
4111 // get<BasicJsonType>() returns *this, this won't call a from_json
4112 // method when value_type is BasicJsonType
4113 return i.template get<typename ConstructibleArrayType::value_type>();
4114 });
4115 arr = std::move(ret);
4116}
4117
4118template < typename BasicJsonType, typename ConstructibleArrayType,
4119 enable_if_t <
4120 is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value &&
4121 !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value &&
4122 !is_constructible_string_type<BasicJsonType, ConstructibleArrayType>::value &&
4123 !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value &&
4124 !is_basic_json<ConstructibleArrayType>::value,
4125 int > = 0 >
4126auto from_json(const BasicJsonType &j, ConstructibleArrayType &arr)
4127-> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4128j.template get<typename ConstructibleArrayType::value_type>(),
4129void())
4130{
4131 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4132 {
4133 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4134 }
4135
4136 from_json_array_impl(j, arr, priority_tag<3> {});
4137}
4138
4139template < typename BasicJsonType, typename T, std::size_t... Idx >
4140std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType &&j,
4141 identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4142{
4143 return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4144}
4145
4146template < typename BasicJsonType, typename T, std::size_t N >
4147auto from_json(BasicJsonType &&j, identity_tag<std::array<T, N>> tag)
4148-> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4149{
4150 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4151 {
4152 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4153 }
4154
4155 return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4156}
4157
4158template<typename BasicJsonType>
4159void from_json(const BasicJsonType &j, typename BasicJsonType::binary_t &bin)
4160{
4161 if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4162 {
4163 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(j.type_name()), j));
4164 }
4165
4166 bin = *j.template get_ptr<const typename BasicJsonType::binary_t *>();
4167}
4168
4169template<typename BasicJsonType, typename ConstructibleObjectType,
4170 enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4171void from_json(const BasicJsonType &j, ConstructibleObjectType &obj)
4172{
4173 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4174 {
4175 JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name()), j));
4176 }
4177
4178 ConstructibleObjectType ret;
4179 const auto *inner_object = j.template get_ptr<const typename BasicJsonType::object_t *>();
4180 using value_type = typename ConstructibleObjectType::value_type;
4181 std::transform(
4182 inner_object->begin(), inner_object->end(),
4183 std::inserter(ret, ret.begin()),
4184 [](typename BasicJsonType::object_t::value_type const & p)
4185 {
4186 return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4187 });
4188 obj = std::move(ret);
4189}
4190
4191// overload for arithmetic types, not chosen for basic_json template arguments
4192// (BooleanType, etc..); note: Is it really necessary to provide explicit
4193// overloads for boolean_t etc. in case of a custom BooleanType which is not
4194// an arithmetic type?
4195template < typename BasicJsonType, typename ArithmeticType,
4196 enable_if_t <
4197 std::is_arithmetic<ArithmeticType>::value &&
4198 !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value &&
4199 !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value &&
4200 !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value &&
4201 !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4202 int > = 0 >
4203void from_json(const BasicJsonType &j, ArithmeticType &val)
4204{
4205 switch (static_cast<value_t>(j))
4206 {
4208 {
4209 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t *>());
4210 break;
4211 }
4212
4214 {
4215 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t *>());
4216 break;
4217 }
4218
4220 {
4221 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t *>());
4222 break;
4223 }
4224
4225 case value_t::boolean:
4226 {
4227 val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t *>());
4228 break;
4229 }
4230
4231 case value_t::null:
4232 case value_t::object:
4233 case value_t::array:
4234 case value_t::string:
4235 case value_t::binary:
4236 case value_t::discarded:
4237 default:
4238 JSON_THROW(type_error::create(302, "type must be number, but is " + std::string(j.type_name()), j));
4239 }
4240}
4241
4242template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4243std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType &&j, index_sequence<Idx...> /*unused*/)
4244{
4245 return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4246}
4247
4248template < typename BasicJsonType, class A1, class A2 >
4249std::pair<A1, A2> from_json_tuple_impl(BasicJsonType &&j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4250{
4251 return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4252 std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4253}
4254
4255template<typename BasicJsonType, typename A1, typename A2>
4256void from_json_tuple_impl(BasicJsonType &&j, std::pair<A1, A2> &p, priority_tag<1> /*unused*/)
4257{
4258 p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4259}
4260
4261template<typename BasicJsonType, typename... Args>
4262std::tuple<Args...> from_json_tuple_impl(BasicJsonType &&j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4263{
4264 return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4265}
4266
4267template<typename BasicJsonType, typename... Args>
4268void from_json_tuple_impl(BasicJsonType &&j, std::tuple<Args...> &t, priority_tag<3> /*unused*/)
4269{
4270 t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4271}
4272
4273template<typename BasicJsonType, typename TupleRelated>
4274auto from_json(BasicJsonType &&j, TupleRelated &&t)
4275-> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4276{
4277 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4278 {
4279 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4280 }
4281
4282 return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4283}
4284
4285template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4286 typename = enable_if_t < !std::is_constructible <
4287 typename BasicJsonType::string_t, Key >::value >>
4288void from_json(const BasicJsonType &j, std::map<Key, Value, Compare, Allocator> &m)
4289{
4290 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4291 {
4292 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4293 }
4294
4295 m.clear();
4296
4297 for (const auto &p : j)
4298 {
4299 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4300 {
4301 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4302 }
4303
4304 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4305 }
4306}
4307
4308template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4309 typename = enable_if_t < !std::is_constructible <
4310 typename BasicJsonType::string_t, Key >::value >>
4311void from_json(const BasicJsonType &j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator> &m)
4312{
4313 if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4314 {
4315 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()), j));
4316 }
4317
4318 m.clear();
4319
4320 for (const auto &p : j)
4321 {
4322 if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4323 {
4324 JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(p.type_name()), j));
4325 }
4326
4327 m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4328 }
4329}
4330
4332{
4333 template<typename BasicJsonType, typename T>
4334 auto operator()(const BasicJsonType &j, T &&val) const
4335 noexcept(noexcept(from_json(j, std::forward<T>(val))))
4336 -> decltype(from_json(j, std::forward<T>(val)))
4337 {
4338 return from_json(j, std::forward<T>(val));
4339 }
4340};
4341} // namespace detail
4342
4346namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4347{
4348constexpr const auto &from_json = detail::static_const<detail::from_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4349} // namespace
4350} // namespace nlohmann
4351
4352// #include <nlohmann/detail/conversions/to_json.hpp>
4353
4354
4355#include <algorithm> // copy
4356#include <iterator> // begin, end
4357#include <string> // string
4358#include <tuple> // tuple, get
4359#include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4360#include <utility> // move, forward, declval, pair
4361#include <valarray> // valarray
4362#include <vector> // vector
4363
4364// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4365
4366
4367#include <cstddef> // size_t
4368#include <iterator> // input_iterator_tag
4369#include <string> // string, to_string
4370#include <tuple> // tuple_size, get, tuple_element
4371#include <utility> // move
4372
4373// #include <nlohmann/detail/meta/type_traits.hpp>
4374
4375// #include <nlohmann/detail/value_t.hpp>
4376
4377
4378namespace nlohmann
4379{
4380namespace detail
4381{
4382template<typename string_type>
4383void int_to_string( string_type &target, std::size_t value )
4384{
4385 // For ADL
4386 using std::to_string;
4387 target = to_string(value);
4388}
4389template<typename IteratorType> class iteration_proxy_value
4390{
4391public:
4392 using difference_type = std::ptrdiff_t;
4394 using pointer = value_type * ;
4395 using reference = value_type & ;
4396 using iterator_category = std::input_iterator_tag;
4397 using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4398
4399private:
4401 IteratorType anchor;
4403 std::size_t array_index = 0;
4405 mutable std::size_t array_index_last = 0;
4407 mutable string_type array_index_str = "0";
4409 const string_type empty_str{};
4410
4411public:
4412 explicit iteration_proxy_value(IteratorType it) noexcept
4413 : anchor(std::move(it))
4414 {}
4415
4418 {
4419 return *this;
4420 }
4421
4424 {
4425 ++anchor;
4426 ++array_index;
4427 return *this;
4428 }
4429
4432 {
4433 return anchor == o.anchor;
4434 }
4435
4438 {
4439 return anchor != o.anchor;
4440 }
4441
4443 const string_type &key() const
4444 {
4445 JSON_ASSERT(anchor.m_object != nullptr);
4446
4447 switch (anchor.m_object->type())
4448 {
4449 // use integer array index as key
4450 case value_t::array:
4451 {
4453 {
4454 int_to_string( array_index_str, array_index );
4456 }
4457
4458 return array_index_str;
4459 }
4460
4461 // use key from the object
4462 case value_t::object:
4463 return anchor.key();
4464
4465 // use an empty key for all primitive types
4466 case value_t::null:
4467 case value_t::string:
4468 case value_t::boolean:
4472 case value_t::binary:
4473 case value_t::discarded:
4474 default:
4475 return empty_str;
4476 }
4477 }
4478
4480 typename IteratorType::reference value() const
4481 {
4482 return anchor.value();
4483 }
4484};
4485
4487template<typename IteratorType> class iteration_proxy
4488{
4489private:
4491 typename IteratorType::reference container;
4492
4493public:
4495 explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4496 : container(cont) {}
4497
4500 {
4502 }
4503
4506 {
4508 }
4509};
4510// Structured Bindings Support
4511// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4512// And see https://github.com/nlohmann/json/pull/1391
4513template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4514auto get(const nlohmann::detail::iteration_proxy_value<IteratorType> &i) -> decltype(i.key())
4515{
4516 return i.key();
4517}
4518// Structured Bindings Support
4519// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4520// And see https://github.com/nlohmann/json/pull/1391
4521template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4522auto get(const nlohmann::detail::iteration_proxy_value<IteratorType> &i) -> decltype(i.value())
4523{
4524 return i.value();
4525}
4526} // namespace detail
4527} // namespace nlohmann
4528
4529// The Addition to the STD Namespace is required to add
4530// Structured Bindings Support to the iteration_proxy_value class
4531// For further reference see https://blog.tartanllama.xyz/structured-bindings/
4532// And see https://github.com/nlohmann/json/pull/1391
4533namespace std
4534{
4535#if defined(__clang__)
4536// Fix: https://github.com/nlohmann/json/issues/1401
4537#pragma clang diagnostic push
4538#pragma clang diagnostic ignored "-Wmismatched-tags"
4539#endif
4540template<typename IteratorType>
4541class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4542 : public std::integral_constant<std::size_t, 2> {};
4543
4544template<std::size_t N, typename IteratorType>
4545class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4546{
4547public:
4548 using type = decltype(
4549 get<N>(std::declval <
4551};
4552#if defined(__clang__)
4553#pragma clang diagnostic pop
4554#endif
4555} // namespace std
4556
4557// #include <nlohmann/detail/meta/cpp_future.hpp>
4558
4559// #include <nlohmann/detail/meta/type_traits.hpp>
4560
4561// #include <nlohmann/detail/value_t.hpp>
4562
4563
4564namespace nlohmann
4565{
4566namespace detail
4567{
4569// constructors //
4571
4572/*
4573 * Note all external_constructor<>::construct functions need to call
4574 * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
4575 * allocated value (e.g., a string). See bug issue
4576 * https://github.com/nlohmann/json/issues/2865 for more information.
4577 */
4578
4579template<value_t> struct external_constructor;
4580
4581template<>
4583{
4584 template<typename BasicJsonType>
4585 static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
4586 {
4587 j.m_value.destroy(j.m_type);
4588 j.m_type = value_t::boolean;
4589 j.m_value = b;
4590 j.assert_invariant();
4591 }
4592};
4593
4594template<>
4596{
4597 template<typename BasicJsonType>
4598 static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
4599 {
4600 j.m_value.destroy(j.m_type);
4601 j.m_type = value_t::string;
4602 j.m_value = s;
4603 j.assert_invariant();
4604 }
4605
4606 template<typename BasicJsonType>
4607 static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
4608 {
4609 j.m_value.destroy(j.m_type);
4610 j.m_type = value_t::string;
4611 j.m_value = std::move(s);
4612 j.assert_invariant();
4613 }
4614
4615 template < typename BasicJsonType, typename CompatibleStringType,
4616 enable_if_t < !std::is_same<CompatibleStringType, typename BasicJsonType::string_t>::value,
4617 int > = 0 >
4618 static void construct(BasicJsonType &j, const CompatibleStringType &str)
4619 {
4620 j.m_value.destroy(j.m_type);
4621 j.m_type = value_t::string;
4622 j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
4623 j.assert_invariant();
4624 }
4625};
4626
4627template<>
4629{
4630 template<typename BasicJsonType>
4631 static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
4632 {
4633 j.m_value.destroy(j.m_type);
4634 j.m_type = value_t::binary;
4635 j.m_value = typename BasicJsonType::binary_t(b);
4636 j.assert_invariant();
4637 }
4638
4639 template<typename BasicJsonType>
4640 static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
4641 {
4642 j.m_value.destroy(j.m_type);
4643 j.m_type = value_t::binary;
4644 j.m_value = typename BasicJsonType::binary_t(std::move(b));
4645 j.assert_invariant();
4646 }
4647};
4648
4649template<>
4651{
4652 template<typename BasicJsonType>
4653 static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
4654 {
4655 j.m_value.destroy(j.m_type);
4656 j.m_type = value_t::number_float;
4657 j.m_value = val;
4658 j.assert_invariant();
4659 }
4660};
4661
4662template<>
4664{
4665 template<typename BasicJsonType>
4666 static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
4667 {
4668 j.m_value.destroy(j.m_type);
4669 j.m_type = value_t::number_unsigned;
4670 j.m_value = val;
4671 j.assert_invariant();
4672 }
4673};
4674
4675template<>
4677{
4678 template<typename BasicJsonType>
4679 static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
4680 {
4681 j.m_value.destroy(j.m_type);
4682 j.m_type = value_t::number_integer;
4683 j.m_value = val;
4684 j.assert_invariant();
4685 }
4686};
4687
4688template<>
4690{
4691 template<typename BasicJsonType>
4692 static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
4693 {
4694 j.m_value.destroy(j.m_type);
4695 j.m_type = value_t::array;
4696 j.m_value = arr;
4697 j.set_parents();
4698 j.assert_invariant();
4699 }
4700
4701 template<typename BasicJsonType>
4702 static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
4703 {
4704 j.m_value.destroy(j.m_type);
4705 j.m_type = value_t::array;
4706 j.m_value = std::move(arr);
4707 j.set_parents();
4708 j.assert_invariant();
4709 }
4710
4711 template < typename BasicJsonType, typename CompatibleArrayType,
4712 enable_if_t < !std::is_same<CompatibleArrayType, typename BasicJsonType::array_t>::value,
4713 int > = 0 >
4714 static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
4715 {
4716 using std::begin;
4717 using std::end;
4718 j.m_value.destroy(j.m_type);
4719 j.m_type = value_t::array;
4720 j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
4721 j.set_parents();
4722 j.assert_invariant();
4723 }
4724
4725 template<typename BasicJsonType>
4726 static void construct(BasicJsonType &j, const std::vector<bool> &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->reserve(arr.size());
4732
4733 for (const bool x : arr)
4734 {
4735 j.m_value.array->push_back(x);
4736 j.set_parent(j.m_value.array->back());
4737 }
4738
4739 j.assert_invariant();
4740 }
4741
4742 template<typename BasicJsonType, typename T,
4743 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4744 static void construct(BasicJsonType &j, const std::valarray<T> &arr)
4745 {
4746 j.m_value.destroy(j.m_type);
4747 j.m_type = value_t::array;
4748 j.m_value = value_t::array;
4749 j.m_value.array->resize(arr.size());
4750
4751 if (arr.size() > 0)
4752 {
4753 std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
4754 }
4755
4756 j.set_parents();
4757 j.assert_invariant();
4758 }
4759};
4760
4761template<>
4763{
4764 template<typename BasicJsonType>
4765 static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
4766 {
4767 j.m_value.destroy(j.m_type);
4768 j.m_type = value_t::object;
4769 j.m_value = obj;
4770 j.set_parents();
4771 j.assert_invariant();
4772 }
4773
4774 template<typename BasicJsonType>
4775 static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
4776 {
4777 j.m_value.destroy(j.m_type);
4778 j.m_type = value_t::object;
4779 j.m_value = std::move(obj);
4780 j.set_parents();
4781 j.assert_invariant();
4782 }
4783
4784 template < typename BasicJsonType, typename CompatibleObjectType,
4785 enable_if_t < !std::is_same<CompatibleObjectType, typename BasicJsonType::object_t>::value, int > = 0 >
4786 static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
4787 {
4788 using std::begin;
4789 using std::end;
4790 j.m_value.destroy(j.m_type);
4791 j.m_type = value_t::object;
4792 j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
4793 j.set_parents();
4794 j.assert_invariant();
4795 }
4796};
4797
4799// to_json //
4801
4802template<typename BasicJsonType, typename T,
4803 enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
4804void to_json(BasicJsonType &j, T b) noexcept
4805{
4807}
4808
4809template<typename BasicJsonType, typename CompatibleString,
4810 enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
4811void to_json(BasicJsonType &j, const CompatibleString &s)
4812{
4813 external_constructor<value_t::string>::construct(j, s);
4814}
4815
4816template<typename BasicJsonType>
4817void to_json(BasicJsonType &j, typename BasicJsonType::string_t &&s)
4818{
4819 external_constructor<value_t::string>::construct(j, std::move(s));
4820}
4821
4822template<typename BasicJsonType, typename FloatType,
4823 enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
4824void to_json(BasicJsonType &j, FloatType val) noexcept
4825{
4826 external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
4827}
4828
4829template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
4830 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
4831void to_json(BasicJsonType &j, CompatibleNumberUnsignedType val) noexcept
4832{
4833 external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
4834}
4835
4836template<typename BasicJsonType, typename CompatibleNumberIntegerType,
4837 enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
4838void to_json(BasicJsonType &j, CompatibleNumberIntegerType val) noexcept
4839{
4840 external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
4841}
4842
4843template<typename BasicJsonType, typename EnumType,
4844 enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4845void to_json(BasicJsonType &j, EnumType e) noexcept
4846{
4847 using underlying_type = typename std::underlying_type<EnumType>::type;
4848 external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
4849}
4850
4851template<typename BasicJsonType>
4852void to_json(BasicJsonType &j, const std::vector<bool> &e)
4853{
4854 external_constructor<value_t::array>::construct(j, e);
4855}
4856
4857template < typename BasicJsonType, typename CompatibleArrayType,
4858 enable_if_t < is_compatible_array_type<BasicJsonType,
4859 CompatibleArrayType>::value &&
4860 !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value &&
4861 !is_compatible_string_type<BasicJsonType, CompatibleArrayType>::value &&
4862 !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value &&
4863 !is_basic_json<CompatibleArrayType>::value,
4864 int > = 0 >
4865void to_json(BasicJsonType &j, const CompatibleArrayType &arr)
4866{
4867 external_constructor<value_t::array>::construct(j, arr);
4868}
4869
4870template<typename BasicJsonType>
4871void to_json(BasicJsonType &j, const typename BasicJsonType::binary_t &bin)
4872{
4873 external_constructor<value_t::binary>::construct(j, bin);
4874}
4875
4876template<typename BasicJsonType, typename T,
4877 enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
4878void to_json(BasicJsonType &j, const std::valarray<T> &arr)
4879{
4880 external_constructor<value_t::array>::construct(j, std::move(arr));
4881}
4882
4883template<typename BasicJsonType>
4884void to_json(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
4885{
4886 external_constructor<value_t::array>::construct(j, std::move(arr));
4887}
4888
4889template < typename BasicJsonType, typename CompatibleObjectType,
4890 enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
4891void to_json(BasicJsonType &j, const CompatibleObjectType &obj)
4892{
4893 external_constructor<value_t::object>::construct(j, obj);
4894}
4895
4896template<typename BasicJsonType>
4897void to_json(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
4898{
4899 external_constructor<value_t::object>::construct(j, std::move(obj));
4900}
4901
4902template <
4903 typename BasicJsonType, typename T, std::size_t N,
4904 enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
4905 const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4906 int > = 0 >
4907void to_json(BasicJsonType &j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4908{
4909 external_constructor<value_t::array>::construct(j, arr);
4910}
4911
4912template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value &&std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
4913void to_json(BasicJsonType &j, const std::pair<T1, T2> &p)
4914{
4915 j = { p.first, p.second };
4916}
4917
4918// for https://github.com/nlohmann/json/pull/1134
4919template<typename BasicJsonType, typename T,
4920 enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
4921void to_json(BasicJsonType &j, const T &b)
4922{
4923 j = { {b.key(), b.value()} };
4924}
4925
4926template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
4927void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence<Idx...> /*unused*/)
4928{
4929 j = { std::get<Idx>(t)... };
4930}
4931
4932template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
4933void to_json(BasicJsonType &j, const T &t)
4934{
4935 to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
4936}
4937
4939{
4940 template<typename BasicJsonType, typename T>
4941 auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
4942 -> decltype(to_json(j, std::forward<T>(val)), void())
4943 {
4944 return to_json(j, std::forward<T>(val));
4945 }
4946};
4947} // namespace detail
4948
4952namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4953{
4954constexpr const auto &to_json = detail::static_const<detail::to_json_fn>::value; // NOLINT(misc-definitions-in-headers)
4955} // namespace
4956} // namespace nlohmann
4957
4958// #include <nlohmann/detail/meta/identity_tag.hpp>
4959
4960// #include <nlohmann/detail/meta/type_traits.hpp>
4961
4962
4963namespace nlohmann
4964{
4965
4966template<typename ValueType, typename>
4968{
4980 template<typename BasicJsonType, typename TargetType = ValueType>
4981 static auto from_json(BasicJsonType && j, TargetType &val) noexcept(
4982 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
4983 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
4984 {
4985 ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
4986 }
4987
5000 template<typename BasicJsonType, typename TargetType = ValueType>
5001 static auto from_json(BasicJsonType && j) noexcept(
5002 noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5003 -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5004 {
5005 return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5006 }
5007
5017 template<typename BasicJsonType, typename TargetType = ValueType>
5018 static auto to_json(BasicJsonType &j, TargetType && val) noexcept(
5019 noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5020 -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5021 {
5022 ::nlohmann::to_json(j, std::forward<TargetType>(val));
5023 }
5024};
5025} // namespace nlohmann
5026
5027// #include <nlohmann/byte_container_with_subtype.hpp>
5028
5029
5030#include <cstdint> // uint8_t, uint64_t
5031#include <tuple> // tie
5032#include <utility> // move
5033
5034namespace nlohmann
5035{
5036
5050template<typename BinaryType>
5051class byte_container_with_subtype : public BinaryType
5052{
5053public:
5055 using container_type = BinaryType;
5057 using subtype_type = std::uint64_t;
5058
5059 byte_container_with_subtype() noexcept(noexcept(container_type()))
5060 : container_type()
5061 {}
5062
5063 byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
5064 : container_type(b)
5065 {}
5066
5067 byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
5068 : container_type(std::move(b))
5069 {}
5070
5071 byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
5072 : container_type(b)
5073 , m_subtype(subtype_)
5074 , m_has_subtype(true)
5075 {}
5076
5077 byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5078 : container_type(std::move(b))
5079 , m_subtype(subtype_)
5080 , m_has_subtype(true)
5081 {}
5082
5083 bool operator==(const byte_container_with_subtype &rhs) const
5084 {
5085 return std::tie(static_cast<const BinaryType &>(*this), m_subtype, m_has_subtype) ==
5086 std::tie(static_cast<const BinaryType &>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5087 }
5088
5089 bool operator!=(const byte_container_with_subtype &rhs) const
5090 {
5091 return !(rhs == *this);
5092 }
5093
5112 void set_subtype(subtype_type subtype_) noexcept
5113 {
5114 m_subtype = subtype_;
5115 m_has_subtype = true;
5116 }
5117
5140 constexpr subtype_type subtype() const noexcept
5141 {
5142 return m_has_subtype ? m_subtype : subtype_type(-1);
5143 }
5144
5161 constexpr bool has_subtype() const noexcept
5162 {
5163 return m_has_subtype;
5164 }
5165
5185 void clear_subtype() noexcept
5186 {
5187 m_subtype = 0;
5188 m_has_subtype = false;
5189 }
5190
5191private:
5192 subtype_type m_subtype = 0;
5193 bool m_has_subtype = false;
5194};
5195
5196} // namespace nlohmann
5197
5198// #include <nlohmann/detail/conversions/from_json.hpp>
5199
5200// #include <nlohmann/detail/conversions/to_json.hpp>
5201
5202// #include <nlohmann/detail/exceptions.hpp>
5203
5204// #include <nlohmann/detail/hash.hpp>
5205
5206
5207#include <cstdint> // uint8_t
5208#include <cstddef> // size_t
5209#include <functional> // hash
5210
5211// #include <nlohmann/detail/macro_scope.hpp>
5212
5213// #include <nlohmann/detail/value_t.hpp>
5214
5215
5216namespace nlohmann
5217{
5218namespace detail
5219{
5220
5221// boost::hash_combine
5222inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5223{
5224 seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5225 return seed;
5226}
5227
5239template<typename BasicJsonType>
5240std::size_t hash(const BasicJsonType &j)
5241{
5242 using string_t = typename BasicJsonType::string_t;
5243 using number_integer_t = typename BasicJsonType::number_integer_t;
5244 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5245 using number_float_t = typename BasicJsonType::number_float_t;
5246 const auto type = static_cast<std::size_t>(j.type());
5247
5248 switch (j.type())
5249 {
5250 case BasicJsonType::value_t::null:
5251 case BasicJsonType::value_t::discarded:
5252 {
5253 return combine(type, 0);
5254 }
5255
5256 case BasicJsonType::value_t::object:
5257 {
5258 auto seed = combine(type, j.size());
5259
5260 for (const auto &element : j.items())
5261 {
5262 const auto h = std::hash<string_t> {}(element.key());
5263 seed = combine(seed, h);
5264 seed = combine(seed, hash(element.value()));
5265 }
5266
5267 return seed;
5268 }
5269
5270 case BasicJsonType::value_t::array:
5271 {
5272 auto seed = combine(type, j.size());
5273
5274 for (const auto &element : j)
5275 {
5276 seed = combine(seed, hash(element));
5277 }
5278
5279 return seed;
5280 }
5281
5282 case BasicJsonType::value_t::string:
5283 {
5284 const auto h = std::hash<string_t> {}(j.template get_ref<const string_t &>());
5285 return combine(type, h);
5286 }
5287
5288 case BasicJsonType::value_t::boolean:
5289 {
5290 const auto h = std::hash<bool> {}(j.template get<bool>());
5291 return combine(type, h);
5292 }
5293
5294 case BasicJsonType::value_t::number_integer:
5295 {
5296 const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5297 return combine(type, h);
5298 }
5299
5300 case BasicJsonType::value_t::number_unsigned:
5301 {
5302 const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5303 return combine(type, h);
5304 }
5305
5306 case BasicJsonType::value_t::number_float:
5307 {
5308 const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5309 return combine(type, h);
5310 }
5311
5312 case BasicJsonType::value_t::binary:
5313 {
5314 auto seed = combine(type, j.get_binary().size());
5315 const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5316 seed = combine(seed, h);
5317 seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5318
5319 for (const auto byte : j.get_binary())
5320 {
5321 seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5322 }
5323
5324 return seed;
5325 }
5326
5327 default: // LCOV_EXCL_LINE
5328 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5329 return 0; // LCOV_EXCL_LINE
5330 }
5331}
5332
5333} // namespace detail
5334} // namespace nlohmann
5335
5336// #include <nlohmann/detail/input/binary_reader.hpp>
5337
5338
5339#include <algorithm> // generate_n
5340#include <array> // array
5341#include <cmath> // ldexp
5342#include <cstddef> // size_t
5343#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5344#include <cstdio> // snprintf
5345#include <cstring> // memcpy
5346#include <iterator> // back_inserter
5347#include <limits> // numeric_limits
5348#include <string> // char_traits, string
5349#include <utility> // make_pair, move
5350#include <vector> // vector
5351
5352// #include <nlohmann/detail/exceptions.hpp>
5353
5354// #include <nlohmann/detail/input/input_adapters.hpp>
5355
5356
5357#include <array> // array
5358#include <cstddef> // size_t
5359#include <cstring> // strlen
5360#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5361#include <memory> // shared_ptr, make_shared, addressof
5362#include <numeric> // accumulate
5363#include <string> // string, char_traits
5364#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5365#include <utility> // pair, declval
5366
5367#ifndef JSON_NO_IO
5368#include <cstdio> // FILE *
5369#include <istream> // istream
5370#endif // JSON_NO_IO
5371
5372// #include <nlohmann/detail/iterators/iterator_traits.hpp>
5373
5374// #include <nlohmann/detail/macro_scope.hpp>
5375
5376
5377namespace nlohmann
5378{
5379namespace detail
5380{
5382enum class input_format_t { json, cbor, msgpack, ubjson, bson };
5383
5385// input adapters //
5387
5388#ifndef JSON_NO_IO
5394{
5395public:
5396 using char_type = char;
5397
5398 JSON_HEDLEY_NON_NULL(2)
5399 explicit file_input_adapter(std::FILE *f) noexcept
5400 : m_file(f)
5401 {}
5402
5403 // make class move-only
5404 file_input_adapter(const file_input_adapter &) = delete;
5405 file_input_adapter(file_input_adapter &&) noexcept = default;
5406 file_input_adapter &operator=(const file_input_adapter &) = delete;
5407 file_input_adapter &operator=(file_input_adapter &&) = delete;
5408 ~file_input_adapter() = default;
5409
5410 std::char_traits<char>::int_type get_character() noexcept
5411 {
5412 return std::fgetc(m_file);
5413 }
5414
5415private:
5417 std::FILE *m_file;
5418};
5419
5420
5431{
5432public:
5433 using char_type = char;
5434
5436 {
5437 // clear stream flags; we use underlying streambuf I/O, do not
5438 // maintain ifstream flags, except eof
5439 if (is != nullptr)
5440 {
5441 is->clear(is->rdstate() & std::ios::eofbit);
5442 }
5443 }
5444
5445 explicit input_stream_adapter(std::istream &i)
5446 : is(&i), sb(i.rdbuf())
5447 {}
5448
5449 // delete because of pointer members
5451 input_stream_adapter &operator=(input_stream_adapter &) = delete;
5452 input_stream_adapter &operator=(input_stream_adapter &&) = delete;
5453
5455 : is(rhs.is), sb(rhs.sb)
5456 {
5457 rhs.is = nullptr;
5458 rhs.sb = nullptr;
5459 }
5460
5461 // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5462 // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5463 // end up as the same value, eg. 0xFFFFFFFF.
5464 std::char_traits<char>::int_type get_character()
5465 {
5466 auto res = sb->sbumpc();
5467
5468 // set eof manually, as we don't use the istream interface.
5469 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5470 {
5471 is->clear(is->rdstate() | std::ios::eofbit);
5472 }
5473
5474 return res;
5475 }
5476
5477private:
5479 std::istream *is = nullptr;
5480 std::streambuf *sb = nullptr;
5481};
5482#endif // JSON_NO_IO
5483
5484// General-purpose iterator-based adapter. It might not be as fast as
5485// theoretically possible for some containers, but it is extremely versatile.
5486template<typename IteratorType>
5488{
5489public:
5490 using char_type = typename std::iterator_traits<IteratorType>::value_type;
5491
5492 iterator_input_adapter(IteratorType first, IteratorType last)
5493 : current(std::move(first)), end(std::move(last))
5494 {}
5495
5496 typename std::char_traits<char_type>::int_type get_character()
5497 {
5498 if (JSON_HEDLEY_LIKELY(current != end))
5499 {
5500 auto result = std::char_traits<char_type>::to_int_type(*current);
5501 std::advance(current, 1);
5502 return result;
5503 }
5504
5505 return std::char_traits<char_type>::eof();
5506 }
5507
5508private:
5509 IteratorType current;
5510 IteratorType end;
5511
5512 template<typename BaseInputAdapter, size_t T>
5513 friend struct wide_string_input_helper;
5514
5515 bool empty() const
5516 {
5517 return current == end;
5518 }
5519};
5520
5521
5522template<typename BaseInputAdapter, size_t T>
5524
5525template<typename BaseInputAdapter>
5526struct wide_string_input_helper<BaseInputAdapter, 4>
5527{
5528 // UTF-32
5529 static void fill_buffer(BaseInputAdapter &input,
5530 std::array<std::char_traits<char>::int_type, 4> &utf8_bytes,
5531 size_t &utf8_bytes_index,
5532 size_t &utf8_bytes_filled)
5533 {
5534 utf8_bytes_index = 0;
5535
5536 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5537 {
5538 utf8_bytes[0] = std::char_traits<char>::eof();
5539 utf8_bytes_filled = 1;
5540 }
5541
5542 else
5543 {
5544 // get the current character
5545 const auto wc = input.get_character();
5546
5547 // UTF-32 to UTF-8 encoding
5548 if (wc < 0x80)
5549 {
5550 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5551 utf8_bytes_filled = 1;
5552 }
5553
5554 else if (wc <= 0x7FF)
5555 {
5556 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5557 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5558 utf8_bytes_filled = 2;
5559 }
5560
5561 else if (wc <= 0xFFFF)
5562 {
5563 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5564 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5565 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5566 utf8_bytes_filled = 3;
5567 }
5568
5569 else if (wc <= 0x10FFFF)
5570 {
5571 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5572 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5573 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5574 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5575 utf8_bytes_filled = 4;
5576 }
5577
5578 else
5579 {
5580 // unknown character
5581 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5582 utf8_bytes_filled = 1;
5583 }
5584 }
5585 }
5586};
5587
5588template<typename BaseInputAdapter>
5589struct wide_string_input_helper<BaseInputAdapter, 2>
5590{
5591 // UTF-16
5592 static void fill_buffer(BaseInputAdapter &input,
5593 std::array<std::char_traits<char>::int_type, 4> &utf8_bytes,
5594 size_t &utf8_bytes_index,
5595 size_t &utf8_bytes_filled)
5596 {
5597 utf8_bytes_index = 0;
5598
5599 if (JSON_HEDLEY_UNLIKELY(input.empty()))
5600 {
5601 utf8_bytes[0] = std::char_traits<char>::eof();
5602 utf8_bytes_filled = 1;
5603 }
5604
5605 else
5606 {
5607 // get the current character
5608 const auto wc = input.get_character();
5609
5610 // UTF-16 to UTF-8 encoding
5611 if (wc < 0x80)
5612 {
5613 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5614 utf8_bytes_filled = 1;
5615 }
5616
5617 else if (wc <= 0x7FF)
5618 {
5619 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5620 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5621 utf8_bytes_filled = 2;
5622 }
5623
5624 else if (0xD800 > wc || wc >= 0xE000)
5625 {
5626 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5627 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5628 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5629 utf8_bytes_filled = 3;
5630 }
5631
5632 else
5633 {
5634 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5635 {
5636 const auto wc2 = static_cast<unsigned int>(input.get_character());
5637 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
5638 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
5639 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
5640 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
5641 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
5642 utf8_bytes_filled = 4;
5643 }
5644
5645 else
5646 {
5647 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5648 utf8_bytes_filled = 1;
5649 }
5650 }
5651 }
5652 }
5653};
5654
5655// Wraps another input apdater to convert wide character types into individual bytes.
5656template<typename BaseInputAdapter, typename WideCharType>
5658{
5659public:
5660 using char_type = char;
5661
5662 wide_string_input_adapter(BaseInputAdapter base)
5663 : base_adapter(base) {}
5664
5665 typename std::char_traits<char>::int_type get_character() noexcept
5666 {
5667 // check if buffer needs to be filled
5669 {
5670 fill_buffer<sizeof(WideCharType)>();
5671 JSON_ASSERT(utf8_bytes_filled > 0);
5672 JSON_ASSERT(utf8_bytes_index == 0);
5673 }
5674
5675 // use buffer
5676 JSON_ASSERT(utf8_bytes_filled > 0);
5677 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
5678 return utf8_bytes[utf8_bytes_index++];
5679 }
5680
5681private:
5682 BaseInputAdapter base_adapter;
5683
5684 template<size_t T>
5685 void fill_buffer()
5686 {
5688 }
5689
5691 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
5692
5694 std::size_t utf8_bytes_index = 0;
5696 std::size_t utf8_bytes_filled = 0;
5697};
5698
5699
5700template<typename IteratorType, typename Enable = void>
5702{
5703 using iterator_type = IteratorType;
5704 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5706
5707 static adapter_type create(IteratorType first, IteratorType last)
5708 {
5709 return adapter_type(std::move(first), std::move(last));
5710 }
5711};
5712
5713template<typename T>
5715{
5716 using value_type = typename std::iterator_traits<T>::value_type;
5717 enum
5718 {
5719 value = sizeof(value_type) > 1
5720 };
5721};
5722
5723template<typename IteratorType>
5724struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
5725{
5726 using iterator_type = IteratorType;
5727 using char_type = typename std::iterator_traits<iterator_type>::value_type;
5730
5731 static adapter_type create(IteratorType first, IteratorType last)
5732 {
5733 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
5734 }
5735};
5736
5737// General purpose iterator-based input
5738template<typename IteratorType>
5739typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
5740{
5742 return factory_type::create(first, last);
5743}
5744
5745// Convenience shorthand from container to iterator
5746// Enables ADL on begin(container) and end(container)
5747// Encloses the using declarations in namespace for not to leak them to outside scope
5748
5749namespace container_input_adapter_factory_impl
5750{
5751
5752using std::begin;
5753using std::end;
5754
5755template<typename ContainerType, typename Enable = void>
5757
5758template<typename ContainerType>
5760 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
5761 {
5762 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
5763
5764 static adapter_type create(const ContainerType &container)
5765{
5766 return input_adapter(begin(container), end(container));
5767}
5768 };
5769
5770} // namespace container_input_adapter_factory_impl
5771
5772template<typename ContainerType>
5774{
5776}
5777
5778#ifndef JSON_NO_IO
5779// Special cases with fast paths
5780inline file_input_adapter input_adapter(std::FILE *file)
5781{
5782 return file_input_adapter(file);
5783}
5784
5785inline input_stream_adapter input_adapter(std::istream &stream)
5786{
5787 return input_stream_adapter(stream);
5788}
5789
5790inline input_stream_adapter input_adapter(std::istream &&stream)
5791{
5792 return input_stream_adapter(stream);
5793}
5794#endif // JSON_NO_IO
5795
5796using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char *>(), std::declval<const char *>()));
5797
5798// Null-delimited strings, and the like.
5799template < typename CharT,
5800 typename std::enable_if <
5801 std::is_pointer<CharT>::value &&
5802 !std::is_array<CharT>::value &&
5803 std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
5804 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5805 int >::type = 0 >
5806contiguous_bytes_input_adapter input_adapter(CharT b)
5807{
5808 auto length = std::strlen(reinterpret_cast<const char *>(b));
5809 const auto *ptr = reinterpret_cast<const char *>(b);
5810 return input_adapter(ptr, ptr + length);
5811}
5812
5813template<typename T, std::size_t N>
5814auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5815{
5816 return input_adapter(array, array + N);
5817}
5818
5819// This class only handles inputs of input_buffer_adapter type.
5820// It's required so that expressions like {ptr, len} can be implicitely casted
5821// to the correct adapter.
5823{
5824public:
5825 template < typename CharT,
5826 typename std::enable_if <
5827 std::is_pointer<CharT>::value &&
5828 std::is_integral<typename std::remove_pointer<CharT>::type>::value &&
5829 sizeof(typename std::remove_pointer<CharT>::type) == 1,
5830 int >::type = 0 >
5831 span_input_adapter(CharT b, std::size_t l)
5832 : ia(reinterpret_cast<const char *>(b), reinterpret_cast<const char *>(b) + l) {}
5833
5834 template<class IteratorType,
5835 typename std::enable_if<
5836 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
5837 int>::type = 0>
5838 span_input_adapter(IteratorType first, IteratorType last)
5839 : ia(input_adapter(first, last)) {}
5840
5841 contiguous_bytes_input_adapter &&get()
5842 {
5843 return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
5844 }
5845
5846private:
5847 contiguous_bytes_input_adapter ia;
5848};
5849} // namespace detail
5850} // namespace nlohmann
5851
5852// #include <nlohmann/detail/input/json_sax.hpp>
5853
5854
5855#include <cstddef>
5856#include <string> // string
5857#include <utility> // move
5858#include <vector> // vector
5859
5860// #include <nlohmann/detail/exceptions.hpp>
5861
5862// #include <nlohmann/detail/macro_scope.hpp>
5863
5864
5865namespace nlohmann
5866{
5867
5876template<typename BasicJsonType>
5878{
5879 using number_integer_t = typename BasicJsonType::number_integer_t;
5880 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5881 using number_float_t = typename BasicJsonType::number_float_t;
5882 using string_t = typename BasicJsonType::string_t;
5883 using binary_t = typename BasicJsonType::binary_t;
5884
5889 virtual bool null() = 0;
5890
5896 virtual bool boolean(bool val) = 0;
5897
5903 virtual bool number_integer(number_integer_t val) = 0;
5904
5910 virtual bool number_unsigned(number_unsigned_t val) = 0;
5911
5918 virtual bool number_float(number_float_t val, const string_t &s) = 0;
5919
5926 virtual bool string(string_t &val) = 0;
5927
5934 virtual bool binary(binary_t &val) = 0;
5935
5942 virtual bool start_object(std::size_t elements) = 0;
5943
5950 virtual bool key(string_t &val) = 0;
5951
5956 virtual bool end_object() = 0;
5957
5964 virtual bool start_array(std::size_t elements) = 0;
5965
5970 virtual bool end_array() = 0;
5971
5979 virtual bool parse_error(std::size_t position,
5980 const std::string &last_token,
5981 const detail::exception &ex) = 0;
5982
5983 json_sax() = default;
5984 json_sax(const json_sax &) = default;
5985 json_sax(json_sax &&) noexcept = default;
5986 json_sax &operator=(const json_sax &) = default;
5987 json_sax &operator=(json_sax &&) noexcept = default;
5988 virtual ~json_sax() = default;
5989};
5990
5991
5992namespace detail
5993{
6007template<typename BasicJsonType>
6009{
6010public:
6011 using number_integer_t = typename BasicJsonType::number_integer_t;
6012 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6013 using number_float_t = typename BasicJsonType::number_float_t;
6014 using string_t = typename BasicJsonType::string_t;
6015 using binary_t = typename BasicJsonType::binary_t;
6016
6022 explicit json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_ = true)
6023 : root(r), allow_exceptions(allow_exceptions_)
6024 {}
6025
6026 // make class move-only
6027 json_sax_dom_parser(const json_sax_dom_parser &) = delete;
6028 json_sax_dom_parser(json_sax_dom_parser &&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6029 json_sax_dom_parser &operator=(const json_sax_dom_parser &) = delete;
6030 json_sax_dom_parser &operator=(json_sax_dom_parser &&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6031 ~json_sax_dom_parser() = default;
6032
6033 bool null()
6034 {
6035 handle_value(nullptr);
6036 return true;
6037 }
6038
6039 bool boolean(bool val)
6040 {
6041 handle_value(val);
6042 return true;
6043 }
6044
6045 bool number_integer(number_integer_t val)
6046 {
6047 handle_value(val);
6048 return true;
6049 }
6050
6051 bool number_unsigned(number_unsigned_t val)
6052 {
6053 handle_value(val);
6054 return true;
6055 }
6056
6057 bool number_float(number_float_t val, const string_t & /*unused*/)
6058 {
6059 handle_value(val);
6060 return true;
6061 }
6062
6063 bool string(string_t &val)
6064 {
6065 handle_value(val);
6066 return true;
6067 }
6068
6069 bool binary(binary_t &val)
6070 {
6071 handle_value(std::move(val));
6072 return true;
6073 }
6074
6075 bool start_object(std::size_t len)
6076 {
6077 ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6078
6079 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6080 {
6081 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6082 }
6083
6084 return true;
6085 }
6086
6087 bool key(string_t &val)
6088 {
6089 // add null at given key and store the reference for later
6090 object_element = &(ref_stack.back()->m_value.object->operator[](val));
6091 return true;
6092 }
6093
6094 bool end_object()
6095 {
6096 ref_stack.back()->set_parents();
6097 ref_stack.pop_back();
6098 return true;
6099 }
6100
6101 bool start_array(std::size_t len)
6102 {
6103 ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6104
6105 if (JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6106 {
6107 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6108 }
6109
6110 return true;
6111 }
6112
6113 bool end_array()
6114 {
6115 ref_stack.back()->set_parents();
6116 ref_stack.pop_back();
6117 return true;
6118 }
6119
6120 template<class Exception>
6121 bool parse_error(std::size_t /*unused*/, const std::string & /*unused*/,
6122 const Exception &ex)
6123 {
6124 errored = true;
6125 static_cast<void>(ex);
6126
6127 if (allow_exceptions)
6128 {
6129 JSON_THROW(ex);
6130 }
6131
6132 return false;
6133 }
6134
6135 constexpr bool is_errored() const
6136 {
6137 return errored;
6138 }
6139
6140private:
6147 template<typename Value>
6148 JSON_HEDLEY_RETURNS_NON_NULL
6149 BasicJsonType *handle_value(Value &&v)
6150 {
6151 if (ref_stack.empty())
6152 {
6153 root = BasicJsonType(std::forward<Value>(v));
6154 return &root;
6155 }
6156
6157 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6158
6159 if (ref_stack.back()->is_array())
6160 {
6161 ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6162 return &(ref_stack.back()->m_value.array->back());
6163 }
6164
6165 JSON_ASSERT(ref_stack.back()->is_object());
6166 JSON_ASSERT(object_element);
6167 *object_element = BasicJsonType(std::forward<Value>(v));
6168 return object_element;
6169 }
6170
6172 BasicJsonType &root;
6174 std::vector<BasicJsonType *> ref_stack {};
6176 BasicJsonType *object_element = nullptr;
6178 bool errored = false;
6180 const bool allow_exceptions = true;
6181};
6182
6183template<typename BasicJsonType>
6185{
6186public:
6187 using number_integer_t = typename BasicJsonType::number_integer_t;
6188 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6189 using number_float_t = typename BasicJsonType::number_float_t;
6190 using string_t = typename BasicJsonType::string_t;
6191 using binary_t = typename BasicJsonType::binary_t;
6192 using parser_callback_t = typename BasicJsonType::parser_callback_t;
6193 using parse_event_t = typename BasicJsonType::parse_event_t;
6194
6195 json_sax_dom_callback_parser(BasicJsonType &r,
6196 const parser_callback_t cb,
6197 const bool allow_exceptions_ = true)
6198 : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6199 {
6200 keep_stack.push_back(true);
6201 }
6202
6203 // make class move-only
6205 json_sax_dom_callback_parser(json_sax_dom_callback_parser &&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6207 json_sax_dom_callback_parser &operator=(json_sax_dom_callback_parser &&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6209
6210 bool null()
6211 {
6212 handle_value(nullptr);
6213 return true;
6214 }
6215
6216 bool boolean(bool val)
6217 {
6218 handle_value(val);
6219 return true;
6220 }
6221
6222 bool number_integer(number_integer_t val)
6223 {
6224 handle_value(val);
6225 return true;
6226 }
6227
6228 bool number_unsigned(number_unsigned_t val)
6229 {
6230 handle_value(val);
6231 return true;
6232 }
6233
6234 bool number_float(number_float_t val, const string_t & /*unused*/)
6235 {
6236 handle_value(val);
6237 return true;
6238 }
6239
6240 bool string(string_t &val)
6241 {
6242 handle_value(val);
6243 return true;
6244 }
6245
6246 bool binary(binary_t &val)
6247 {
6248 handle_value(std::move(val));
6249 return true;
6250 }
6251
6252 bool start_object(std::size_t len)
6253 {
6254 // check callback for object start
6255 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6256 keep_stack.push_back(keep);
6257 auto val = handle_value(BasicJsonType::value_t::object, true);
6258 ref_stack.push_back(val.second);
6259
6260 // check object limit
6261 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6262 {
6263 JSON_THROW(out_of_range::create(408, "excessive object size: " + std::to_string(len), *ref_stack.back()));
6264 }
6265
6266 return true;
6267 }
6268
6269 bool key(string_t &val)
6270 {
6271 BasicJsonType k = BasicJsonType(val);
6272 // check callback for key
6273 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6274 key_keep_stack.push_back(keep);
6275
6276 // add discarded value at given key and store the reference for later
6277 if (keep && ref_stack.back())
6278 {
6279 object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6280 }
6281
6282 return true;
6283 }
6284
6285 bool end_object()
6286 {
6287 if (ref_stack.back())
6288 {
6289 if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6290 {
6291 // discard object
6292 *ref_stack.back() = discarded;
6293 }
6294
6295 else
6296 {
6297 ref_stack.back()->set_parents();
6298 }
6299 }
6300
6301 JSON_ASSERT(!ref_stack.empty());
6302 JSON_ASSERT(!keep_stack.empty());
6303 ref_stack.pop_back();
6304 keep_stack.pop_back();
6305
6306 if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6307 {
6308 // remove discarded value
6309 for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6310 {
6311 if (it->is_discarded())
6312 {
6313 ref_stack.back()->erase(it);
6314 break;
6315 }
6316 }
6317 }
6318
6319 return true;
6320 }
6321
6322 bool start_array(std::size_t len)
6323 {
6324 const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6325 keep_stack.push_back(keep);
6326 auto val = handle_value(BasicJsonType::value_t::array, true);
6327 ref_stack.push_back(val.second);
6328
6329 // check array limit
6330 if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != std::size_t(-1) && len > ref_stack.back()->max_size()))
6331 {
6332 JSON_THROW(out_of_range::create(408, "excessive array size: " + std::to_string(len), *ref_stack.back()));
6333 }
6334
6335 return true;
6336 }
6337
6338 bool end_array()
6339 {
6340 bool keep = true;
6341
6342 if (ref_stack.back())
6343 {
6344 keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6345
6346 if (keep)
6347 {
6348 ref_stack.back()->set_parents();
6349 }
6350
6351 else
6352 {
6353 // discard array
6354 *ref_stack.back() = discarded;
6355 }
6356 }
6357
6358 JSON_ASSERT(!ref_stack.empty());
6359 JSON_ASSERT(!keep_stack.empty());
6360 ref_stack.pop_back();
6361 keep_stack.pop_back();
6362
6363 // remove discarded value
6364 if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6365 {
6366 ref_stack.back()->m_value.array->pop_back();
6367 }
6368
6369 return true;
6370 }
6371
6372 template<class Exception>
6373 bool parse_error(std::size_t /*unused*/, const std::string & /*unused*/,
6374 const Exception &ex)
6375 {
6376 errored = true;
6377 static_cast<void>(ex);
6378
6379 if (allow_exceptions)
6380 {
6381 JSON_THROW(ex);
6382 }
6383
6384 return false;
6385 }
6386
6387 constexpr bool is_errored() const
6388 {
6389 return errored;
6390 }
6391
6392private:
6408 template<typename Value>
6409 std::pair<bool, BasicJsonType *> handle_value(Value &&v, const bool skip_callback = false)
6410 {
6411 JSON_ASSERT(!keep_stack.empty());
6412
6413 // do not handle this value if we know it would be added to a discarded
6414 // container
6415 if (!keep_stack.back())
6416 {
6417 return {false, nullptr};
6418 }
6419
6420 // create value
6421 auto value = BasicJsonType(std::forward<Value>(v));
6422 // check callback
6423 const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6424
6425 // do not handle this value if we just learnt it shall be discarded
6426 if (!keep)
6427 {
6428 return {false, nullptr};
6429 }
6430
6431 if (ref_stack.empty())
6432 {
6433 root = std::move(value);
6434 return {true, &root};
6435 }
6436
6437 // skip this value if we already decided to skip the parent
6438 // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6439 if (!ref_stack.back())
6440 {
6441 return {false, nullptr};
6442 }
6443
6444 // we now only expect arrays and objects
6445 JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6446
6447 // array
6448 if (ref_stack.back()->is_array())
6449 {
6450 ref_stack.back()->m_value.array->emplace_back(std::move(value));
6451 return {true, &(ref_stack.back()->m_value.array->back())};
6452 }
6453
6454 // object
6455 JSON_ASSERT(ref_stack.back()->is_object());
6456 // check if we should store an element for the current key
6457 JSON_ASSERT(!key_keep_stack.empty());
6458 const bool store_element = key_keep_stack.back();
6459 key_keep_stack.pop_back();
6460
6461 if (!store_element)
6462 {
6463 return {false, nullptr};
6464 }
6465
6466 JSON_ASSERT(object_element);
6467 *object_element = std::move(value);
6468 return {true, object_element};
6469 }
6470
6472 BasicJsonType &root;
6474 std::vector<BasicJsonType *> ref_stack {};
6476 std::vector<bool> keep_stack {};
6478 std::vector<bool> key_keep_stack {};
6480 BasicJsonType *object_element = nullptr;
6482 bool errored = false;
6484 const parser_callback_t callback = nullptr;
6486 const bool allow_exceptions = true;
6488 BasicJsonType discarded = BasicJsonType::value_t::discarded;
6489};
6490
6491template<typename BasicJsonType>
6493{
6494public:
6495 using number_integer_t = typename BasicJsonType::number_integer_t;
6496 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6497 using number_float_t = typename BasicJsonType::number_float_t;
6498 using string_t = typename BasicJsonType::string_t;
6499 using binary_t = typename BasicJsonType::binary_t;
6500
6501 bool null()
6502 {
6503 return true;
6504 }
6505
6506 bool boolean(bool /*unused*/)
6507 {
6508 return true;
6509 }
6510
6511 bool number_integer(number_integer_t /*unused*/)
6512 {
6513 return true;
6514 }
6515
6516 bool number_unsigned(number_unsigned_t /*unused*/)
6517 {
6518 return true;
6519 }
6520
6521 bool number_float(number_float_t /*unused*/, const string_t & /*unused*/)
6522 {
6523 return true;
6524 }
6525
6526 bool string(string_t & /*unused*/)
6527 {
6528 return true;
6529 }
6530
6531 bool binary(binary_t & /*unused*/)
6532 {
6533 return true;
6534 }
6535
6536 bool start_object(std::size_t /*unused*/ = std::size_t(-1))
6537 {
6538 return true;
6539 }
6540
6541 bool key(string_t & /*unused*/)
6542 {
6543 return true;
6544 }
6545
6546 bool end_object()
6547 {
6548 return true;
6549 }
6550
6551 bool start_array(std::size_t /*unused*/ = std::size_t(-1))
6552 {
6553 return true;
6554 }
6555
6556 bool end_array()
6557 {
6558 return true;
6559 }
6560
6561 bool parse_error(std::size_t /*unused*/, const std::string & /*unused*/, const detail::exception & /*unused*/)
6562 {
6563 return false;
6564 }
6565};
6566} // namespace detail
6567
6568} // namespace nlohmann
6569
6570// #include <nlohmann/detail/input/lexer.hpp>
6571
6572
6573#include <array> // array
6574#include <clocale> // localeconv
6575#include <cstddef> // size_t
6576#include <cstdio> // snprintf
6577#include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6578#include <initializer_list> // initializer_list
6579#include <string> // char_traits, string
6580#include <utility> // move
6581#include <vector> // vector
6582
6583// #include <nlohmann/detail/input/input_adapters.hpp>
6584
6585// #include <nlohmann/detail/input/position_t.hpp>
6586
6587// #include <nlohmann/detail/macro_scope.hpp>
6588
6589
6590namespace nlohmann
6591{
6592namespace detail
6593{
6595// lexer //
6597
6598template<typename BasicJsonType>
6600{
6601public:
6603 enum class token_type
6604 {
6605 uninitialized,
6606 literal_true,
6607 literal_false,
6608 literal_null,
6609 value_string,
6610 value_unsigned,
6611 value_integer,
6612 value_float,
6613 begin_array,
6614 begin_object,
6615 end_array,
6616 end_object,
6617 name_separator,
6618 value_separator,
6619 parse_error,
6620 end_of_input,
6621 literal_or_value
6622 };
6623
6625 JSON_HEDLEY_RETURNS_NON_NULL
6626 JSON_HEDLEY_CONST
6627 static const char *token_type_name(const token_type t) noexcept
6628 {
6629 switch (t)
6630 {
6632 return "<uninitialized>";
6633
6635 return "true literal";
6636
6638 return "false literal";
6639
6641 return "null literal";
6642
6644 return "string literal";
6645
6649 return "number literal";
6650
6652 return "'['";
6653
6655 return "'{'";
6656
6658 return "']'";
6659
6661 return "'}'";
6662
6664 return "':'";
6665
6667 return "','";
6668
6670 return "<parse error>";
6671
6673 return "end of input";
6674
6676 return "'[', '{', or a literal";
6677
6678 // LCOV_EXCL_START
6679 default: // catch non-enum values
6680 return "unknown token";
6681 // LCOV_EXCL_STOP
6682 }
6683 }
6684};
6690template<typename BasicJsonType, typename InputAdapterType>
6691class lexer : public lexer_base<BasicJsonType>
6692{
6693 using number_integer_t = typename BasicJsonType::number_integer_t;
6694 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6695 using number_float_t = typename BasicJsonType::number_float_t;
6696 using string_t = typename BasicJsonType::string_t;
6697 using char_type = typename InputAdapterType::char_type;
6698 using char_int_type = typename std::char_traits<char_type>::int_type;
6699
6700public:
6702
6703 explicit lexer(InputAdapterType &&adapter, bool ignore_comments_ = false) noexcept
6704 : ia(std::move(adapter))
6705 , ignore_comments(ignore_comments_)
6706 , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
6707 {}
6708
6709 // delete because of pointer members
6710 lexer(const lexer &) = delete;
6711 lexer(lexer &&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6712 lexer &operator=(lexer &) = delete;
6713 lexer &operator=(lexer &&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6714 ~lexer() = default;
6715
6716private:
6718 // locales
6720
6722 JSON_HEDLEY_PURE
6723 static char get_decimal_point() noexcept
6724 {
6725 const auto *loc = localeconv();
6726 JSON_ASSERT(loc != nullptr);
6727 return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
6728 }
6729
6731 // scan functions
6733
6750 {
6751 // this function only makes sense after reading `\u`
6752 JSON_ASSERT(current == 'u');
6753 int codepoint = 0;
6754 const auto factors = { 12u, 8u, 4u, 0u };
6755
6756 for (const auto factor : factors)
6757 {
6758 get();
6759
6760 if (current >= '0' && current <= '9')
6761 {
6762 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
6763 }
6764
6765 else if (current >= 'A' && current <= 'F')
6766 {
6767 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
6768 }
6769
6770 else if (current >= 'a' && current <= 'f')
6771 {
6772 codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
6773 }
6774
6775 else
6776 {
6777 return -1;
6778 }
6779 }
6780
6781 JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
6782 return codepoint;
6783 }
6784
6800 bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
6801 {
6802 JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
6803 add(current);
6804
6805 for (auto range = ranges.begin(); range != ranges.end(); ++range)
6806 {
6807 get();
6808
6809 if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
6810 {
6811 add(current);
6812 }
6813
6814 else
6815 {
6816 error_message = "invalid string: ill-formed UTF-8 byte";
6817 return false;
6818 }
6819 }
6820
6821 return true;
6822 }
6823
6840 {
6841 // reset token_buffer (ignore opening quote)
6842 reset();
6843 // we entered the function by reading an open quote
6844 JSON_ASSERT(current == '\"');
6845
6846 while (true)
6847 {
6848 // get next character
6849 switch (get())
6850 {
6851 // end of file while parsing string
6852 case std::char_traits<char_type>::eof():
6853 {
6854 error_message = "invalid string: missing closing quote";
6855 return token_type::parse_error;
6856 }
6857
6858 // closing quote
6859 case '\"':
6860 {
6861 return token_type::value_string;
6862 }
6863
6864 // escapes
6865 case '\\':
6866 {
6867 switch (get())
6868 {
6869 // quotation mark
6870 case '\"':
6871 add('\"');
6872 break;
6873
6874 // reverse solidus
6875 case '\\':
6876 add('\\');
6877 break;
6878
6879 // solidus
6880 case '/':
6881 add('/');
6882 break;
6883
6884 // backspace
6885 case 'b':
6886 add('\b');
6887 break;
6888
6889 // form feed
6890 case 'f':
6891 add('\f');
6892 break;
6893
6894 // line feed
6895 case 'n':
6896 add('\n');
6897 break;
6898
6899 // carriage return
6900 case 'r':
6901 add('\r');
6902 break;
6903
6904 // tab
6905 case 't':
6906 add('\t');
6907 break;
6908
6909 // unicode escapes
6910 case 'u':
6911 {
6912 const int codepoint1 = get_codepoint();
6913 int codepoint = codepoint1; // start with codepoint1
6914
6915 if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
6916 {
6917 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6918 return token_type::parse_error;
6919 }
6920
6921 // check if code point is a high surrogate
6922 if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
6923 {
6924 // expect next \uxxxx entry
6925 if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
6926 {
6927 const int codepoint2 = get_codepoint();
6928
6929 if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
6930 {
6931 error_message = "invalid string: '\\u' must be followed by 4 hex digits";
6932 return token_type::parse_error;
6933 }
6934
6935 // check if codepoint2 is a low surrogate
6936 if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
6937 {
6938 // overwrite codepoint
6939 codepoint = static_cast<int>(
6940 // high surrogate occupies the most significant 22 bits
6941 (static_cast<unsigned int>(codepoint1) << 10u)
6942 // low surrogate occupies the least significant 15 bits
6943 + static_cast<unsigned int>(codepoint2)
6944 // there is still the 0xD800, 0xDC00 and 0x10000 noise
6945 // in the result so we have to subtract with:
6946 // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
6947 - 0x35FDC00u);
6948 }
6949
6950 else
6951 {
6952 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6953 return token_type::parse_error;
6954 }
6955 }
6956
6957 else
6958 {
6959 error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
6960 return token_type::parse_error;
6961 }
6962 }
6963
6964 else
6965 {
6966 if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
6967 {
6968 error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
6969 return token_type::parse_error;
6970 }
6971 }
6972
6973 // result of the above calculation yields a proper codepoint
6974 JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
6975
6976 // translate codepoint into bytes
6977 if (codepoint < 0x80)
6978 {
6979 // 1-byte characters: 0xxxxxxx (ASCII)
6980 add(static_cast<char_int_type>(codepoint));
6981 }
6982
6983 else if (codepoint <= 0x7FF)
6984 {
6985 // 2-byte characters: 110xxxxx 10xxxxxx
6986 add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
6987 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6988 }
6989
6990 else if (codepoint <= 0xFFFF)
6991 {
6992 // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
6993 add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
6994 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
6995 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
6996 }
6997
6998 else
6999 {
7000 // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7001 add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7002 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7003 add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7004 add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7005 }
7006
7007 break;
7008 }
7009
7010 // other characters after escape
7011 default:
7012 error_message = "invalid string: forbidden character after backslash";
7013 return token_type::parse_error;
7014 }
7015
7016 break;
7017 }
7018
7019 // invalid control characters
7020 case 0x00:
7021 {
7022 error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7023 return token_type::parse_error;
7024 }
7025
7026 case 0x01:
7027 {
7028 error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7029 return token_type::parse_error;
7030 }
7031
7032 case 0x02:
7033 {
7034 error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7035 return token_type::parse_error;
7036 }
7037
7038 case 0x03:
7039 {
7040 error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7041 return token_type::parse_error;
7042 }
7043
7044 case 0x04:
7045 {
7046 error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7047 return token_type::parse_error;
7048 }
7049
7050 case 0x05:
7051 {
7052 error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7053 return token_type::parse_error;
7054 }
7055
7056 case 0x06:
7057 {
7058 error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7059 return token_type::parse_error;
7060 }
7061
7062 case 0x07:
7063 {
7064 error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7065 return token_type::parse_error;
7066 }
7067
7068 case 0x08:
7069 {
7070 error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7071 return token_type::parse_error;
7072 }
7073
7074 case 0x09:
7075 {
7076 error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7077 return token_type::parse_error;
7078 }
7079
7080 case 0x0A:
7081 {
7082 error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7083 return token_type::parse_error;
7084 }
7085
7086 case 0x0B:
7087 {
7088 error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7089 return token_type::parse_error;
7090 }
7091
7092 case 0x0C:
7093 {
7094 error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7095 return token_type::parse_error;
7096 }
7097
7098 case 0x0D:
7099 {
7100 error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7101 return token_type::parse_error;
7102 }
7103
7104 case 0x0E:
7105 {
7106 error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7107 return token_type::parse_error;
7108 }
7109
7110 case 0x0F:
7111 {
7112 error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7113 return token_type::parse_error;
7114 }
7115
7116 case 0x10:
7117 {
7118 error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7119 return token_type::parse_error;
7120 }
7121
7122 case 0x11:
7123 {
7124 error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7125 return token_type::parse_error;
7126 }
7127
7128 case 0x12:
7129 {
7130 error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7131 return token_type::parse_error;
7132 }
7133
7134 case 0x13:
7135 {
7136 error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7137 return token_type::parse_error;
7138 }
7139
7140 case 0x14:
7141 {
7142 error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7143 return token_type::parse_error;
7144 }
7145
7146 case 0x15:
7147 {
7148 error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7149 return token_type::parse_error;
7150 }
7151
7152 case 0x16:
7153 {
7154 error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7155 return token_type::parse_error;
7156 }
7157
7158 case 0x17:
7159 {
7160 error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7161 return token_type::parse_error;
7162 }
7163
7164 case 0x18:
7165 {
7166 error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7167 return token_type::parse_error;
7168 }
7169
7170 case 0x19:
7171 {
7172 error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7173 return token_type::parse_error;
7174 }
7175
7176 case 0x1A:
7177 {
7178 error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7179 return token_type::parse_error;
7180 }
7181
7182 case 0x1B:
7183 {
7184 error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7185 return token_type::parse_error;
7186 }
7187
7188 case 0x1C:
7189 {
7190 error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7191 return token_type::parse_error;
7192 }
7193
7194 case 0x1D:
7195 {
7196 error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7197 return token_type::parse_error;
7198 }
7199
7200 case 0x1E:
7201 {
7202 error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7203 return token_type::parse_error;
7204 }
7205
7206 case 0x1F:
7207 {
7208 error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7209 return token_type::parse_error;
7210 }
7211
7212 // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7213 case 0x20:
7214 case 0x21:
7215 case 0x23:
7216 case 0x24:
7217 case 0x25:
7218 case 0x26:
7219 case 0x27:
7220 case 0x28:
7221 case 0x29:
7222 case 0x2A:
7223 case 0x2B:
7224 case 0x2C:
7225 case 0x2D:
7226 case 0x2E:
7227 case 0x2F:
7228 case 0x30:
7229 case 0x31:
7230 case 0x32:
7231 case 0x33:
7232 case 0x34:
7233 case 0x35:
7234 case 0x36:
7235 case 0x37:
7236 case 0x38:
7237 case 0x39:
7238 case 0x3A:
7239 case 0x3B:
7240 case 0x3C:
7241 case 0x3D:
7242 case 0x3E:
7243 case 0x3F:
7244 case 0x40:
7245 case 0x41:
7246 case 0x42:
7247 case 0x43:
7248 case 0x44:
7249 case 0x45:
7250 case 0x46:
7251 case 0x47:
7252 case 0x48:
7253 case 0x49:
7254 case 0x4A:
7255 case 0x4B:
7256 case 0x4C:
7257 case 0x4D:
7258 case 0x4E:
7259 case 0x4F:
7260 case 0x50:
7261 case 0x51:
7262 case 0x52:
7263 case 0x53:
7264 case 0x54:
7265 case 0x55:
7266 case 0x56:
7267 case 0x57:
7268 case 0x58:
7269 case 0x59:
7270 case 0x5A:
7271 case 0x5B:
7272 case 0x5D:
7273 case 0x5E:
7274 case 0x5F:
7275 case 0x60:
7276 case 0x61:
7277 case 0x62:
7278 case 0x63:
7279 case 0x64:
7280 case 0x65:
7281 case 0x66:
7282 case 0x67:
7283 case 0x68:
7284 case 0x69:
7285 case 0x6A:
7286 case 0x6B:
7287 case 0x6C:
7288 case 0x6D:
7289 case 0x6E:
7290 case 0x6F:
7291 case 0x70:
7292 case 0x71:
7293 case 0x72:
7294 case 0x73:
7295 case 0x74:
7296 case 0x75:
7297 case 0x76:
7298 case 0x77:
7299 case 0x78:
7300 case 0x79:
7301 case 0x7A:
7302 case 0x7B:
7303 case 0x7C:
7304 case 0x7D:
7305 case 0x7E:
7306 case 0x7F:
7307 {
7308 add(current);
7309 break;
7310 }
7311
7312 // U+0080..U+07FF: bytes C2..DF 80..BF
7313 case 0xC2:
7314 case 0xC3:
7315 case 0xC4:
7316 case 0xC5:
7317 case 0xC6:
7318 case 0xC7:
7319 case 0xC8:
7320 case 0xC9:
7321 case 0xCA:
7322 case 0xCB:
7323 case 0xCC:
7324 case 0xCD:
7325 case 0xCE:
7326 case 0xCF:
7327 case 0xD0:
7328 case 0xD1:
7329 case 0xD2:
7330 case 0xD3:
7331 case 0xD4:
7332 case 0xD5:
7333 case 0xD6:
7334 case 0xD7:
7335 case 0xD8:
7336 case 0xD9:
7337 case 0xDA:
7338 case 0xDB:
7339 case 0xDC:
7340 case 0xDD:
7341 case 0xDE:
7342 case 0xDF:
7343 {
7344 if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7345 {
7346 return token_type::parse_error;
7347 }
7348 break;
7349 }
7350
7351 // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7352 case 0xE0:
7353 {
7354 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7355 {
7356 return token_type::parse_error;
7357 }
7358 break;
7359 }
7360
7361 // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7362 // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7363 case 0xE1:
7364 case 0xE2:
7365 case 0xE3:
7366 case 0xE4:
7367 case 0xE5:
7368 case 0xE6:
7369 case 0xE7:
7370 case 0xE8:
7371 case 0xE9:
7372 case 0xEA:
7373 case 0xEB:
7374 case 0xEC:
7375 case 0xEE:
7376 case 0xEF:
7377 {
7378 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7379 {
7380 return token_type::parse_error;
7381 }
7382 break;
7383 }
7384
7385 // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7386 case 0xED:
7387 {
7388 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7389 {
7390 return token_type::parse_error;
7391 }
7392 break;
7393 }
7394
7395 // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7396 case 0xF0:
7397 {
7398 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7399 {
7400 return token_type::parse_error;
7401 }
7402 break;
7403 }
7404
7405 // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7406 case 0xF1:
7407 case 0xF2:
7408 case 0xF3:
7409 {
7410 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7411 {
7412 return token_type::parse_error;
7413 }
7414 break;
7415 }
7416
7417 // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7418 case 0xF4:
7419 {
7420 if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7421 {
7422 return token_type::parse_error;
7423 }
7424 break;
7425 }
7426
7427 // remaining bytes (80..C1 and F5..FF) are ill-formed
7428 default:
7429 {
7430 error_message = "invalid string: ill-formed UTF-8 byte";
7431 return token_type::parse_error;
7432 }
7433 }
7434 }
7435 }
7436
7442 {
7443 switch (get())
7444 {
7445 // single-line comments skip input until a newline or EOF is read
7446 case '/':
7447 {
7448 while (true)
7449 {
7450 switch (get())
7451 {
7452 case '\n':
7453 case '\r':
7454 case std::char_traits<char_type>::eof():
7455 case '\0':
7456 return true;
7457
7458 default:
7459 break;
7460 }
7461 }
7462 }
7463
7464 // multi-line comments skip input until */ is read
7465 case '*':
7466 {
7467 while (true)
7468 {
7469 switch (get())
7470 {
7471 case std::char_traits<char_type>::eof():
7472 case '\0':
7473 {
7474 error_message = "invalid comment; missing closing '*/'";
7475 return false;
7476 }
7477
7478 case '*':
7479 {
7480 switch (get())
7481 {
7482 case '/':
7483 return true;
7484
7485 default:
7486 {
7487 unget();
7488 continue;
7489 }
7490 }
7491 }
7492
7493 default:
7494 continue;
7495 }
7496 }
7497 }
7498
7499 // unexpected character after reading '/'
7500 default:
7501 {
7502 error_message = "invalid comment; expecting '/' or '*' after '/'";
7503 return false;
7504 }
7505 }
7506 }
7507
7508 JSON_HEDLEY_NON_NULL(2)
7509 static void strtof(float &f, const char *str, char **endptr) noexcept
7510 {
7511 f = std::strtof(str, endptr);
7512 }
7513
7514 JSON_HEDLEY_NON_NULL(2)
7515 static void strtof(double &f, const char *str, char **endptr) noexcept
7516 {
7517 f = std::strtod(str, endptr);
7518 }
7519
7520 JSON_HEDLEY_NON_NULL(2)
7521 static void strtof(long double &f, const char *str, char **endptr) noexcept
7522 {
7523 f = std::strtold(str, endptr);
7524 }
7525
7566 token_type scan_number() // lgtm [cpp/use-of-goto]
7567 {
7568 // reset token_buffer to store the number's bytes
7569 reset();
7570 // the type of the parsed number; initially set to unsigned; will be
7571 // changed if minus sign, decimal point or exponent is read
7572 token_type number_type = token_type::value_unsigned;
7573
7574 // state (init): we just found out we need to scan a number
7575 switch (current)
7576 {
7577 case '-':
7578 {
7579 add(current);
7580 goto scan_number_minus;
7581 }
7582
7583 case '0':
7584 {
7585 add(current);
7586 goto scan_number_zero;
7587 }
7588
7589 case '1':
7590 case '2':
7591 case '3':
7592 case '4':
7593 case '5':
7594 case '6':
7595 case '7':
7596 case '8':
7597 case '9':
7598 {
7599 add(current);
7600 goto scan_number_any1;
7601 }
7602
7603 // all other characters are rejected outside scan_number()
7604 default: // LCOV_EXCL_LINE
7605 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7606 }
7607
7608scan_number_minus:
7609 // state: we just parsed a leading minus sign
7610 number_type = token_type::value_integer;
7611
7612 switch (get())
7613 {
7614 case '0':
7615 {
7616 add(current);
7617 goto scan_number_zero;
7618 }
7619
7620 case '1':
7621 case '2':
7622 case '3':
7623 case '4':
7624 case '5':
7625 case '6':
7626 case '7':
7627 case '8':
7628 case '9':
7629 {
7630 add(current);
7631 goto scan_number_any1;
7632 }
7633
7634 default:
7635 {
7636 error_message = "invalid number; expected digit after '-'";
7637 return token_type::parse_error;
7638 }
7639 }
7640
7641scan_number_zero:
7642
7643 // state: we just parse a zero (maybe with a leading minus sign)
7644 switch (get())
7645 {
7646 case '.':
7647 {
7649 goto scan_number_decimal1;
7650 }
7651
7652 case 'e':
7653 case 'E':
7654 {
7655 add(current);
7656 goto scan_number_exponent;
7657 }
7658
7659 default:
7660 goto scan_number_done;
7661 }
7662
7663scan_number_any1:
7664
7665 // state: we just parsed a number 0-9 (maybe with a leading minus sign)
7666 switch (get())
7667 {
7668 case '0':
7669 case '1':
7670 case '2':
7671 case '3':
7672 case '4':
7673 case '5':
7674 case '6':
7675 case '7':
7676 case '8':
7677 case '9':
7678 {
7679 add(current);
7680 goto scan_number_any1;
7681 }
7682
7683 case '.':
7684 {
7686 goto scan_number_decimal1;
7687 }
7688
7689 case 'e':
7690 case 'E':
7691 {
7692 add(current);
7693 goto scan_number_exponent;
7694 }
7695
7696 default:
7697 goto scan_number_done;
7698 }
7699
7700scan_number_decimal1:
7701 // state: we just parsed a decimal point
7702 number_type = token_type::value_float;
7703
7704 switch (get())
7705 {
7706 case '0':
7707 case '1':
7708 case '2':
7709 case '3':
7710 case '4':
7711 case '5':
7712 case '6':
7713 case '7':
7714 case '8':
7715 case '9':
7716 {
7717 add(current);
7718 goto scan_number_decimal2;
7719 }
7720
7721 default:
7722 {
7723 error_message = "invalid number; expected digit after '.'";
7724 return token_type::parse_error;
7725 }
7726 }
7727
7728scan_number_decimal2:
7729
7730 // we just parsed at least one number after a decimal point
7731 switch (get())
7732 {
7733 case '0':
7734 case '1':
7735 case '2':
7736 case '3':
7737 case '4':
7738 case '5':
7739 case '6':
7740 case '7':
7741 case '8':
7742 case '9':
7743 {
7744 add(current);
7745 goto scan_number_decimal2;
7746 }
7747
7748 case 'e':
7749 case 'E':
7750 {
7751 add(current);
7752 goto scan_number_exponent;
7753 }
7754
7755 default:
7756 goto scan_number_done;
7757 }
7758
7759scan_number_exponent:
7760 // we just parsed an exponent
7761 number_type = token_type::value_float;
7762
7763 switch (get())
7764 {
7765 case '+':
7766 case '-':
7767 {
7768 add(current);
7769 goto scan_number_sign;
7770 }
7771
7772 case '0':
7773 case '1':
7774 case '2':
7775 case '3':
7776 case '4':
7777 case '5':
7778 case '6':
7779 case '7':
7780 case '8':
7781 case '9':
7782 {
7783 add(current);
7784 goto scan_number_any2;
7785 }
7786
7787 default:
7788 {
7790 "invalid number; expected '+', '-', or digit after exponent";
7791 return token_type::parse_error;
7792 }
7793 }
7794
7795scan_number_sign:
7796
7797 // we just parsed an exponent sign
7798 switch (get())
7799 {
7800 case '0':
7801 case '1':
7802 case '2':
7803 case '3':
7804 case '4':
7805 case '5':
7806 case '6':
7807 case '7':
7808 case '8':
7809 case '9':
7810 {
7811 add(current);
7812 goto scan_number_any2;
7813 }
7814
7815 default:
7816 {
7817 error_message = "invalid number; expected digit after exponent sign";
7818 return token_type::parse_error;
7819 }
7820 }
7821
7822scan_number_any2:
7823
7824 // we just parsed a number after the exponent or exponent sign
7825 switch (get())
7826 {
7827 case '0':
7828 case '1':
7829 case '2':
7830 case '3':
7831 case '4':
7832 case '5':
7833 case '6':
7834 case '7':
7835 case '8':
7836 case '9':
7837 {
7838 add(current);
7839 goto scan_number_any2;
7840 }
7841
7842 default:
7843 goto scan_number_done;
7844 }
7845
7846scan_number_done:
7847 // unget the character after the number (we only read it to know that
7848 // we are done scanning a number)
7849 unget();
7850 char *endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
7851 errno = 0;
7852
7853 // try to parse integers first and fall back to floats
7854 if (number_type == token_type::value_unsigned)
7855 {
7856 const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
7857 // we checked the number format before
7858 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7859
7860 if (errno == 0)
7861 {
7862 value_unsigned = static_cast<number_unsigned_t>(x);
7863
7864 if (value_unsigned == x)
7865 {
7866 return token_type::value_unsigned;
7867 }
7868 }
7869 }
7870
7871 else if (number_type == token_type::value_integer)
7872 {
7873 const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
7874 // we checked the number format before
7875 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7876
7877 if (errno == 0)
7878 {
7879 value_integer = static_cast<number_integer_t>(x);
7880
7881 if (value_integer == x)
7882 {
7883 return token_type::value_integer;
7884 }
7885 }
7886 }
7887
7888 // this code is reached if we parse a floating-point number or if an
7889 // integer conversion above failed
7890 strtof(value_float, token_buffer.data(), &endptr);
7891 // we checked the number format before
7892 JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
7893 return token_type::value_float;
7894 }
7895
7901 JSON_HEDLEY_NON_NULL(2)
7902 token_type scan_literal(const char_type *literal_text, const std::size_t length,
7903 token_type return_type)
7904 {
7905 JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
7906
7907 for (std::size_t i = 1; i < length; ++i)
7908 {
7909 if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
7910 {
7911 error_message = "invalid literal";
7912 return token_type::parse_error;
7913 }
7914 }
7915
7916 return return_type;
7917 }
7918
7920 // input management
7922
7924 void reset() noexcept
7925 {
7926 token_buffer.clear();
7927 token_string.clear();
7928 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7929 }
7930
7931 /*
7932 @brief get next character from the input
7933
7934 This function provides the interface to the used input adapter. It does
7935 not throw in case the input reached EOF, but returns a
7936 `std::char_traits<char>::eof()` in that case. Stores the scanned characters
7937 for use in error messages.
7938
7939 @return character read from the input
7940 */
7941 char_int_type get()
7942 {
7945
7946 if (next_unget)
7947 {
7948 // just reset the next_unget variable and work with current
7949 next_unget = false;
7950 }
7951
7952 else
7953 {
7954 current = ia.get_character();
7955 }
7956
7957 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7958 {
7959 token_string.push_back(std::char_traits<char_type>::to_char_type(current));
7960 }
7961
7962 if (current == '\n')
7963 {
7966 }
7967
7968 return current;
7969 }
7970
7979 void unget()
7980 {
7981 next_unget = true;
7983
7984 // in case we "unget" a newline, we have to also decrement the lines_read
7986 {
7987 if (position.lines_read > 0)
7988 {
7990 }
7991 }
7992
7993 else
7994 {
7996 }
7997
7998 if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
7999 {
8000 JSON_ASSERT(!token_string.empty());
8001 token_string.pop_back();
8002 }
8003 }
8004
8006 void add(char_int_type c)
8007 {
8008 token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8009 }
8010
8011public:
8013 // value getters
8015
8017 constexpr number_integer_t get_number_integer() const noexcept
8018 {
8019 return value_integer;
8020 }
8021
8023 constexpr number_unsigned_t get_number_unsigned() const noexcept
8024 {
8025 return value_unsigned;
8026 }
8027
8029 constexpr number_float_t get_number_float() const noexcept
8030 {
8031 return value_float;
8032 }
8033
8035 string_t &get_string()
8036 {
8037 return token_buffer;
8038 }
8039
8041 // diagnostics
8043
8045 constexpr position_t get_position() const noexcept
8046 {
8047 return position;
8048 }
8049
8053 std::string get_token_string() const
8054 {
8055 // escape control characters
8056 std::string result;
8057
8058 for (const auto c : token_string)
8059 {
8060 if (static_cast<unsigned char>(c) <= '\x1F')
8061 {
8062 // escape control characters
8063 std::array<char, 9> cs{{}};
8064 (std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8065 result += cs.data();
8066 }
8067
8068 else
8069 {
8070 // add character as is
8071 result.push_back(static_cast<std::string::value_type>(c));
8072 }
8073 }
8074
8075 return result;
8076 }
8077
8079 JSON_HEDLEY_RETURNS_NON_NULL
8080 constexpr const char *get_error_message() const noexcept
8081 {
8082 return error_message;
8083 }
8084
8086 // actual scanner
8088
8094 {
8095 if (get() == 0xEF)
8096 {
8097 // check if we completely parse the BOM
8098 return get() == 0xBB && get() == 0xBF;
8099 }
8100
8101 // the first character is not the beginning of the BOM; unget it to
8102 // process is later
8103 unget();
8104 return true;
8105 }
8106
8107 void skip_whitespace()
8108 {
8109 do
8110 {
8111 get();
8112 }
8113 while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8114 }
8115
8116 token_type scan()
8117 {
8118 // initially, skip the BOM
8119 if (position.chars_read_total == 0 && !skip_bom())
8120 {
8121 error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8122 return token_type::parse_error;
8123 }
8124
8125 // read next character and ignore whitespace
8126 skip_whitespace();
8127
8128 // ignore comments
8129 while (ignore_comments && current == '/')
8130 {
8131 if (!scan_comment())
8132 {
8133 return token_type::parse_error;
8134 }
8135
8136 // skip following whitespace
8137 skip_whitespace();
8138 }
8139
8140 switch (current)
8141 {
8142 // structural characters
8143 case '[':
8144 return token_type::begin_array;
8145
8146 case ']':
8147 return token_type::end_array;
8148
8149 case '{':
8150 return token_type::begin_object;
8151
8152 case '}':
8153 return token_type::end_object;
8154
8155 case ':':
8156 return token_type::name_separator;
8157
8158 case ',':
8159 return token_type::value_separator;
8160
8161 // literals
8162 case 't':
8163 {
8164 std::array<char_type, 4> true_literal = {{char_type('t'), char_type('r'), char_type('u'), char_type('e')}};
8165 return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8166 }
8167
8168 case 'f':
8169 {
8170 std::array<char_type, 5> false_literal = {{char_type('f'), char_type('a'), char_type('l'), char_type('s'), char_type('e')}};
8171 return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8172 }
8173
8174 case 'n':
8175 {
8176 std::array<char_type, 4> null_literal = {{char_type('n'), char_type('u'), char_type('l'), char_type('l')}};
8177 return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8178 }
8179
8180 // string
8181 case '\"':
8182 return scan_string();
8183
8184 // number
8185 case '-':
8186 case '0':
8187 case '1':
8188 case '2':
8189 case '3':
8190 case '4':
8191 case '5':
8192 case '6':
8193 case '7':
8194 case '8':
8195 case '9':
8196 return scan_number();
8197
8198 // end of input (the null byte is needed when parsing from
8199 // string literals)
8200 case '\0':
8201 case std::char_traits<char_type>::eof():
8202 return token_type::end_of_input;
8203
8204 // error
8205 default:
8206 error_message = "invalid literal";
8207 return token_type::parse_error;
8208 }
8209 }
8210
8211private:
8213 InputAdapterType ia;
8214
8216 const bool ignore_comments = false;
8217
8219 char_int_type current = std::char_traits<char_type>::eof();
8220
8222 bool next_unget = false;
8223
8226
8228 std::vector<char_type> token_string {};
8229
8231 string_t token_buffer {};
8232
8234 const char *error_message = "";
8235
8236 // number values
8237 number_integer_t value_integer = 0;
8238 number_unsigned_t value_unsigned = 0;
8239 number_float_t value_float = 0;
8240
8242 const char_int_type decimal_point_char = '.';
8243};
8244} // namespace detail
8245} // namespace nlohmann
8246
8247// #include <nlohmann/detail/macro_scope.hpp>
8248
8249// #include <nlohmann/detail/meta/is_sax.hpp>
8250
8251
8252#include <cstdint> // size_t
8253#include <utility> // declval
8254#include <string> // string
8255
8256// #include <nlohmann/detail/meta/detected.hpp>
8257
8258// #include <nlohmann/detail/meta/type_traits.hpp>
8259
8260
8261namespace nlohmann
8262{
8263namespace detail
8264{
8265template<typename T>
8266using null_function_t = decltype(std::declval<T &>().null());
8267
8268template<typename T>
8269using boolean_function_t =
8270 decltype(std::declval<T &>().boolean(std::declval<bool>()));
8271
8272template<typename T, typename Integer>
8273using number_integer_function_t =
8274 decltype(std::declval<T &>().number_integer(std::declval<Integer>()));
8275
8276template<typename T, typename Unsigned>
8277using number_unsigned_function_t =
8278 decltype(std::declval<T &>().number_unsigned(std::declval<Unsigned>()));
8279
8280template<typename T, typename Float, typename String>
8281using number_float_function_t = decltype(std::declval<T &>().number_float(
8282 std::declval<Float>(), std::declval<const String &>()));
8283
8284template<typename T, typename String>
8285using string_function_t =
8286 decltype(std::declval<T &>().string(std::declval<String &>()));
8287
8288template<typename T, typename Binary>
8289using binary_function_t =
8290 decltype(std::declval<T &>().binary(std::declval<Binary &>()));
8291
8292template<typename T>
8293using start_object_function_t =
8294 decltype(std::declval<T &>().start_object(std::declval<std::size_t>()));
8295
8296template<typename T, typename String>
8297using key_function_t =
8298 decltype(std::declval<T &>().key(std::declval<String &>()));
8299
8300template<typename T>
8301using end_object_function_t = decltype(std::declval<T &>().end_object());
8302
8303template<typename T>
8304using start_array_function_t =
8305 decltype(std::declval<T &>().start_array(std::declval<std::size_t>()));
8306
8307template<typename T>
8308using end_array_function_t = decltype(std::declval<T &>().end_array());
8309
8310template<typename T, typename Exception>
8311using parse_error_function_t = decltype(std::declval<T &>().parse_error(
8312 std::declval<std::size_t>(), std::declval<const std::string &>(),
8313 std::declval<const Exception &>()));
8314
8315template<typename SAX, typename BasicJsonType>
8317{
8318private:
8320 "BasicJsonType must be of type basic_json<...>");
8321
8322 using number_integer_t = typename BasicJsonType::number_integer_t;
8323 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8324 using number_float_t = typename BasicJsonType::number_float_t;
8325 using string_t = typename BasicJsonType::string_t;
8326 using binary_t = typename BasicJsonType::binary_t;
8327 using exception_t = typename BasicJsonType::exception;
8328
8329public:
8330 static constexpr bool value =
8331 is_detected_exact<bool, null_function_t, SAX>::value &&
8332 is_detected_exact<bool, boolean_function_t, SAX>::value &&
8333 is_detected_exact<bool, number_integer_function_t, SAX, number_integer_t>::value &&
8334 is_detected_exact<bool, number_unsigned_function_t, SAX, number_unsigned_t>::value &&
8335 is_detected_exact<bool, number_float_function_t, SAX, number_float_t, string_t>::value &&
8336 is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
8337 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value &&
8338 is_detected_exact<bool, start_object_function_t, SAX>::value &&
8339 is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
8340 is_detected_exact<bool, end_object_function_t, SAX>::value &&
8341 is_detected_exact<bool, start_array_function_t, SAX>::value &&
8342 is_detected_exact<bool, end_array_function_t, SAX>::value &&
8343 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
8344};
8345
8346template<typename SAX, typename BasicJsonType>
8348{
8349private:
8351 "BasicJsonType must be of type basic_json<...>");
8352
8353 using number_integer_t = typename BasicJsonType::number_integer_t;
8354 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8355 using number_float_t = typename BasicJsonType::number_float_t;
8356 using string_t = typename BasicJsonType::string_t;
8357 using binary_t = typename BasicJsonType::binary_t;
8358 using exception_t = typename BasicJsonType::exception;
8359
8360public:
8361 static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
8362 "Missing/invalid function: bool null()");
8363 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8364 "Missing/invalid function: bool boolean(bool)");
8365 static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
8366 "Missing/invalid function: bool boolean(bool)");
8367 static_assert(
8368 is_detected_exact<bool, number_integer_function_t, SAX,
8369 number_integer_t>::value,
8370 "Missing/invalid function: bool number_integer(number_integer_t)");
8371 static_assert(
8372 is_detected_exact<bool, number_unsigned_function_t, SAX,
8373 number_unsigned_t>::value,
8374 "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8375 static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8376 number_float_t, string_t>::value,
8377 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8378 static_assert(
8379 is_detected_exact<bool, string_function_t, SAX, string_t>::value,
8380 "Missing/invalid function: bool string(string_t&)");
8381 static_assert(
8382 is_detected_exact<bool, binary_function_t, SAX, binary_t>::value,
8383 "Missing/invalid function: bool binary(binary_t&)");
8384 static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
8385 "Missing/invalid function: bool start_object(std::size_t)");
8386 static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
8387 "Missing/invalid function: bool key(string_t&)");
8388 static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
8389 "Missing/invalid function: bool end_object()");
8390 static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
8391 "Missing/invalid function: bool start_array(std::size_t)");
8392 static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
8393 "Missing/invalid function: bool end_array()");
8394 static_assert(
8395 is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
8396 "Missing/invalid function: bool parse_error(std::size_t, const "
8397 "std::string&, const exception&)");
8398};
8399} // namespace detail
8400} // namespace nlohmann
8401
8402// #include <nlohmann/detail/meta/type_traits.hpp>
8403
8404// #include <nlohmann/detail/value_t.hpp>
8405
8406
8407namespace nlohmann
8408{
8409namespace detail
8410{
8411
8414{
8415 error,
8416 ignore,
8417 store
8418};
8419
8427static inline bool little_endianess(int num = 1) noexcept
8428{
8429 return *reinterpret_cast<char *>(&num) == 1;
8430}
8431
8432
8434// binary reader //
8436
8440template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8442{
8443 using number_integer_t = typename BasicJsonType::number_integer_t;
8444 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8445 using number_float_t = typename BasicJsonType::number_float_t;
8446 using string_t = typename BasicJsonType::string_t;
8447 using binary_t = typename BasicJsonType::binary_t;
8448 using json_sax_t = SAX;
8449 using char_type = typename InputAdapterType::char_type;
8450 using char_int_type = typename std::char_traits<char_type>::int_type;
8451
8452public:
8458 explicit binary_reader(InputAdapterType &&adapter) noexcept : ia(std::move(adapter))
8459 {
8461 }
8462
8463 // make class move-only
8464 binary_reader(const binary_reader &) = delete;
8465 binary_reader(binary_reader &&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8466 binary_reader &operator=(const binary_reader &) = delete;
8467 binary_reader &operator=(binary_reader &&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8468 ~binary_reader() = default;
8469
8478 JSON_HEDLEY_NON_NULL(3)
8479 bool sax_parse(const input_format_t format,
8480 json_sax_t *sax_,
8481 const bool strict = true,
8482 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8483 {
8484 sax = sax_;
8485 bool result = false;
8486
8487 switch (format)
8488 {
8489 case input_format_t::bson:
8490 result = parse_bson_internal();
8491 break;
8492
8493 case input_format_t::cbor:
8494 result = parse_cbor_internal(true, tag_handler);
8495 break;
8496
8497 case input_format_t::msgpack:
8498 result = parse_msgpack_internal();
8499 break;
8500
8501 case input_format_t::ubjson:
8502 result = parse_ubjson_internal();
8503 break;
8504
8505 case input_format_t::json: // LCOV_EXCL_LINE
8506 default: // LCOV_EXCL_LINE
8507 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8508 }
8509
8510 // strict mode: next byte must be EOF
8511 if (result && strict)
8512 {
8513 if (format == input_format_t::ubjson)
8514 {
8516 }
8517
8518 else
8519 {
8520 get();
8521 }
8522
8523 if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8524 {
8525 return sax->parse_error(chars_read, get_token_string(),
8526 parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value"), BasicJsonType()));
8527 }
8528 }
8529
8530 return result;
8531 }
8532
8533private:
8535 // BSON //
8537
8543 {
8544 std::int32_t document_size{};
8545 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8546
8547 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
8548 {
8549 return false;
8550 }
8551
8552 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8553 {
8554 return false;
8555 }
8556
8557 return sax->end_object();
8558 }
8559
8567 bool get_bson_cstr(string_t &result)
8568 {
8569 auto out = std::back_inserter(result);
8570
8571 while (true)
8572 {
8573 get();
8574
8575 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
8576 {
8577 return false;
8578 }
8579
8580 if (current == 0x00)
8581 {
8582 return true;
8583 }
8584
8585 *out++ = static_cast<typename string_t::value_type>(current);
8586 }
8587 }
8588
8600 template<typename NumberType>
8601 bool get_bson_string(const NumberType len, string_t &result)
8602 {
8603 if (JSON_HEDLEY_UNLIKELY(len < 1))
8604 {
8605 auto last_token = get_token_string();
8606 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()));
8607 }
8608
8609 return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8610 }
8611
8621 template<typename NumberType>
8622 bool get_bson_binary(const NumberType len, binary_t &result)
8623 {
8624 if (JSON_HEDLEY_UNLIKELY(len < 0))
8625 {
8626 auto last_token = get_token_string();
8627 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()));
8628 }
8629
8630 // All BSON binary values have a subtype
8631 std::uint8_t subtype{};
8632 get_number<std::uint8_t>(input_format_t::bson, subtype);
8633 result.set_subtype(subtype);
8634 return get_binary(input_format_t::bson, len, result);
8635 }
8636
8647 bool parse_bson_element_internal(const char_int_type element_type,
8648 const std::size_t element_type_parse_position)
8649 {
8650 switch (element_type)
8651 {
8652 case 0x01: // double
8653 {
8654 double number{};
8655 return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8656 }
8657
8658 case 0x02: // string
8659 {
8660 std::int32_t len{};
8661 string_t value;
8662 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8663 }
8664
8665 case 0x03: // object
8666 {
8667 return parse_bson_internal();
8668 }
8669
8670 case 0x04: // array
8671 {
8672 return parse_bson_array();
8673 }
8674
8675 case 0x05: // binary
8676 {
8677 std::int32_t len{};
8678 binary_t value;
8679 return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
8680 }
8681
8682 case 0x08: // boolean
8683 {
8684 return sax->boolean(get() != 0);
8685 }
8686
8687 case 0x0A: // null
8688 {
8689 return sax->null();
8690 }
8691
8692 case 0x10: // int32
8693 {
8694 std::int32_t value{};
8695 return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8696 }
8697
8698 case 0x12: // int64
8699 {
8700 std::int64_t value{};
8701 return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
8702 }
8703
8704 default: // anything else not supported (yet)
8705 {
8706 std::array<char, 3> cr{{}};
8707 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8708 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()));
8709 }
8710 }
8711 }
8712
8725 bool parse_bson_element_list(const bool is_array)
8726 {
8727 string_t key;
8728
8729 while (auto element_type = get())
8730 {
8731 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
8732 {
8733 return false;
8734 }
8735
8736 const std::size_t element_type_parse_position = chars_read;
8737
8738 if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
8739 {
8740 return false;
8741 }
8742
8743 if (!is_array && !sax->key(key))
8744 {
8745 return false;
8746 }
8747
8748 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
8749 {
8750 return false;
8751 }
8752
8753 // get_bson_cstr only appends
8754 key.clear();
8755 }
8756
8757 return true;
8758 }
8759
8765 {
8766 std::int32_t document_size{};
8767 get_number<std::int32_t, true>(input_format_t::bson, document_size);
8768
8769 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
8770 {
8771 return false;
8772 }
8773
8774 if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
8775 {
8776 return false;
8777 }
8778
8779 return sax->end_array();
8780 }
8781
8783 // CBOR //
8785
8794 bool parse_cbor_internal(const bool get_char,
8795 const cbor_tag_handler_t tag_handler)
8796 {
8797 switch (get_char ? get() : current)
8798 {
8799 // EOF
8800 case std::char_traits<char_type>::eof():
8801 return unexpect_eof(input_format_t::cbor, "value");
8802
8803 // Integer 0x00..0x17 (0..23)
8804 case 0x00:
8805 case 0x01:
8806 case 0x02:
8807 case 0x03:
8808 case 0x04:
8809 case 0x05:
8810 case 0x06:
8811 case 0x07:
8812 case 0x08:
8813 case 0x09:
8814 case 0x0A:
8815 case 0x0B:
8816 case 0x0C:
8817 case 0x0D:
8818 case 0x0E:
8819 case 0x0F:
8820 case 0x10:
8821 case 0x11:
8822 case 0x12:
8823 case 0x13:
8824 case 0x14:
8825 case 0x15:
8826 case 0x16:
8827 case 0x17:
8828 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
8829
8830 case 0x18: // Unsigned integer (one-byte uint8_t follows)
8831 {
8832 std::uint8_t number{};
8833 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8834 }
8835
8836 case 0x19: // Unsigned integer (two-byte uint16_t follows)
8837 {
8838 std::uint16_t number{};
8839 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8840 }
8841
8842 case 0x1A: // Unsigned integer (four-byte uint32_t follows)
8843 {
8844 std::uint32_t number{};
8845 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8846 }
8847
8848 case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
8849 {
8850 std::uint64_t number{};
8851 return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
8852 }
8853
8854 // Negative integer -1-0x00..-1-0x17 (-1..-24)
8855 case 0x20:
8856 case 0x21:
8857 case 0x22:
8858 case 0x23:
8859 case 0x24:
8860 case 0x25:
8861 case 0x26:
8862 case 0x27:
8863 case 0x28:
8864 case 0x29:
8865 case 0x2A:
8866 case 0x2B:
8867 case 0x2C:
8868 case 0x2D:
8869 case 0x2E:
8870 case 0x2F:
8871 case 0x30:
8872 case 0x31:
8873 case 0x32:
8874 case 0x33:
8875 case 0x34:
8876 case 0x35:
8877 case 0x36:
8878 case 0x37:
8879 return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
8880
8881 case 0x38: // Negative integer (one-byte uint8_t follows)
8882 {
8883 std::uint8_t number{};
8884 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8885 }
8886
8887 case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
8888 {
8889 std::uint16_t number{};
8890 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8891 }
8892
8893 case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
8894 {
8895 std::uint32_t number{};
8896 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
8897 }
8898
8899 case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
8900 {
8901 std::uint64_t number{};
8902 return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
8903 - static_cast<number_integer_t>(number));
8904 }
8905
8906 // Binary data (0x00..0x17 bytes follow)
8907 case 0x40:
8908 case 0x41:
8909 case 0x42:
8910 case 0x43:
8911 case 0x44:
8912 case 0x45:
8913 case 0x46:
8914 case 0x47:
8915 case 0x48:
8916 case 0x49:
8917 case 0x4A:
8918 case 0x4B:
8919 case 0x4C:
8920 case 0x4D:
8921 case 0x4E:
8922 case 0x4F:
8923 case 0x50:
8924 case 0x51:
8925 case 0x52:
8926 case 0x53:
8927 case 0x54:
8928 case 0x55:
8929 case 0x56:
8930 case 0x57:
8931 case 0x58: // Binary data (one-byte uint8_t for n follows)
8932 case 0x59: // Binary data (two-byte uint16_t for n follow)
8933 case 0x5A: // Binary data (four-byte uint32_t for n follow)
8934 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
8935 case 0x5F: // Binary data (indefinite length)
8936 {
8937 binary_t b;
8938 return get_cbor_binary(b) && sax->binary(b);
8939 }
8940
8941 // UTF-8 string (0x00..0x17 bytes follow)
8942 case 0x60:
8943 case 0x61:
8944 case 0x62:
8945 case 0x63:
8946 case 0x64:
8947 case 0x65:
8948 case 0x66:
8949 case 0x67:
8950 case 0x68:
8951 case 0x69:
8952 case 0x6A:
8953 case 0x6B:
8954 case 0x6C:
8955 case 0x6D:
8956 case 0x6E:
8957 case 0x6F:
8958 case 0x70:
8959 case 0x71:
8960 case 0x72:
8961 case 0x73:
8962 case 0x74:
8963 case 0x75:
8964 case 0x76:
8965 case 0x77:
8966 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
8967 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
8968 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
8969 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
8970 case 0x7F: // UTF-8 string (indefinite length)
8971 {
8972 string_t s;
8973 return get_cbor_string(s) && sax->string(s);
8974 }
8975
8976 // array (0x00..0x17 data items follow)
8977 case 0x80:
8978 case 0x81:
8979 case 0x82:
8980 case 0x83:
8981 case 0x84:
8982 case 0x85:
8983 case 0x86:
8984 case 0x87:
8985 case 0x88:
8986 case 0x89:
8987 case 0x8A:
8988 case 0x8B:
8989 case 0x8C:
8990 case 0x8D:
8991 case 0x8E:
8992 case 0x8F:
8993 case 0x90:
8994 case 0x91:
8995 case 0x92:
8996 case 0x93:
8997 case 0x94:
8998 case 0x95:
8999 case 0x96:
9000 case 0x97:
9001 return get_cbor_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9002
9003 case 0x98: // array (one-byte uint8_t for n follows)
9004 {
9005 std::uint8_t len{};
9006 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9007 }
9008
9009 case 0x99: // array (two-byte uint16_t for n follow)
9010 {
9011 std::uint16_t len{};
9012 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9013 }
9014
9015 case 0x9A: // array (four-byte uint32_t for n follow)
9016 {
9017 std::uint32_t len{};
9018 return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9019 }
9020
9021 case 0x9B: // array (eight-byte uint64_t for n follow)
9022 {
9023 std::uint64_t len{};
9024 return get_number(input_format_t::cbor, len) && get_cbor_array(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9025 }
9026
9027 case 0x9F: // array (indefinite length)
9028 return get_cbor_array(std::size_t(-1), tag_handler);
9029
9030 // map (0x00..0x17 pairs of data items follow)
9031 case 0xA0:
9032 case 0xA1:
9033 case 0xA2:
9034 case 0xA3:
9035 case 0xA4:
9036 case 0xA5:
9037 case 0xA6:
9038 case 0xA7:
9039 case 0xA8:
9040 case 0xA9:
9041 case 0xAA:
9042 case 0xAB:
9043 case 0xAC:
9044 case 0xAD:
9045 case 0xAE:
9046 case 0xAF:
9047 case 0xB0:
9048 case 0xB1:
9049 case 0xB2:
9050 case 0xB3:
9051 case 0xB4:
9052 case 0xB5:
9053 case 0xB6:
9054 case 0xB7:
9055 return get_cbor_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9056
9057 case 0xB8: // map (one-byte uint8_t for n follows)
9058 {
9059 std::uint8_t len{};
9060 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9061 }
9062
9063 case 0xB9: // map (two-byte uint16_t for n follow)
9064 {
9065 std::uint16_t len{};
9066 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9067 }
9068
9069 case 0xBA: // map (four-byte uint32_t for n follow)
9070 {
9071 std::uint32_t len{};
9072 return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9073 }
9074
9075 case 0xBB: // map (eight-byte uint64_t for n follow)
9076 {
9077 std::uint64_t len{};
9078 return get_number(input_format_t::cbor, len) && get_cbor_object(detail::conditional_static_cast<std::size_t>(len), tag_handler);
9079 }
9080
9081 case 0xBF: // map (indefinite length)
9082 return get_cbor_object(std::size_t(-1), tag_handler);
9083
9084 case 0xC6: // tagged item
9085 case 0xC7:
9086 case 0xC8:
9087 case 0xC9:
9088 case 0xCA:
9089 case 0xCB:
9090 case 0xCC:
9091 case 0xCD:
9092 case 0xCE:
9093 case 0xCF:
9094 case 0xD0:
9095 case 0xD1:
9096 case 0xD2:
9097 case 0xD3:
9098 case 0xD4:
9099 case 0xD8: // tagged item (1 bytes follow)
9100 case 0xD9: // tagged item (2 bytes follow)
9101 case 0xDA: // tagged item (4 bytes follow)
9102 case 0xDB: // tagged item (8 bytes follow)
9103 {
9104 switch (tag_handler)
9105 {
9107 {
9108 auto last_token = get_token_string();
9109 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()));
9110 }
9111
9113 {
9114 // ignore binary subtype
9115 switch (current)
9116 {
9117 case 0xD8:
9118 {
9119 std::uint8_t subtype_to_ignore{};
9120 get_number(input_format_t::cbor, subtype_to_ignore);
9121 break;
9122 }
9123
9124 case 0xD9:
9125 {
9126 std::uint16_t subtype_to_ignore{};
9127 get_number(input_format_t::cbor, subtype_to_ignore);
9128 break;
9129 }
9130
9131 case 0xDA:
9132 {
9133 std::uint32_t subtype_to_ignore{};
9134 get_number(input_format_t::cbor, subtype_to_ignore);
9135 break;
9136 }
9137
9138 case 0xDB:
9139 {
9140 std::uint64_t subtype_to_ignore{};
9141 get_number(input_format_t::cbor, subtype_to_ignore);
9142 break;
9143 }
9144
9145 default:
9146 break;
9147 }
9148
9149 return parse_cbor_internal(true, tag_handler);
9150 }
9151
9153 {
9154 binary_t b;
9155
9156 // use binary subtype and store in binary container
9157 switch (current)
9158 {
9159 case 0xD8:
9160 {
9161 std::uint8_t subtype{};
9162 get_number(input_format_t::cbor, subtype);
9163 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9164 break;
9165 }
9166
9167 case 0xD9:
9168 {
9169 std::uint16_t subtype{};
9170 get_number(input_format_t::cbor, subtype);
9171 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9172 break;
9173 }
9174
9175 case 0xDA:
9176 {
9177 std::uint32_t subtype{};
9178 get_number(input_format_t::cbor, subtype);
9179 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9180 break;
9181 }
9182
9183 case 0xDB:
9184 {
9185 std::uint64_t subtype{};
9186 get_number(input_format_t::cbor, subtype);
9187 b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9188 break;
9189 }
9190
9191 default:
9192 return parse_cbor_internal(true, tag_handler);
9193 }
9194
9195 get();
9196 return get_cbor_binary(b) && sax->binary(b);
9197 }
9198
9199 default: // LCOV_EXCL_LINE
9200 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9201 return false; // LCOV_EXCL_LINE
9202 }
9203 }
9204
9205 case 0xF4: // false
9206 return sax->boolean(false);
9207
9208 case 0xF5: // true
9209 return sax->boolean(true);
9210
9211 case 0xF6: // null
9212 return sax->null();
9213
9214 case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9215 {
9216 const auto byte1_raw = get();
9217
9218 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9219 {
9220 return false;
9221 }
9222
9223 const auto byte2_raw = get();
9224
9225 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9226 {
9227 return false;
9228 }
9229
9230 const auto byte1 = static_cast<unsigned char>(byte1_raw);
9231 const auto byte2 = static_cast<unsigned char>(byte2_raw);
9232 // code from RFC 7049, Appendix D, Figure 3:
9233 // As half-precision floating-point numbers were only added
9234 // to IEEE 754 in 2008, today's programming platforms often
9235 // still only have limited support for them. It is very
9236 // easy to include at least decoding support for them even
9237 // without such support. An example of a small decoder for
9238 // half-precision floating-point numbers in the C language
9239 // is shown in Fig. 3.
9240 const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9241 const double val = [&half]
9242 {
9243 const int exp = (half >> 10u) & 0x1Fu;
9244 const unsigned int mant = half & 0x3FFu;
9245 JSON_ASSERT(0 <= exp &&exp <= 32);
9246 JSON_ASSERT(mant <= 1024);
9247
9248 switch (exp)
9249 {
9250 case 0:
9251 return std::ldexp(mant, -24);
9252
9253 case 31:
9254 return (mant == 0)
9255 ? std::numeric_limits<double>::infinity()
9256 : std::numeric_limits<double>::quiet_NaN();
9257
9258 default:
9259 return std::ldexp(mant + 1024, exp - 25);
9260 }
9261 }();
9262 return sax->number_float((half & 0x8000u) != 0
9263 ? static_cast<number_float_t>(-val)
9264 : static_cast<number_float_t>(val), "");
9265 }
9266
9267 case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9268 {
9269 float number{};
9270 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9271 }
9272
9273 case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9274 {
9275 double number{};
9276 return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9277 }
9278
9279 default: // anything else (0xFF is handled inside the other types)
9280 {
9281 auto last_token = get_token_string();
9282 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()));
9283 }
9284 }
9285 }
9286
9298 bool get_cbor_string(string_t &result)
9299 {
9300 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9301 {
9302 return false;
9303 }
9304
9305 switch (current)
9306 {
9307 // UTF-8 string (0x00..0x17 bytes follow)
9308 case 0x60:
9309 case 0x61:
9310 case 0x62:
9311 case 0x63:
9312 case 0x64:
9313 case 0x65:
9314 case 0x66:
9315 case 0x67:
9316 case 0x68:
9317 case 0x69:
9318 case 0x6A:
9319 case 0x6B:
9320 case 0x6C:
9321 case 0x6D:
9322 case 0x6E:
9323 case 0x6F:
9324 case 0x70:
9325 case 0x71:
9326 case 0x72:
9327 case 0x73:
9328 case 0x74:
9329 case 0x75:
9330 case 0x76:
9331 case 0x77:
9332 {
9333 return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9334 }
9335
9336 case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9337 {
9338 std::uint8_t len{};
9339 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9340 }
9341
9342 case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9343 {
9344 std::uint16_t len{};
9345 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9346 }
9347
9348 case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9349 {
9350 std::uint32_t len{};
9351 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9352 }
9353
9354 case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9355 {
9356 std::uint64_t len{};
9357 return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9358 }
9359
9360 case 0x7F: // UTF-8 string (indefinite length)
9361 {
9362 while (get() != 0xFF)
9363 {
9364 string_t chunk;
9365
9366 if (!get_cbor_string(chunk))
9367 {
9368 return false;
9369 }
9370
9371 result.append(chunk);
9372 }
9373
9374 return true;
9375 }
9376
9377 default:
9378 {
9379 auto last_token = get_token_string();
9380 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()));
9381 }
9382 }
9383 }
9384
9396 bool get_cbor_binary(binary_t &result)
9397 {
9398 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
9399 {
9400 return false;
9401 }
9402
9403 switch (current)
9404 {
9405 // Binary data (0x00..0x17 bytes follow)
9406 case 0x40:
9407 case 0x41:
9408 case 0x42:
9409 case 0x43:
9410 case 0x44:
9411 case 0x45:
9412 case 0x46:
9413 case 0x47:
9414 case 0x48:
9415 case 0x49:
9416 case 0x4A:
9417 case 0x4B:
9418 case 0x4C:
9419 case 0x4D:
9420 case 0x4E:
9421 case 0x4F:
9422 case 0x50:
9423 case 0x51:
9424 case 0x52:
9425 case 0x53:
9426 case 0x54:
9427 case 0x55:
9428 case 0x56:
9429 case 0x57:
9430 {
9431 return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9432 }
9433
9434 case 0x58: // Binary data (one-byte uint8_t for n follows)
9435 {
9436 std::uint8_t len{};
9437 return get_number(input_format_t::cbor, len) &&
9438 get_binary(input_format_t::cbor, len, result);
9439 }
9440
9441 case 0x59: // Binary data (two-byte uint16_t for n follow)
9442 {
9443 std::uint16_t len{};
9444 return get_number(input_format_t::cbor, len) &&
9445 get_binary(input_format_t::cbor, len, result);
9446 }
9447
9448 case 0x5A: // Binary data (four-byte uint32_t for n follow)
9449 {
9450 std::uint32_t len{};
9451 return get_number(input_format_t::cbor, len) &&
9452 get_binary(input_format_t::cbor, len, result);
9453 }
9454
9455 case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9456 {
9457 std::uint64_t len{};
9458 return get_number(input_format_t::cbor, len) &&
9459 get_binary(input_format_t::cbor, len, result);
9460 }
9461
9462 case 0x5F: // Binary data (indefinite length)
9463 {
9464 while (get() != 0xFF)
9465 {
9466 binary_t chunk;
9467
9468 if (!get_cbor_binary(chunk))
9469 {
9470 return false;
9471 }
9472
9473 result.insert(result.end(), chunk.begin(), chunk.end());
9474 }
9475
9476 return true;
9477 }
9478
9479 default:
9480 {
9481 auto last_token = get_token_string();
9482 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()));
9483 }
9484 }
9485 }
9486
9493 bool get_cbor_array(const std::size_t len,
9494 const cbor_tag_handler_t tag_handler)
9495 {
9496 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9497 {
9498 return false;
9499 }
9500
9501 if (len != std::size_t(-1))
9502 {
9503 for (std::size_t i = 0; i < len; ++i)
9504 {
9505 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9506 {
9507 return false;
9508 }
9509 }
9510 }
9511
9512 else
9513 {
9514 while (get() != 0xFF)
9515 {
9516 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9517 {
9518 return false;
9519 }
9520 }
9521 }
9522
9523 return sax->end_array();
9524 }
9525
9532 bool get_cbor_object(const std::size_t len,
9533 const cbor_tag_handler_t tag_handler)
9534 {
9535 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9536 {
9537 return false;
9538 }
9539
9540 if (len != 0)
9541 {
9542 string_t key;
9543
9544 if (len != std::size_t(-1))
9545 {
9546 for (std::size_t i = 0; i < len; ++i)
9547 {
9548 get();
9549
9550 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9551 {
9552 return false;
9553 }
9554
9555 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9556 {
9557 return false;
9558 }
9559
9560 key.clear();
9561 }
9562 }
9563
9564 else
9565 {
9566 while (get() != 0xFF)
9567 {
9568 if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9569 {
9570 return false;
9571 }
9572
9573 if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9574 {
9575 return false;
9576 }
9577
9578 key.clear();
9579 }
9580 }
9581 }
9582
9583 return sax->end_object();
9584 }
9585
9587 // MsgPack //
9589
9594 {
9595 switch (get())
9596 {
9597 // EOF
9598 case std::char_traits<char_type>::eof():
9599 return unexpect_eof(input_format_t::msgpack, "value");
9600
9601 // positive fixint
9602 case 0x00:
9603 case 0x01:
9604 case 0x02:
9605 case 0x03:
9606 case 0x04:
9607 case 0x05:
9608 case 0x06:
9609 case 0x07:
9610 case 0x08:
9611 case 0x09:
9612 case 0x0A:
9613 case 0x0B:
9614 case 0x0C:
9615 case 0x0D:
9616 case 0x0E:
9617 case 0x0F:
9618 case 0x10:
9619 case 0x11:
9620 case 0x12:
9621 case 0x13:
9622 case 0x14:
9623 case 0x15:
9624 case 0x16:
9625 case 0x17:
9626 case 0x18:
9627 case 0x19:
9628 case 0x1A:
9629 case 0x1B:
9630 case 0x1C:
9631 case 0x1D:
9632 case 0x1E:
9633 case 0x1F:
9634 case 0x20:
9635 case 0x21:
9636 case 0x22:
9637 case 0x23:
9638 case 0x24:
9639 case 0x25:
9640 case 0x26:
9641 case 0x27:
9642 case 0x28:
9643 case 0x29:
9644 case 0x2A:
9645 case 0x2B:
9646 case 0x2C:
9647 case 0x2D:
9648 case 0x2E:
9649 case 0x2F:
9650 case 0x30:
9651 case 0x31:
9652 case 0x32:
9653 case 0x33:
9654 case 0x34:
9655 case 0x35:
9656 case 0x36:
9657 case 0x37:
9658 case 0x38:
9659 case 0x39:
9660 case 0x3A:
9661 case 0x3B:
9662 case 0x3C:
9663 case 0x3D:
9664 case 0x3E:
9665 case 0x3F:
9666 case 0x40:
9667 case 0x41:
9668 case 0x42:
9669 case 0x43:
9670 case 0x44:
9671 case 0x45:
9672 case 0x46:
9673 case 0x47:
9674 case 0x48:
9675 case 0x49:
9676 case 0x4A:
9677 case 0x4B:
9678 case 0x4C:
9679 case 0x4D:
9680 case 0x4E:
9681 case 0x4F:
9682 case 0x50:
9683 case 0x51:
9684 case 0x52:
9685 case 0x53:
9686 case 0x54:
9687 case 0x55:
9688 case 0x56:
9689 case 0x57:
9690 case 0x58:
9691 case 0x59:
9692 case 0x5A:
9693 case 0x5B:
9694 case 0x5C:
9695 case 0x5D:
9696 case 0x5E:
9697 case 0x5F:
9698 case 0x60:
9699 case 0x61:
9700 case 0x62:
9701 case 0x63:
9702 case 0x64:
9703 case 0x65:
9704 case 0x66:
9705 case 0x67:
9706 case 0x68:
9707 case 0x69:
9708 case 0x6A:
9709 case 0x6B:
9710 case 0x6C:
9711 case 0x6D:
9712 case 0x6E:
9713 case 0x6F:
9714 case 0x70:
9715 case 0x71:
9716 case 0x72:
9717 case 0x73:
9718 case 0x74:
9719 case 0x75:
9720 case 0x76:
9721 case 0x77:
9722 case 0x78:
9723 case 0x79:
9724 case 0x7A:
9725 case 0x7B:
9726 case 0x7C:
9727 case 0x7D:
9728 case 0x7E:
9729 case 0x7F:
9730 return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9731
9732 // fixmap
9733 case 0x80:
9734 case 0x81:
9735 case 0x82:
9736 case 0x83:
9737 case 0x84:
9738 case 0x85:
9739 case 0x86:
9740 case 0x87:
9741 case 0x88:
9742 case 0x89:
9743 case 0x8A:
9744 case 0x8B:
9745 case 0x8C:
9746 case 0x8D:
9747 case 0x8E:
9748 case 0x8F:
9749 return get_msgpack_object(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9750
9751 // fixarray
9752 case 0x90:
9753 case 0x91:
9754 case 0x92:
9755 case 0x93:
9756 case 0x94:
9757 case 0x95:
9758 case 0x96:
9759 case 0x97:
9760 case 0x98:
9761 case 0x99:
9762 case 0x9A:
9763 case 0x9B:
9764 case 0x9C:
9765 case 0x9D:
9766 case 0x9E:
9767 case 0x9F:
9768 return get_msgpack_array(static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
9769
9770 // fixstr
9771 case 0xA0:
9772 case 0xA1:
9773 case 0xA2:
9774 case 0xA3:
9775 case 0xA4:
9776 case 0xA5:
9777 case 0xA6:
9778 case 0xA7:
9779 case 0xA8:
9780 case 0xA9:
9781 case 0xAA:
9782 case 0xAB:
9783 case 0xAC:
9784 case 0xAD:
9785 case 0xAE:
9786 case 0xAF:
9787 case 0xB0:
9788 case 0xB1:
9789 case 0xB2:
9790 case 0xB3:
9791 case 0xB4:
9792 case 0xB5:
9793 case 0xB6:
9794 case 0xB7:
9795 case 0xB8:
9796 case 0xB9:
9797 case 0xBA:
9798 case 0xBB:
9799 case 0xBC:
9800 case 0xBD:
9801 case 0xBE:
9802 case 0xBF:
9803 case 0xD9: // str 8
9804 case 0xDA: // str 16
9805 case 0xDB: // str 32
9806 {
9807 string_t s;
9808 return get_msgpack_string(s) && sax->string(s);
9809 }
9810
9811 case 0xC0: // nil
9812 return sax->null();
9813
9814 case 0xC2: // false
9815 return sax->boolean(false);
9816
9817 case 0xC3: // true
9818 return sax->boolean(true);
9819
9820 case 0xC4: // bin 8
9821 case 0xC5: // bin 16
9822 case 0xC6: // bin 32
9823 case 0xC7: // ext 8
9824 case 0xC8: // ext 16
9825 case 0xC9: // ext 32
9826 case 0xD4: // fixext 1
9827 case 0xD5: // fixext 2
9828 case 0xD6: // fixext 4
9829 case 0xD7: // fixext 8
9830 case 0xD8: // fixext 16
9831 {
9832 binary_t b;
9833 return get_msgpack_binary(b) && sax->binary(b);
9834 }
9835
9836 case 0xCA: // float 32
9837 {
9838 float number{};
9839 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9840 }
9841
9842 case 0xCB: // float 64
9843 {
9844 double number{};
9845 return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
9846 }
9847
9848 case 0xCC: // uint 8
9849 {
9850 std::uint8_t number{};
9851 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9852 }
9853
9854 case 0xCD: // uint 16
9855 {
9856 std::uint16_t number{};
9857 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9858 }
9859
9860 case 0xCE: // uint 32
9861 {
9862 std::uint32_t number{};
9863 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9864 }
9865
9866 case 0xCF: // uint 64
9867 {
9868 std::uint64_t number{};
9869 return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
9870 }
9871
9872 case 0xD0: // int 8
9873 {
9874 std::int8_t number{};
9875 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9876 }
9877
9878 case 0xD1: // int 16
9879 {
9880 std::int16_t number{};
9881 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9882 }
9883
9884 case 0xD2: // int 32
9885 {
9886 std::int32_t number{};
9887 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9888 }
9889
9890 case 0xD3: // int 64
9891 {
9892 std::int64_t number{};
9893 return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
9894 }
9895
9896 case 0xDC: // array 16
9897 {
9898 std::uint16_t len{};
9899 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9900 }
9901
9902 case 0xDD: // array 32
9903 {
9904 std::uint32_t len{};
9905 return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
9906 }
9907
9908 case 0xDE: // map 16
9909 {
9910 std::uint16_t len{};
9911 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9912 }
9913
9914 case 0xDF: // map 32
9915 {
9916 std::uint32_t len{};
9917 return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
9918 }
9919
9920 // negative fixint
9921 case 0xE0:
9922 case 0xE1:
9923 case 0xE2:
9924 case 0xE3:
9925 case 0xE4:
9926 case 0xE5:
9927 case 0xE6:
9928 case 0xE7:
9929 case 0xE8:
9930 case 0xE9:
9931 case 0xEA:
9932 case 0xEB:
9933 case 0xEC:
9934 case 0xED:
9935 case 0xEE:
9936 case 0xEF:
9937 case 0xF0:
9938 case 0xF1:
9939 case 0xF2:
9940 case 0xF3:
9941 case 0xF4:
9942 case 0xF5:
9943 case 0xF6:
9944 case 0xF7:
9945 case 0xF8:
9946 case 0xF9:
9947 case 0xFA:
9948 case 0xFB:
9949 case 0xFC:
9950 case 0xFD:
9951 case 0xFE:
9952 case 0xFF:
9953 return sax->number_integer(static_cast<std::int8_t>(current));
9954
9955 default: // anything else
9956 {
9957 auto last_token = get_token_string();
9958 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()));
9959 }
9960 }
9961 }
9962
9973 bool get_msgpack_string(string_t &result)
9974 {
9975 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
9976 {
9977 return false;
9978 }
9979
9980 switch (current)
9981 {
9982 // fixstr
9983 case 0xA0:
9984 case 0xA1:
9985 case 0xA2:
9986 case 0xA3:
9987 case 0xA4:
9988 case 0xA5:
9989 case 0xA6:
9990 case 0xA7:
9991 case 0xA8:
9992 case 0xA9:
9993 case 0xAA:
9994 case 0xAB:
9995 case 0xAC:
9996 case 0xAD:
9997 case 0xAE:
9998 case 0xAF:
9999 case 0xB0:
10000 case 0xB1:
10001 case 0xB2:
10002 case 0xB3:
10003 case 0xB4:
10004 case 0xB5:
10005 case 0xB6:
10006 case 0xB7:
10007 case 0xB8:
10008 case 0xB9:
10009 case 0xBA:
10010 case 0xBB:
10011 case 0xBC:
10012 case 0xBD:
10013 case 0xBE:
10014 case 0xBF:
10015 {
10016 return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
10017 }
10018
10019 case 0xD9: // str 8
10020 {
10021 std::uint8_t len{};
10022 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10023 }
10024
10025 case 0xDA: // str 16
10026 {
10027 std::uint16_t len{};
10028 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10029 }
10030
10031 case 0xDB: // str 32
10032 {
10033 std::uint32_t len{};
10034 return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10035 }
10036
10037 default:
10038 {
10039 auto last_token = get_token_string();
10040 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()));
10041 }
10042 }
10043 }
10044
10055 bool get_msgpack_binary(binary_t &result)
10056 {
10057 // helper function to set the subtype
10058 auto assign_and_return_true = [&result](std::int8_t subtype)
10059 {
10060 result.set_subtype(static_cast<std::uint8_t>(subtype));
10061 return true;
10062 };
10063
10064 switch (current)
10065 {
10066 case 0xC4: // bin 8
10067 {
10068 std::uint8_t len{};
10069 return get_number(input_format_t::msgpack, len) &&
10070 get_binary(input_format_t::msgpack, len, result);
10071 }
10072
10073 case 0xC5: // bin 16
10074 {
10075 std::uint16_t len{};
10076 return get_number(input_format_t::msgpack, len) &&
10077 get_binary(input_format_t::msgpack, len, result);
10078 }
10079
10080 case 0xC6: // bin 32
10081 {
10082 std::uint32_t len{};
10083 return get_number(input_format_t::msgpack, len) &&
10084 get_binary(input_format_t::msgpack, len, result);
10085 }
10086
10087 case 0xC7: // ext 8
10088 {
10089 std::uint8_t len{};
10090 std::int8_t subtype{};
10091 return get_number(input_format_t::msgpack, len) &&
10092 get_number(input_format_t::msgpack, subtype) &&
10093 get_binary(input_format_t::msgpack, len, result) &&
10094 assign_and_return_true(subtype);
10095 }
10096
10097 case 0xC8: // ext 16
10098 {
10099 std::uint16_t len{};
10100 std::int8_t subtype{};
10101 return get_number(input_format_t::msgpack, len) &&
10102 get_number(input_format_t::msgpack, subtype) &&
10103 get_binary(input_format_t::msgpack, len, result) &&
10104 assign_and_return_true(subtype);
10105 }
10106
10107 case 0xC9: // ext 32
10108 {
10109 std::uint32_t len{};
10110 std::int8_t subtype{};
10111 return get_number(input_format_t::msgpack, len) &&
10112 get_number(input_format_t::msgpack, subtype) &&
10113 get_binary(input_format_t::msgpack, len, result) &&
10114 assign_and_return_true(subtype);
10115 }
10116
10117 case 0xD4: // fixext 1
10118 {
10119 std::int8_t subtype{};
10120 return get_number(input_format_t::msgpack, subtype) &&
10121 get_binary(input_format_t::msgpack, 1, result) &&
10122 assign_and_return_true(subtype);
10123 }
10124
10125 case 0xD5: // fixext 2
10126 {
10127 std::int8_t subtype{};
10128 return get_number(input_format_t::msgpack, subtype) &&
10129 get_binary(input_format_t::msgpack, 2, result) &&
10130 assign_and_return_true(subtype);
10131 }
10132
10133 case 0xD6: // fixext 4
10134 {
10135 std::int8_t subtype{};
10136 return get_number(input_format_t::msgpack, subtype) &&
10137 get_binary(input_format_t::msgpack, 4, result) &&
10138 assign_and_return_true(subtype);
10139 }
10140
10141 case 0xD7: // fixext 8
10142 {
10143 std::int8_t subtype{};
10144 return get_number(input_format_t::msgpack, subtype) &&
10145 get_binary(input_format_t::msgpack, 8, result) &&
10146 assign_and_return_true(subtype);
10147 }
10148
10149 case 0xD8: // fixext 16
10150 {
10151 std::int8_t subtype{};
10152 return get_number(input_format_t::msgpack, subtype) &&
10153 get_binary(input_format_t::msgpack, 16, result) &&
10154 assign_and_return_true(subtype);
10155 }
10156
10157 default: // LCOV_EXCL_LINE
10158 return false; // LCOV_EXCL_LINE
10159 }
10160 }
10161
10166 bool get_msgpack_array(const std::size_t len)
10167 {
10168 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10169 {
10170 return false;
10171 }
10172
10173 for (std::size_t i = 0; i < len; ++i)
10174 {
10175 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10176 {
10177 return false;
10178 }
10179 }
10180
10181 return sax->end_array();
10182 }
10183
10188 bool get_msgpack_object(const std::size_t len)
10189 {
10190 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10191 {
10192 return false;
10193 }
10194
10195 string_t key;
10196
10197 for (std::size_t i = 0; i < len; ++i)
10198 {
10199 get();
10200
10201 if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10202 {
10203 return false;
10204 }
10205
10206 if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10207 {
10208 return false;
10209 }
10210
10211 key.clear();
10212 }
10213
10214 return sax->end_object();
10215 }
10216
10218 // UBJSON //
10220
10228 bool parse_ubjson_internal(const bool get_char = true)
10229 {
10230 return get_ubjson_value(get_char ? get_ignore_noop() : current);
10231 }
10232
10247 bool get_ubjson_string(string_t &result, const bool get_char = true)
10248 {
10249 if (get_char)
10250 {
10251 get(); // TODO(niels): may we ignore N here?
10252 }
10253
10254 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10255 {
10256 return false;
10257 }
10258
10259 switch (current)
10260 {
10261 case 'U':
10262 {
10263 std::uint8_t len{};
10264 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10265 }
10266
10267 case 'i':
10268 {
10269 std::int8_t len{};
10270 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10271 }
10272
10273 case 'I':
10274 {
10275 std::int16_t len{};
10276 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10277 }
10278
10279 case 'l':
10280 {
10281 std::int32_t len{};
10282 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10283 }
10284
10285 case 'L':
10286 {
10287 std::int64_t len{};
10288 return get_number(input_format_t::ubjson, len) && get_string(input_format_t::ubjson, len, result);
10289 }
10290
10291 default:
10292 auto last_token = get_token_string();
10293 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()));
10294 }
10295 }
10296
10301 bool get_ubjson_size_value(std::size_t &result)
10302 {
10303 switch (get_ignore_noop())
10304 {
10305 case 'U':
10306 {
10307 std::uint8_t number{};
10308
10309 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10310 {
10311 return false;
10312 }
10313
10314 result = static_cast<std::size_t>(number);
10315 return true;
10316 }
10317
10318 case 'i':
10319 {
10320 std::int8_t number{};
10321
10322 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10323 {
10324 return false;
10325 }
10326
10327 result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10328 return true;
10329 }
10330
10331 case 'I':
10332 {
10333 std::int16_t number{};
10334
10335 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10336 {
10337 return false;
10338 }
10339
10340 result = static_cast<std::size_t>(number);
10341 return true;
10342 }
10343
10344 case 'l':
10345 {
10346 std::int32_t number{};
10347
10348 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10349 {
10350 return false;
10351 }
10352
10353 result = static_cast<std::size_t>(number);
10354 return true;
10355 }
10356
10357 case 'L':
10358 {
10359 std::int64_t number{};
10360
10361 if (JSON_HEDLEY_UNLIKELY(!get_number(input_format_t::ubjson, number)))
10362 {
10363 return false;
10364 }
10365
10366 result = static_cast<std::size_t>(number);
10367 return true;
10368 }
10369
10370 default:
10371 {
10372 auto last_token = get_token_string();
10373 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()));
10374 }
10375 }
10376 }
10377
10388 bool get_ubjson_size_type(std::pair<std::size_t, char_int_type> &result)
10389 {
10390 result.first = string_t::npos; // size
10391 result.second = 0; // type
10393
10394 if (current == '$')
10395 {
10396 result.second = get(); // must not ignore 'N', because 'N' maybe the type
10397
10398 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "type")))
10399 {
10400 return false;
10401 }
10402
10404
10405 if (JSON_HEDLEY_UNLIKELY(current != '#'))
10406 {
10407 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "value")))
10408 {
10409 return false;
10410 }
10411
10412 auto last_token = get_token_string();
10413 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()));
10414 }
10415
10416 return get_ubjson_size_value(result.first);
10417 }
10418
10419 if (current == '#')
10420 {
10421 return get_ubjson_size_value(result.first);
10422 }
10423
10424 return true;
10425 }
10426
10431 bool get_ubjson_value(const char_int_type prefix)
10432 {
10433 switch (prefix)
10434 {
10435 case std::char_traits<char_type>::eof(): // EOF
10436 return unexpect_eof(input_format_t::ubjson, "value");
10437
10438 case 'T': // true
10439 return sax->boolean(true);
10440
10441 case 'F': // false
10442 return sax->boolean(false);
10443
10444 case 'Z': // null
10445 return sax->null();
10446
10447 case 'U':
10448 {
10449 std::uint8_t number{};
10450 return get_number(input_format_t::ubjson, number) && sax->number_unsigned(number);
10451 }
10452
10453 case 'i':
10454 {
10455 std::int8_t number{};
10456 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10457 }
10458
10459 case 'I':
10460 {
10461 std::int16_t number{};
10462 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10463 }
10464
10465 case 'l':
10466 {
10467 std::int32_t number{};
10468 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10469 }
10470
10471 case 'L':
10472 {
10473 std::int64_t number{};
10474 return get_number(input_format_t::ubjson, number) && sax->number_integer(number);
10475 }
10476
10477 case 'd':
10478 {
10479 float number{};
10480 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10481 }
10482
10483 case 'D':
10484 {
10485 double number{};
10486 return get_number(input_format_t::ubjson, number) && sax->number_float(static_cast<number_float_t>(number), "");
10487 }
10488
10489 case 'H':
10490 {
10491 return get_ubjson_high_precision_number();
10492 }
10493
10494 case 'C': // char
10495 {
10496 get();
10497
10498 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "char")))
10499 {
10500 return false;
10501 }
10502
10503 if (JSON_HEDLEY_UNLIKELY(current > 127))
10504 {
10505 auto last_token = get_token_string();
10506 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()));
10507 }
10508
10509 string_t s(1, static_cast<typename string_t::value_type>(current));
10510 return sax->string(s);
10511 }
10512
10513 case 'S': // string
10514 {
10515 string_t s;
10516 return get_ubjson_string(s) && sax->string(s);
10517 }
10518
10519 case '[': // array
10520 return get_ubjson_array();
10521
10522 case '{': // object
10523 return get_ubjson_object();
10524
10525 default: // anything else
10526 {
10527 auto last_token = get_token_string();
10528 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()));
10529 }
10530 }
10531 }
10532
10537 {
10538 std::pair<std::size_t, char_int_type> size_and_type;
10539
10540 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10541 {
10542 return false;
10543 }
10544
10545 if (size_and_type.first != string_t::npos)
10546 {
10547 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
10548 {
10549 return false;
10550 }
10551
10552 if (size_and_type.second != 0)
10553 {
10554 if (size_and_type.second != 'N')
10555 {
10556 for (std::size_t i = 0; i < size_and_type.first; ++i)
10557 {
10558 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10559 {
10560 return false;
10561 }
10562 }
10563 }
10564 }
10565
10566 else
10567 {
10568 for (std::size_t i = 0; i < size_and_type.first; ++i)
10569 {
10570 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10571 {
10572 return false;
10573 }
10574 }
10575 }
10576 }
10577
10578 else
10579 {
10580 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
10581 {
10582 return false;
10583 }
10584
10585 while (current != ']')
10586 {
10587 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
10588 {
10589 return false;
10590 }
10591
10593 }
10594 }
10595
10596 return sax->end_array();
10597 }
10598
10603 {
10604 std::pair<std::size_t, char_int_type> size_and_type;
10605
10606 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
10607 {
10608 return false;
10609 }
10610
10611 string_t key;
10612
10613 if (size_and_type.first != string_t::npos)
10614 {
10615 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
10616 {
10617 return false;
10618 }
10619
10620 if (size_and_type.second != 0)
10621 {
10622 for (std::size_t i = 0; i < size_and_type.first; ++i)
10623 {
10624 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10625 {
10626 return false;
10627 }
10628
10629 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
10630 {
10631 return false;
10632 }
10633
10634 key.clear();
10635 }
10636 }
10637
10638 else
10639 {
10640 for (std::size_t i = 0; i < size_and_type.first; ++i)
10641 {
10642 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
10643 {
10644 return false;
10645 }
10646
10647 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10648 {
10649 return false;
10650 }
10651
10652 key.clear();
10653 }
10654 }
10655 }
10656
10657 else
10658 {
10659 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
10660 {
10661 return false;
10662 }
10663
10664 while (current != '}')
10665 {
10666 if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
10667 {
10668 return false;
10669 }
10670
10671 if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
10672 {
10673 return false;
10674 }
10675
10677 key.clear();
10678 }
10679 }
10680
10681 return sax->end_object();
10682 }
10683
10684 // Note, no reader for UBJSON binary types is implemented because they do
10685 // not exist
10686
10687 bool get_ubjson_high_precision_number()
10688 {
10689 // get size of following number string
10690 std::size_t size{};
10691 auto res = get_ubjson_size_value(size);
10692
10693 if (JSON_HEDLEY_UNLIKELY(!res))
10694 {
10695 return res;
10696 }
10697
10698 // get number string
10699 std::vector<char> number_vector;
10700
10701 for (std::size_t i = 0; i < size; ++i)
10702 {
10703 get();
10704
10705 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::ubjson, "number")))
10706 {
10707 return false;
10708 }
10709
10710 number_vector.push_back(static_cast<char>(current));
10711 }
10712
10713 // parse number string
10714 using ia_type = decltype(detail::input_adapter(number_vector));
10715 auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
10716 const auto result_number = number_lexer.scan();
10717 const auto number_string = number_lexer.get_token_string();
10718 const auto result_remainder = number_lexer.scan();
10719 using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
10720
10721 if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
10722 {
10723 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()));
10724 }
10725
10726 switch (result_number)
10727 {
10728 case token_type::value_integer:
10729 return sax->number_integer(number_lexer.get_number_integer());
10730
10731 case token_type::value_unsigned:
10732 return sax->number_unsigned(number_lexer.get_number_unsigned());
10733
10734 case token_type::value_float:
10735 return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
10736
10737 case token_type::uninitialized:
10738 case token_type::literal_true:
10739 case token_type::literal_false:
10740 case token_type::literal_null:
10741 case token_type::value_string:
10742 case token_type::begin_array:
10743 case token_type::begin_object:
10744 case token_type::end_array:
10745 case token_type::end_object:
10746 case token_type::name_separator:
10747 case token_type::value_separator:
10748 case token_type::parse_error:
10749 case token_type::end_of_input:
10750 case token_type::literal_or_value:
10751 default:
10752 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()));
10753 }
10754 }
10755
10757 // Utility functions //
10759
10769 char_int_type get()
10770 {
10771 ++chars_read;
10772 return current = ia.get_character();
10773 }
10774
10778 char_int_type get_ignore_noop()
10779 {
10780 do
10781 {
10782 get();
10783 }
10784 while (current == 'N');
10785
10786 return current;
10787 }
10788
10789 /*
10790 @brief read a number from the input
10791
10792 @tparam NumberType the type of the number
10793 @param[in] format the current format (for diagnostics)
10794 @param[out] result number of type @a NumberType
10795
10796 @return whether conversion completed
10797
10798 @note This function needs to respect the system's endianess, because
10799 bytes in CBOR, MessagePack, and UBJSON are stored in network order
10800 (big endian) and therefore need reordering on little endian systems.
10801 */
10802 template<typename NumberType, bool InputIsLittleEndian = false>
10803 bool get_number(const input_format_t format, NumberType &result)
10804 {
10805 // step 1: read input into array with system's byte order
10806 std::array<std::uint8_t, sizeof(NumberType)> vec{};
10807
10808 for (std::size_t i = 0; i < sizeof(NumberType); ++i)
10809 {
10810 get();
10811
10812 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
10813 {
10814 return false;
10815 }
10816
10817 // reverse byte order prior to conversion if necessary
10818 if (is_little_endian != InputIsLittleEndian)
10819 {
10820 vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
10821 }
10822
10823 else
10824 {
10825 vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
10826 }
10827 }
10828
10829 // step 2: convert array into number of type T and return
10830 std::memcpy(&result, vec.data(), sizeof(NumberType));
10831 return true;
10832 }
10833
10848 template<typename NumberType>
10849 bool get_string(const input_format_t format,
10850 const NumberType len,
10851 string_t &result)
10852 {
10853 bool success = true;
10854
10855 for (NumberType i = 0; i < len; i++)
10856 {
10857 get();
10858
10859 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
10860 {
10861 success = false;
10862 break;
10863 }
10864
10865 result.push_back(static_cast<typename string_t::value_type>(current));
10866 }
10867
10868 return success;
10869 }
10870
10885 template<typename NumberType>
10886 bool get_binary(const input_format_t format,
10887 const NumberType len,
10888 binary_t &result)
10889 {
10890 bool success = true;
10891
10892 for (NumberType i = 0; i < len; i++)
10893 {
10894 get();
10895
10896 if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
10897 {
10898 success = false;
10899 break;
10900 }
10901
10902 result.push_back(static_cast<std::uint8_t>(current));
10903 }
10904
10905 return success;
10906 }
10907
10913 JSON_HEDLEY_NON_NULL(3)
10914 bool unexpect_eof(const input_format_t format, const char *context) const
10915 {
10916 if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
10917 {
10918 return sax->parse_error(chars_read, "<end of file>",
10919 parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), BasicJsonType()));
10920 }
10921
10922 return true;
10923 }
10924
10928 std::string get_token_string() const
10929 {
10930 std::array<char, 3> cr{{}};
10931 (std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current)); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
10932 return std::string{cr.data()};
10933 }
10934
10941 std::string exception_message(const input_format_t format,
10942 const std::string &detail,
10943 const std::string &context) const
10944 {
10945 std::string error_msg = "syntax error while parsing ";
10946
10947 switch (format)
10948 {
10949 case input_format_t::cbor:
10950 error_msg += "CBOR";
10951 break;
10952
10953 case input_format_t::msgpack:
10954 error_msg += "MessagePack";
10955 break;
10956
10957 case input_format_t::ubjson:
10958 error_msg += "UBJSON";
10959 break;
10960
10961 case input_format_t::bson:
10962 error_msg += "BSON";
10963 break;
10964
10965 case input_format_t::json: // LCOV_EXCL_LINE
10966 default: // LCOV_EXCL_LINE
10967 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
10968 }
10969
10970 return error_msg + " " + context + ": " + detail;
10971 }
10972
10973private:
10975 InputAdapterType ia;
10976
10978 char_int_type current = std::char_traits<char_type>::eof();
10979
10981 std::size_t chars_read = 0;
10982
10985
10987 json_sax_t *sax = nullptr;
10988};
10989} // namespace detail
10990} // namespace nlohmann
10991
10992// #include <nlohmann/detail/input/input_adapters.hpp>
10993
10994// #include <nlohmann/detail/input/lexer.hpp>
10995
10996// #include <nlohmann/detail/input/parser.hpp>
10997
10998
10999#include <cmath> // isfinite
11000#include <cstdint> // uint8_t
11001#include <functional> // function
11002#include <string> // string
11003#include <utility> // move
11004#include <vector> // vector
11005
11006// #include <nlohmann/detail/exceptions.hpp>
11007
11008// #include <nlohmann/detail/input/input_adapters.hpp>
11009
11010// #include <nlohmann/detail/input/json_sax.hpp>
11011
11012// #include <nlohmann/detail/input/lexer.hpp>
11013
11014// #include <nlohmann/detail/macro_scope.hpp>
11015
11016// #include <nlohmann/detail/meta/is_sax.hpp>
11017
11018// #include <nlohmann/detail/value_t.hpp>
11019
11020
11021namespace nlohmann
11022{
11023namespace detail
11024{
11026// parser //
11028
11029enum class parse_event_t : std::uint8_t
11030{
11034 object_end,
11038 array_end,
11040 key,
11042 value
11043};
11044
11045template<typename BasicJsonType>
11046using parser_callback_t =
11047 std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType & /*parsed*/)>;
11048
11054template<typename BasicJsonType, typename InputAdapterType>
11056{
11057 using number_integer_t = typename BasicJsonType::number_integer_t;
11058 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
11059 using number_float_t = typename BasicJsonType::number_float_t;
11060 using string_t = typename BasicJsonType::string_t;
11062 using token_type = typename lexer_t::token_type;
11063
11064public:
11066 explicit parser(InputAdapterType &&adapter,
11067 const parser_callback_t<BasicJsonType> cb = nullptr,
11068 const bool allow_exceptions_ = true,
11069 const bool skip_comments = false)
11070 : callback(cb)
11071 , m_lexer(std::move(adapter), skip_comments)
11072 , allow_exceptions(allow_exceptions_)
11073 {
11074 // read first token
11075 get_token();
11076 }
11077
11088 void parse(const bool strict, BasicJsonType &result)
11089 {
11090 if (callback)
11091 {
11093 sax_parse_internal(&sdp);
11094
11095 // in strict mode, input must be completely read
11096 if (strict && (get_token() != token_type::end_of_input))
11097 {
11098 sdp.parse_error(m_lexer.get_position(),
11101 exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11102 }
11103
11104 // in case of an error, return discarded value
11105 if (sdp.is_errored())
11106 {
11107 result = value_t::discarded;
11108 return;
11109 }
11110
11111 // set top-level value to null if it was discarded by the callback
11112 // function
11113 if (result.is_discarded())
11114 {
11115 result = nullptr;
11116 }
11117 }
11118
11119 else
11120 {
11122 sax_parse_internal(&sdp);
11123
11124 // in strict mode, input must be completely read
11125 if (strict && (get_token() != token_type::end_of_input))
11126 {
11127 sdp.parse_error(m_lexer.get_position(),
11129 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11130 }
11131
11132 // in case of an error, return discarded value
11133 if (sdp.is_errored())
11134 {
11135 result = value_t::discarded;
11136 return;
11137 }
11138 }
11139
11140 result.assert_invariant();
11141 }
11142
11149 bool accept(const bool strict = true)
11150 {
11152 return sax_parse(&sax_acceptor, strict);
11153 }
11154
11155 template<typename SAX>
11156 JSON_HEDLEY_NON_NULL(2)
11157 bool sax_parse(SAX *sax, const bool strict = true)
11158 {
11160 const bool result = sax_parse_internal(sax);
11161
11162 // strict mode: next byte must be EOF
11163 if (result && strict && (get_token() != token_type::end_of_input))
11164 {
11165 return sax->parse_error(m_lexer.get_position(),
11167 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), BasicJsonType()));
11168 }
11169
11170 return result;
11171 }
11172
11173private:
11174 template<typename SAX>
11175 JSON_HEDLEY_NON_NULL(2)
11176 bool sax_parse_internal(SAX *sax)
11177 {
11178 // stack to remember the hierarchy of structured values we are parsing
11179 // true = array; false = object
11180 std::vector<bool> states;
11181 // value to avoid a goto (see comment where set to true)
11182 bool skip_to_state_evaluation = false;
11183
11184 while (true)
11185 {
11186 if (!skip_to_state_evaluation)
11187 {
11188 // invariant: get_token() was called before each iteration
11189 switch (last_token)
11190 {
11191 case token_type::begin_object:
11192 {
11193 if (JSON_HEDLEY_UNLIKELY(!sax->start_object(std::size_t(-1))))
11194 {
11195 return false;
11196 }
11197
11198 // closing } -> we are done
11199 if (get_token() == token_type::end_object)
11200 {
11201 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11202 {
11203 return false;
11204 }
11205
11206 break;
11207 }
11208
11209 // parse key
11210 if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11211 {
11212 return sax->parse_error(m_lexer.get_position(),
11214 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11215 }
11216
11217 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11218 {
11219 return false;
11220 }
11221
11222 // parse separator (:)
11223 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11224 {
11225 return sax->parse_error(m_lexer.get_position(),
11227 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11228 }
11229
11230 // remember we are now inside an object
11231 states.push_back(false);
11232 // parse values
11233 get_token();
11234 continue;
11235 }
11236
11237 case token_type::begin_array:
11238 {
11239 if (JSON_HEDLEY_UNLIKELY(!sax->start_array(std::size_t(-1))))
11240 {
11241 return false;
11242 }
11243
11244 // closing ] -> we are done
11245 if (get_token() == token_type::end_array)
11246 {
11247 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11248 {
11249 return false;
11250 }
11251
11252 break;
11253 }
11254
11255 // remember we are now inside an array
11256 states.push_back(true);
11257 // parse values (no need to call get_token)
11258 continue;
11259 }
11260
11261 case token_type::value_float:
11262 {
11263 const auto res = m_lexer.get_number_float();
11264
11265 if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11266 {
11267 return sax->parse_error(m_lexer.get_position(),
11269 out_of_range::create(406, "number overflow parsing '" + m_lexer.get_token_string() + "'", BasicJsonType()));
11270 }
11271
11272 if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11273 {
11274 return false;
11275 }
11276
11277 break;
11278 }
11279
11280 case token_type::literal_false:
11281 {
11282 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11283 {
11284 return false;
11285 }
11286
11287 break;
11288 }
11289
11290 case token_type::literal_null:
11291 {
11292 if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11293 {
11294 return false;
11295 }
11296
11297 break;
11298 }
11299
11300 case token_type::literal_true:
11301 {
11302 if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11303 {
11304 return false;
11305 }
11306
11307 break;
11308 }
11309
11310 case token_type::value_integer:
11311 {
11312 if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11313 {
11314 return false;
11315 }
11316
11317 break;
11318 }
11319
11320 case token_type::value_string:
11321 {
11322 if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11323 {
11324 return false;
11325 }
11326
11327 break;
11328 }
11329
11330 case token_type::value_unsigned:
11331 {
11332 if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
11333 {
11334 return false;
11335 }
11336
11337 break;
11338 }
11339
11340 case token_type::parse_error:
11341 {
11342 // using "uninitialized" to avoid "expected" message
11343 return sax->parse_error(m_lexer.get_position(),
11345 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), BasicJsonType()));
11346 }
11347
11348 case token_type::uninitialized:
11349 case token_type::end_array:
11350 case token_type::end_object:
11351 case token_type::name_separator:
11352 case token_type::value_separator:
11353 case token_type::end_of_input:
11354 case token_type::literal_or_value:
11355 default: // the last token was unexpected
11356 {
11357 return sax->parse_error(m_lexer.get_position(),
11359 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), BasicJsonType()));
11360 }
11361 }
11362 }
11363
11364 else
11365 {
11366 skip_to_state_evaluation = false;
11367 }
11368
11369 // we reached this line after we successfully parsed a value
11370 if (states.empty())
11371 {
11372 // empty stack: we reached the end of the hierarchy: done
11373 return true;
11374 }
11375
11376 if (states.back()) // array
11377 {
11378 // comma -> next value
11379 if (get_token() == token_type::value_separator)
11380 {
11381 // parse a new value
11382 get_token();
11383 continue;
11384 }
11385
11386 // closing ]
11387 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
11388 {
11389 if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11390 {
11391 return false;
11392 }
11393
11394 // We are done with this array. Before we can parse a
11395 // new value, we need to evaluate the new state first.
11396 // By setting skip_to_state_evaluation to false, we
11397 // are effectively jumping to the beginning of this if.
11398 JSON_ASSERT(!states.empty());
11399 states.pop_back();
11400 skip_to_state_evaluation = true;
11401 continue;
11402 }
11403
11404 return sax->parse_error(m_lexer.get_position(),
11406 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), BasicJsonType()));
11407 }
11408
11409 // states.back() is false -> object
11410
11411 // comma -> next value
11412 if (get_token() == token_type::value_separator)
11413 {
11414 // parse key
11415 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
11416 {
11417 return sax->parse_error(m_lexer.get_position(),
11419 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), BasicJsonType()));
11420 }
11421
11422 if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11423 {
11424 return false;
11425 }
11426
11427 // parse separator (:)
11428 if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11429 {
11430 return sax->parse_error(m_lexer.get_position(),
11432 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), BasicJsonType()));
11433 }
11434
11435 // parse values
11436 get_token();
11437 continue;
11438 }
11439
11440 // closing }
11441 if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
11442 {
11443 if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11444 {
11445 return false;
11446 }
11447
11448 // We are done with this object. Before we can parse a
11449 // new value, we need to evaluate the new state first.
11450 // By setting skip_to_state_evaluation to false, we
11451 // are effectively jumping to the beginning of this if.
11452 JSON_ASSERT(!states.empty());
11453 states.pop_back();
11454 skip_to_state_evaluation = true;
11455 continue;
11456 }
11457
11458 return sax->parse_error(m_lexer.get_position(),
11460 parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), BasicJsonType()));
11461 }
11462 }
11463
11465 token_type get_token()
11466 {
11467 return last_token = m_lexer.scan();
11468 }
11469
11470 std::string exception_message(const token_type expected, const std::string &context)
11471 {
11472 std::string error_msg = "syntax error ";
11473
11474 if (!context.empty())
11475 {
11476 error_msg += "while parsing " + context + " ";
11477 }
11478
11479 error_msg += "- ";
11480
11481 if (last_token == token_type::parse_error)
11482 {
11483 error_msg += std::string(m_lexer.get_error_message()) + "; last read: '" +
11484 m_lexer.get_token_string() + "'";
11485 }
11486
11487 else
11488 {
11489 error_msg += "unexpected " + std::string(lexer_t::token_type_name(last_token));
11490 }
11491
11492 if (expected != token_type::uninitialized)
11493 {
11494 error_msg += "; expected " + std::string(lexer_t::token_type_name(expected));
11495 }
11496
11497 return error_msg;
11498 }
11499
11500private:
11502 const parser_callback_t<BasicJsonType> callback = nullptr;
11504 token_type last_token = token_type::uninitialized;
11508 const bool allow_exceptions = true;
11509};
11510
11511} // namespace detail
11512} // namespace nlohmann
11513
11514// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11515
11516
11517// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11518
11519
11520#include <cstddef> // ptrdiff_t
11521#include <limits> // numeric_limits
11522
11523// #include <nlohmann/detail/macro_scope.hpp>
11524
11525
11526namespace nlohmann
11527{
11528namespace detail
11529{
11530/*
11531@brief an iterator for primitive JSON types
11532
11533This class models an iterator for primitive JSON types (boolean, number,
11534string). It's only purpose is to allow the iterator/const_iterator classes
11535to "iterate" over primitive values. Internally, the iterator is modeled by
11536a `difference_type` variable. Value begin_value (`0`) models the begin,
11537end_value (`1`) models past the end.
11538*/
11540{
11541private:
11542 using difference_type = std::ptrdiff_t;
11543 static constexpr difference_type begin_value = 0;
11544 static constexpr difference_type end_value = begin_value + 1;
11545
11546JSON_PRIVATE_UNLESS_TESTED:
11548 difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
11549
11550public:
11551 constexpr difference_type get_value() const noexcept
11552 {
11553 return m_it;
11554 }
11555
11557 void set_begin() noexcept
11558 {
11559 m_it = begin_value;
11560 }
11561
11563 void set_end() noexcept
11564 {
11565 m_it = end_value;
11566 }
11567
11569 constexpr bool is_begin() const noexcept
11570 {
11571 return m_it == begin_value;
11572 }
11573
11575 constexpr bool is_end() const noexcept
11576 {
11577 return m_it == end_value;
11578 }
11579
11580 friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11581 {
11582 return lhs.m_it == rhs.m_it;
11583 }
11584
11585 friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11586 {
11587 return lhs.m_it < rhs.m_it;
11588 }
11589
11590 primitive_iterator_t operator+(difference_type n) noexcept
11591 {
11592 auto result = *this;
11593 result += n;
11594 return result;
11595 }
11596
11597 friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
11598 {
11599 return lhs.m_it - rhs.m_it;
11600 }
11601
11602 primitive_iterator_t &operator++() noexcept
11603 {
11604 ++m_it;
11605 return *this;
11606 }
11607
11608 primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
11609 {
11610 auto result = *this;
11611 ++m_it;
11612 return result;
11613 }
11614
11615 primitive_iterator_t &operator--() noexcept
11616 {
11617 --m_it;
11618 return *this;
11619 }
11620
11621 primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
11622 {
11623 auto result = *this;
11624 --m_it;
11625 return result;
11626 }
11627
11628 primitive_iterator_t &operator+=(difference_type n) noexcept
11629 {
11630 m_it += n;
11631 return *this;
11632 }
11633
11634 primitive_iterator_t &operator-=(difference_type n) noexcept
11635 {
11636 m_it -= n;
11637 return *this;
11638 }
11639};
11640} // namespace detail
11641} // namespace nlohmann
11642
11643
11644namespace nlohmann
11645{
11646namespace detail
11647{
11654template<typename BasicJsonType> struct internal_iterator
11655{
11657 typename BasicJsonType::object_t::iterator object_iterator {};
11659 typename BasicJsonType::array_t::iterator array_iterator {};
11662};
11663} // namespace detail
11664} // namespace nlohmann
11665
11666// #include <nlohmann/detail/iterators/iter_impl.hpp>
11667
11668
11669#include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
11670#include <type_traits> // conditional, is_const, remove_const
11671
11672// #include <nlohmann/detail/exceptions.hpp>
11673
11674// #include <nlohmann/detail/iterators/internal_iterator.hpp>
11675
11676// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
11677
11678// #include <nlohmann/detail/macro_scope.hpp>
11679
11680// #include <nlohmann/detail/meta/cpp_future.hpp>
11681
11682// #include <nlohmann/detail/meta/type_traits.hpp>
11683
11684// #include <nlohmann/detail/value_t.hpp>
11685
11686
11687namespace nlohmann
11688{
11689namespace detail
11690{
11691// forward declare, to be able to friend it later on
11692template<typename IteratorType> class iteration_proxy;
11693template<typename IteratorType> class iteration_proxy_value;
11694
11711template<typename BasicJsonType>
11713{
11715 using other_iter_impl = iter_impl<typename std::conditional<std::is_const<BasicJsonType>::value, typename std::remove_const<BasicJsonType>::type, const BasicJsonType>::type>;
11718 friend BasicJsonType;
11721
11722 using object_t = typename BasicJsonType::object_t;
11723 using array_t = typename BasicJsonType::array_t;
11724 // make sure BasicJsonType is basic_json or const basic_json
11726 "iter_impl only accepts (const) basic_json");
11727
11728public:
11729
11735 using iterator_category = std::bidirectional_iterator_tag;
11736
11738 using value_type = typename BasicJsonType::value_type;
11740 using difference_type = typename BasicJsonType::difference_type;
11742 using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
11743 typename BasicJsonType::const_pointer,
11744 typename BasicJsonType::pointer>::type;
11747 typename std::conditional<std::is_const<BasicJsonType>::value,
11748 typename BasicJsonType::const_reference,
11749 typename BasicJsonType::reference>::type;
11750
11751 iter_impl() = default;
11752 ~iter_impl() = default;
11753 iter_impl(iter_impl &&) noexcept = default;
11754 iter_impl &operator=(iter_impl &&) noexcept = default;
11755
11762 explicit iter_impl(pointer object) noexcept : m_object(object)
11763 {
11764 JSON_ASSERT(m_object != nullptr);
11765
11766 switch (m_object->m_type)
11767 {
11768 case value_t::object:
11769 {
11770 m_it.object_iterator = typename object_t::iterator();
11771 break;
11772 }
11773
11774 case value_t::array:
11775 {
11776 m_it.array_iterator = typename array_t::iterator();
11777 break;
11778 }
11779
11780 case value_t::null:
11781 case value_t::string:
11782 case value_t::boolean:
11786 case value_t::binary:
11787 case value_t::discarded:
11788 default:
11789 {
11791 break;
11792 }
11793 }
11794 }
11795
11813 : m_object(other.m_object), m_it(other.m_it)
11814 {}
11815
11823 {
11824 if (&other != this)
11825 {
11826 m_object = other.m_object;
11827 m_it = other.m_it;
11828 }
11829
11830 return *this;
11831 }
11832
11838 iter_impl(const iter_impl<typename std::remove_const<BasicJsonType>::type> &other) noexcept
11839 : m_object(other.m_object), m_it(other.m_it)
11840 {}
11841
11848 iter_impl &operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type> &other) noexcept // NOLINT(cert-oop54-cpp)
11849 {
11850 m_object = other.m_object;
11851 m_it = other.m_it;
11852 return *this;
11853 }
11854
11855JSON_PRIVATE_UNLESS_TESTED:
11860 void set_begin() noexcept
11861 {
11862 JSON_ASSERT(m_object != nullptr);
11863
11864 switch (m_object->m_type)
11865 {
11866 case value_t::object:
11867 {
11868 m_it.object_iterator = m_object->m_value.object->begin();
11869 break;
11870 }
11871
11872 case value_t::array:
11873 {
11874 m_it.array_iterator = m_object->m_value.array->begin();
11875 break;
11876 }
11877
11878 case value_t::null:
11879 {
11880 // set to end so begin()==end() is true: null is empty
11882 break;
11883 }
11884
11885 case value_t::string:
11886 case value_t::boolean:
11890 case value_t::binary:
11891 case value_t::discarded:
11892 default:
11893 {
11895 break;
11896 }
11897 }
11898 }
11899
11904 void set_end() noexcept
11905 {
11906 JSON_ASSERT(m_object != nullptr);
11907
11908 switch (m_object->m_type)
11909 {
11910 case value_t::object:
11911 {
11912 m_it.object_iterator = m_object->m_value.object->end();
11913 break;
11914 }
11915
11916 case value_t::array:
11917 {
11918 m_it.array_iterator = m_object->m_value.array->end();
11919 break;
11920 }
11921
11922 case value_t::null:
11923 case value_t::string:
11924 case value_t::boolean:
11928 case value_t::binary:
11929 case value_t::discarded:
11930 default:
11931 {
11933 break;
11934 }
11935 }
11936 }
11937
11938public:
11944 {
11945 JSON_ASSERT(m_object != nullptr);
11946
11947 switch (m_object->m_type)
11948 {
11949 case value_t::object:
11950 {
11951 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11952 return m_it.object_iterator->second;
11953 }
11954
11955 case value_t::array:
11956 {
11957 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
11958 return *m_it.array_iterator;
11959 }
11960
11961 case value_t::null:
11962 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11963
11964 case value_t::string:
11965 case value_t::boolean:
11969 case value_t::binary:
11970 case value_t::discarded:
11971 default:
11972 {
11973 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
11974 {
11975 return *m_object;
11976 }
11977
11978 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
11979 }
11980 }
11981 }
11982
11988 {
11989 JSON_ASSERT(m_object != nullptr);
11990
11991 switch (m_object->m_type)
11992 {
11993 case value_t::object:
11994 {
11995 JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
11996 return &(m_it.object_iterator->second);
11997 }
11998
11999 case value_t::array:
12000 {
12001 JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
12002 return &*m_it.array_iterator;
12003 }
12004
12005 case value_t::null:
12006 case value_t::string:
12007 case value_t::boolean:
12011 case value_t::binary:
12012 case value_t::discarded:
12013 default:
12014 {
12015 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.is_begin()))
12016 {
12017 return m_object;
12018 }
12019
12020 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12021 }
12022 }
12023 }
12024
12029 iter_impl const operator++(int) // NOLINT(readability-const-return-type)
12030 {
12031 auto result = *this;
12032 ++(*this);
12033 return result;
12034 }
12035
12041 {
12042 JSON_ASSERT(m_object != nullptr);
12043
12044 switch (m_object->m_type)
12045 {
12046 case value_t::object:
12047 {
12048 std::advance(m_it.object_iterator, 1);
12049 break;
12050 }
12051
12052 case value_t::array:
12053 {
12054 std::advance(m_it.array_iterator, 1);
12055 break;
12056 }
12057
12058 case value_t::null:
12059 case value_t::string:
12060 case value_t::boolean:
12064 case value_t::binary:
12065 case value_t::discarded:
12066 default:
12067 {
12069 break;
12070 }
12071 }
12072
12073 return *this;
12074 }
12075
12080 iter_impl const operator--(int) // NOLINT(readability-const-return-type)
12081 {
12082 auto result = *this;
12083 --(*this);
12084 return result;
12085 }
12086
12092 {
12093 JSON_ASSERT(m_object != nullptr);
12094
12095 switch (m_object->m_type)
12096 {
12097 case value_t::object:
12098 {
12099 std::advance(m_it.object_iterator, -1);
12100 break;
12101 }
12102
12103 case value_t::array:
12104 {
12105 std::advance(m_it.array_iterator, -1);
12106 break;
12107 }
12108
12109 case value_t::null:
12110 case value_t::string:
12111 case value_t::boolean:
12115 case value_t::binary:
12116 case value_t::discarded:
12117 default:
12118 {
12120 break;
12121 }
12122 }
12123
12124 return *this;
12125 }
12126
12131 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 >
12132 bool operator==(const IterImpl &other) const
12133 {
12134 // if objects are not the same, the comparison is undefined
12135 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12136 {
12137 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12138 }
12139
12140 JSON_ASSERT(m_object != nullptr);
12141
12142 switch (m_object->m_type)
12143 {
12144 case value_t::object:
12145 return (m_it.object_iterator == other.m_it.object_iterator);
12146
12147 case value_t::array:
12148 return (m_it.array_iterator == other.m_it.array_iterator);
12149
12150 case value_t::null:
12151 case value_t::string:
12152 case value_t::boolean:
12156 case value_t::binary:
12157 case value_t::discarded:
12158 default:
12159 return (m_it.primitive_iterator == other.m_it.primitive_iterator);
12160 }
12161 }
12162
12167 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 >
12168 bool operator!=(const IterImpl &other) const
12169 {
12170 return !operator==(other);
12171 }
12172
12177 bool operator<(const iter_impl &other) const
12178 {
12179 // if objects are not the same, the comparison is undefined
12180 if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12181 {
12182 JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", *m_object));
12183 }
12184
12185 JSON_ASSERT(m_object != nullptr);
12186
12187 switch (m_object->m_type)
12188 {
12189 case value_t::object:
12190 JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", *m_object));
12191
12192 case value_t::array:
12193 return (m_it.array_iterator < other.m_it.array_iterator);
12194
12195 case value_t::null:
12196 case value_t::string:
12197 case value_t::boolean:
12201 case value_t::binary:
12202 case value_t::discarded:
12203 default:
12205 }
12206 }
12207
12212 bool operator<=(const iter_impl &other) const
12213 {
12214 return !other.operator < (*this);
12215 }
12216
12221 bool operator>(const iter_impl &other) const
12222 {
12223 return !operator<=(other);
12224 }
12225
12230 bool operator>=(const iter_impl &other) const
12231 {
12232 return !operator<(other);
12233 }
12234
12240 {
12241 JSON_ASSERT(m_object != nullptr);
12242
12243 switch (m_object->m_type)
12244 {
12245 case value_t::object:
12246 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12247
12248 case value_t::array:
12249 {
12250 std::advance(m_it.array_iterator, i);
12251 break;
12252 }
12253
12254 case value_t::null:
12255 case value_t::string:
12256 case value_t::boolean:
12260 case value_t::binary:
12261 case value_t::discarded:
12262 default:
12263 {
12265 break;
12266 }
12267 }
12268
12269 return *this;
12270 }
12271
12277 {
12278 return operator+=(-i);
12279 }
12280
12286 {
12287 auto result = *this;
12288 result += i;
12289 return result;
12290 }
12291
12297 {
12298 auto result = it;
12299 result += i;
12300 return result;
12301 }
12302
12308 {
12309 auto result = *this;
12310 result -= i;
12311 return result;
12312 }
12313
12319 {
12320 JSON_ASSERT(m_object != nullptr);
12321
12322 switch (m_object->m_type)
12323 {
12324 case value_t::object:
12325 JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", *m_object));
12326
12327 case value_t::array:
12328 return m_it.array_iterator - other.m_it.array_iterator;
12329
12330 case value_t::null:
12331 case value_t::string:
12332 case value_t::boolean:
12336 case value_t::binary:
12337 case value_t::discarded:
12338 default:
12340 }
12341 }
12342
12348 {
12349 JSON_ASSERT(m_object != nullptr);
12350
12351 switch (m_object->m_type)
12352 {
12353 case value_t::object:
12354 JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", *m_object));
12355
12356 case value_t::array:
12357 return *std::next(m_it.array_iterator, n);
12358
12359 case value_t::null:
12360 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12361
12362 case value_t::string:
12363 case value_t::boolean:
12367 case value_t::binary:
12368 case value_t::discarded:
12369 default:
12370 {
12371 if (JSON_HEDLEY_LIKELY(m_it.primitive_iterator.get_value() == -n))
12372 {
12373 return *m_object;
12374 }
12375
12376 JSON_THROW(invalid_iterator::create(214, "cannot get value", *m_object));
12377 }
12378 }
12379 }
12380
12385 const typename object_t::key_type &key() const
12386 {
12387 JSON_ASSERT(m_object != nullptr);
12388
12389 if (JSON_HEDLEY_LIKELY(m_object->is_object()))
12390 {
12391 return m_it.object_iterator->first;
12392 }
12393
12394 JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", *m_object));
12395 }
12396
12402 {
12403 return operator*();
12404 }
12405
12406JSON_PRIVATE_UNLESS_TESTED:
12408 pointer m_object = nullptr;
12411};
12412} // namespace detail
12413} // namespace nlohmann
12414
12415// #include <nlohmann/detail/iterators/iteration_proxy.hpp>
12416
12417// #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
12418
12419
12420#include <cstddef> // ptrdiff_t
12421#include <iterator> // reverse_iterator
12422#include <utility> // declval
12423
12424namespace nlohmann
12425{
12426namespace detail
12427{
12429// reverse_iterator //
12431
12450template<typename Base>
12451class json_reverse_iterator : public std::reverse_iterator<Base>
12452{
12453public:
12454 using difference_type = std::ptrdiff_t;
12456 using base_iterator = std::reverse_iterator<Base>;
12458 using reference = typename Base::reference;
12459
12461 explicit json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
12462 : base_iterator(it) {}
12463
12465 explicit json_reverse_iterator(const base_iterator &it) noexcept : base_iterator(it) {}
12466
12468 json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
12469 {
12470 return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
12471 }
12472
12475 {
12476 return static_cast<json_reverse_iterator &>(base_iterator::operator++());
12477 }
12478
12480 json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
12481 {
12482 return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
12483 }
12484
12487 {
12488 return static_cast<json_reverse_iterator &>(base_iterator::operator--());
12489 }
12490
12493 {
12494 return static_cast<json_reverse_iterator &>(base_iterator::operator+=(i));
12495 }
12496
12498 json_reverse_iterator operator+(difference_type i) const
12499 {
12500 return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
12501 }
12502
12504 json_reverse_iterator operator-(difference_type i) const
12505 {
12506 return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
12507 }
12508
12510 difference_type operator-(const json_reverse_iterator &other) const
12511 {
12512 return base_iterator(*this) - base_iterator(other);
12513 }
12514
12516 reference operator[](difference_type n) const
12517 {
12518 return *(this->operator+(n));
12519 }
12520
12522 auto key() const -> decltype(std::declval<Base>().key())
12523 {
12524 auto it = --this->base();
12525 return it.key();
12526 }
12527
12530 {
12531 auto it = --this->base();
12532 return it.operator * ();
12533 }
12534};
12535} // namespace detail
12536} // namespace nlohmann
12537
12538// #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12539
12540// #include <nlohmann/detail/json_pointer.hpp>
12541
12542
12543#include <algorithm> // all_of
12544#include <cctype> // isdigit
12545#include <limits> // max
12546#include <numeric> // accumulate
12547#include <string> // string
12548#include <utility> // move
12549#include <vector> // vector
12550
12551// #include <nlohmann/detail/exceptions.hpp>
12552
12553// #include <nlohmann/detail/macro_scope.hpp>
12554
12555// #include <nlohmann/detail/string_escape.hpp>
12556
12557// #include <nlohmann/detail/value_t.hpp>
12558
12559
12560namespace nlohmann
12561{
12562template<typename BasicJsonType>
12564{
12565 // allow basic_json to access private members
12566 NLOHMANN_BASIC_JSON_TPL_DECLARATION
12567 friend class basic_json;
12568
12569public:
12591 explicit json_pointer(const std::string &s = "")
12592 : reference_tokens(split(s))
12593 {}
12594
12609 std::string to_string() const
12610 {
12611 return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
12612 std::string{},
12613 [](const std::string & a, const std::string & b)
12614 {
12615 return a + "/" + detail::escape(b);
12616 });
12617 }
12618
12620 operator std::string() const
12621 {
12622 return to_string();
12623 }
12624
12642 {
12643 reference_tokens.insert(reference_tokens.end(),
12644 ptr.reference_tokens.begin(),
12645 ptr.reference_tokens.end());
12646 return *this;
12647 }
12648
12665 json_pointer &operator/=(std::string token)
12666 {
12667 push_back(std::move(token));
12668 return *this;
12669 }
12670
12687 json_pointer &operator/=(std::size_t array_idx)
12688 {
12689 return *this /= std::to_string(array_idx);
12690 }
12691
12708 const json_pointer &rhs)
12709 {
12710 return json_pointer(lhs) /= rhs;
12711 }
12712
12728 friend json_pointer operator/(const json_pointer &ptr, std::string token) // NOLINT(performance-unnecessary-value-param)
12729 {
12730 return json_pointer(ptr) /= std::move(token);
12731 }
12732
12748 friend json_pointer operator/(const json_pointer &ptr, std::size_t array_idx)
12749 {
12750 return json_pointer(ptr) /= array_idx;
12751 }
12752
12767 {
12768 if (empty())
12769 {
12770 return *this;
12771 }
12772
12773 json_pointer res = *this;
12774 res.pop_back();
12775 return res;
12776 }
12777
12792 {
12793 if (JSON_HEDLEY_UNLIKELY(empty()))
12794 {
12795 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12796 }
12797
12798 reference_tokens.pop_back();
12799 }
12800
12815 const std::string &back() const
12816 {
12817 if (JSON_HEDLEY_UNLIKELY(empty()))
12818 {
12819 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12820 }
12821
12822 return reference_tokens.back();
12823 }
12824
12837 void push_back(const std::string &token)
12838 {
12839 reference_tokens.push_back(token);
12840 }
12841
12843 void push_back(std::string &&token)
12844 {
12845 reference_tokens.push_back(std::move(token));
12846 }
12847
12862 bool empty() const noexcept
12863 {
12864 return reference_tokens.empty();
12865 }
12866
12867private:
12878 static typename BasicJsonType::size_type array_index(const std::string &s)
12879 {
12880 using size_type = typename BasicJsonType::size_type;
12881
12882 // error condition (cf. RFC 6901, Sect. 4)
12883 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
12884 {
12885 JSON_THROW(detail::parse_error::create(106, 0, "array index '" + s + "' must not begin with '0'", BasicJsonType()));
12886 }
12887
12888 // error condition (cf. RFC 6901, Sect. 4)
12889 if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
12890 {
12891 JSON_THROW(detail::parse_error::create(109, 0, "array index '" + s + "' is not a number", BasicJsonType()));
12892 }
12893
12894 std::size_t processed_chars = 0;
12895 unsigned long long res = 0; // NOLINT(runtime/int)
12896 JSON_TRY
12897 {
12898 res = std::stoull(s, &processed_chars);
12899 }
12900 JSON_CATCH(std::out_of_range &)
12901 {
12902 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12903 }
12904
12905 // check if the string was completely read
12906 if (JSON_HEDLEY_UNLIKELY(processed_chars != s.size()))
12907 {
12908 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'", BasicJsonType()));
12909 }
12910
12911 // only triggered on special platforms (like 32bit), see also
12912 // https://github.com/nlohmann/json/pull/2203
12913 if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
12914 {
12915 JSON_THROW(detail::out_of_range::create(410, "array index " + s + " exceeds size_type", BasicJsonType())); // LCOV_EXCL_LINE
12916 }
12917
12918 return static_cast<size_type>(res);
12919 }
12920
12921JSON_PRIVATE_UNLESS_TESTED:
12922 json_pointer top() const
12923 {
12924 if (JSON_HEDLEY_UNLIKELY(empty()))
12925 {
12926 JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", BasicJsonType()));
12927 }
12928
12929 json_pointer result = *this;
12930 result.reference_tokens = {reference_tokens[0]};
12931 return result;
12932 }
12933
12934private:
12943 BasicJsonType &get_and_create(BasicJsonType &j) const
12944 {
12945 auto *result = &j;
12946
12947 // in case no reference tokens exist, return a reference to the JSON value
12948 // j which will be overwritten by a primitive value
12949 for (const auto &reference_token : reference_tokens)
12950 {
12951 switch (result->type())
12952 {
12954 {
12955 if (reference_token == "0")
12956 {
12957 // start a new array if reference token is 0
12958 result = &result->operator[](0);
12959 }
12960
12961 else
12962 {
12963 // start a new object otherwise
12964 result = &result->operator[](reference_token);
12965 }
12966
12967 break;
12968 }
12969
12971 {
12972 // create an entry in the object
12973 result = &result->operator[](reference_token);
12974 break;
12975 }
12976
12978 {
12979 // create an entry in the array
12980 result = &result->operator[](array_index(reference_token));
12981 break;
12982 }
12983
12984 /*
12985 The following code is only reached if there exists a reference
12986 token _and_ the current value is primitive. In this case, we have
12987 an error situation, because primitive values may only occur as
12988 single value; that is, with an empty list of reference tokens.
12989 */
12997 default:
12998 JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", j));
12999 }
13000 }
13001
13002 return *result;
13003 }
13004
13024 BasicJsonType &get_unchecked(BasicJsonType *ptr) const
13025 {
13026 for (const auto &reference_token : reference_tokens)
13027 {
13028 // convert null values to arrays or objects before continuing
13029 if (ptr->is_null())
13030 {
13031 // check if reference token is a number
13032 const bool nums =
13033 std::all_of(reference_token.begin(), reference_token.end(),
13034 [](const unsigned char x)
13035 {
13036 return std::isdigit(x);
13037 });
13038 // change value to array for numbers or "-" or to object otherwise
13039 *ptr = (nums || reference_token == "-")
13042 }
13043
13044 switch (ptr->type())
13045 {
13047 {
13048 // use unchecked object access
13049 ptr = &ptr->operator[](reference_token);
13050 break;
13051 }
13052
13054 {
13055 if (reference_token == "-")
13056 {
13057 // explicitly treat "-" as index beyond the end
13058 ptr = &ptr->operator[](ptr->m_value.array->size());
13059 }
13060
13061 else
13062 {
13063 // convert array index to number; unchecked access
13064 ptr = &ptr->operator[](array_index(reference_token));
13065 }
13066
13067 break;
13068 }
13069
13078 default:
13079 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13080 }
13081 }
13082
13083 return *ptr;
13084 }
13085
13092 BasicJsonType &get_checked(BasicJsonType *ptr) const
13093 {
13094 for (const auto &reference_token : reference_tokens)
13095 {
13096 switch (ptr->type())
13097 {
13099 {
13100 // note: at performs range check
13101 ptr = &ptr->at(reference_token);
13102 break;
13103 }
13104
13106 {
13107 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13108 {
13109 // "-" always fails the range check
13110 JSON_THROW(detail::out_of_range::create(402,
13111 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13112 ") is out of range", *ptr));
13113 }
13114
13115 // note: at performs range check
13116 ptr = &ptr->at(array_index(reference_token));
13117 break;
13118 }
13119
13128 default:
13129 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13130 }
13131 }
13132
13133 return *ptr;
13134 }
13135
13149 const BasicJsonType &get_unchecked(const BasicJsonType *ptr) const
13150 {
13151 for (const auto &reference_token : reference_tokens)
13152 {
13153 switch (ptr->type())
13154 {
13156 {
13157 // use unchecked object access
13158 ptr = &ptr->operator[](reference_token);
13159 break;
13160 }
13161
13163 {
13164 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13165 {
13166 // "-" cannot be used for const access
13167 JSON_THROW(detail::out_of_range::create(402, "array index '-' (" + std::to_string(ptr->m_value.array->size()) + ") is out of range", *ptr));
13168 }
13169
13170 // use unchecked array access
13171 ptr = &ptr->operator[](array_index(reference_token));
13172 break;
13173 }
13174
13183 default:
13184 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13185 }
13186 }
13187
13188 return *ptr;
13189 }
13190
13197 const BasicJsonType &get_checked(const BasicJsonType *ptr) const
13198 {
13199 for (const auto &reference_token : reference_tokens)
13200 {
13201 switch (ptr->type())
13202 {
13204 {
13205 // note: at performs range check
13206 ptr = &ptr->at(reference_token);
13207 break;
13208 }
13209
13211 {
13212 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13213 {
13214 // "-" always fails the range check
13215 JSON_THROW(detail::out_of_range::create(402,
13216 "array index '-' (" + std::to_string(ptr->m_value.array->size()) +
13217 ") is out of range", *ptr));
13218 }
13219
13220 // note: at performs range check
13221 ptr = &ptr->at(array_index(reference_token));
13222 break;
13223 }
13224
13233 default:
13234 JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + reference_token + "'", *ptr));
13235 }
13236 }
13237
13238 return *ptr;
13239 }
13240
13245 bool contains(const BasicJsonType *ptr) const
13246 {
13247 for (const auto &reference_token : reference_tokens)
13248 {
13249 switch (ptr->type())
13250 {
13252 {
13253 if (!ptr->contains(reference_token))
13254 {
13255 // we did not find the key in the object
13256 return false;
13257 }
13258
13259 ptr = &ptr->operator[](reference_token);
13260 break;
13261 }
13262
13264 {
13265 if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13266 {
13267 // "-" always fails the range check
13268 return false;
13269 }
13270
13271 if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13272 {
13273 // invalid char
13274 return false;
13275 }
13276
13277 if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
13278 {
13279 if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13280 {
13281 // first char should be between '1' and '9'
13282 return false;
13283 }
13284
13285 for (std::size_t i = 1; i < reference_token.size(); i++)
13286 {
13287 if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13288 {
13289 // other char should be between '0' and '9'
13290 return false;
13291 }
13292 }
13293 }
13294
13295 const auto idx = array_index(reference_token);
13296
13297 if (idx >= ptr->size())
13298 {
13299 // index out of range
13300 return false;
13301 }
13302
13303 ptr = &ptr->operator[](idx);
13304 break;
13305 }
13306
13315 default:
13316 {
13317 // we do not expect primitive values if there is still a
13318 // reference token to process
13319 return false;
13320 }
13321 }
13322 }
13323
13324 // no reference token left means we found a primitive value
13325 return true;
13326 }
13327
13337 static std::vector<std::string> split(const std::string &reference_string)
13338 {
13339 std::vector<std::string> result;
13340
13341 // special case: empty reference string -> no reference tokens
13342 if (reference_string.empty())
13343 {
13344 return result;
13345 }
13346
13347 // check if nonempty reference string begins with slash
13348 if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
13349 {
13350 JSON_THROW(detail::parse_error::create(107, 1, "JSON pointer must be empty or begin with '/' - was: '" + reference_string + "'", BasicJsonType()));
13351 }
13352
13353 // extract the reference tokens:
13354 // - slash: position of the last read slash (or end of string)
13355 // - start: position after the previous slash
13356 for (
13357 // search for the first slash after the first character
13358 std::size_t slash = reference_string.find_first_of('/', 1),
13359 // set the beginning of the first reference token
13360 start = 1;
13361 // we can stop if start == 0 (if slash == std::string::npos)
13362 start != 0;
13363 // set the beginning of the next reference token
13364 // (will eventually be 0 if slash == std::string::npos)
13365 start = (slash == std::string::npos) ? 0 : slash + 1,
13366 // find next slash
13367 slash = reference_string.find_first_of('/', start))
13368 {
13369 // use the text between the beginning of the reference token
13370 // (start) and the last slash (slash).
13371 auto reference_token = reference_string.substr(start, slash - start);
13372
13373 // check reference tokens are properly escaped
13374 for (std::size_t pos = reference_token.find_first_of('~');
13375 pos != std::string::npos;
13376 pos = reference_token.find_first_of('~', pos + 1))
13377 {
13378 JSON_ASSERT(reference_token[pos] == '~');
13379
13380 // ~ must be followed by 0 or 1
13381 if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
13382 (reference_token[pos + 1] != '0' &&
13383 reference_token[pos + 1] != '1')))
13384 {
13385 JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", BasicJsonType()));
13386 }
13387 }
13388
13389 // finally, store the reference token
13390 detail::unescape(reference_token);
13391 result.push_back(reference_token);
13392 }
13393
13394 return result;
13395 }
13396
13397private:
13405 static void flatten(const std::string &reference_string,
13406 const BasicJsonType &value,
13407 BasicJsonType &result)
13408 {
13409 switch (value.type())
13410 {
13412 {
13413 if (value.m_value.array->empty())
13414 {
13415 // flatten empty array as null
13416 result[reference_string] = nullptr;
13417 }
13418
13419 else
13420 {
13421 // iterate array and use index as reference string
13422 for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13423 {
13424 flatten(reference_string + "/" + std::to_string(i),
13425 value.m_value.array->operator[](i), result);
13426 }
13427 }
13428
13429 break;
13430 }
13431
13433 {
13434 if (value.m_value.object->empty())
13435 {
13436 // flatten empty object as null
13437 result[reference_string] = nullptr;
13438 }
13439
13440 else
13441 {
13442 // iterate object and use keys as reference string
13443 for (const auto &element : *value.m_value.object)
13444 {
13445 flatten(reference_string + "/" + detail::escape(element.first), element.second, result);
13446 }
13447 }
13448
13449 break;
13450 }
13451
13460 default:
13461 {
13462 // add primitive value with its reference string
13463 result[reference_string] = value;
13464 break;
13465 }
13466 }
13467 }
13468
13479 static BasicJsonType
13480 unflatten(const BasicJsonType &value)
13481 {
13482 if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
13483 {
13484 JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", value));
13485 }
13486
13487 BasicJsonType result;
13488
13489 // iterate the JSON object values
13490 for (const auto &element : *value.m_value.object)
13491 {
13492 if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
13493 {
13494 JSON_THROW(detail::type_error::create(315, "values in object must be primitive", element.second));
13495 }
13496
13497 // assign value to reference pointed to by JSON pointer; Note that if
13498 // the JSON pointer is "" (i.e., points to the whole value), function
13499 // get_and_create returns a reference to result itself. An assignment
13500 // will then create a primitive value.
13501 json_pointer(element.first).get_and_create(result) = element.second;
13502 }
13503
13504 return result;
13505 }
13506
13518 friend bool operator==(json_pointer const &lhs,
13519 json_pointer const &rhs) noexcept
13520 {
13521 return lhs.reference_tokens == rhs.reference_tokens;
13522 }
13523
13535 friend bool operator!=(json_pointer const &lhs,
13536 json_pointer const &rhs) noexcept
13537 {
13538 return !(lhs == rhs);
13539 }
13540
13542 std::vector<std::string> reference_tokens;
13543};
13544} // namespace nlohmann
13545
13546// #include <nlohmann/detail/json_ref.hpp>
13547
13548
13549#include <initializer_list>
13550#include <utility>
13551
13552// #include <nlohmann/detail/meta/type_traits.hpp>
13553
13554
13555namespace nlohmann
13556{
13557namespace detail
13558{
13559template<typename BasicJsonType>
13561{
13562public:
13563 using value_type = BasicJsonType;
13564
13565 json_ref(value_type &&value)
13566 : owned_value(std::move(value))
13567 {}
13568
13569 json_ref(const value_type &value)
13570 : value_ref(&value)
13571 {}
13572
13573 json_ref(std::initializer_list<json_ref> init)
13574 : owned_value(init)
13575 {}
13576
13577 template <
13578 class... Args,
13579 enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
13580 json_ref(Args && ... args)
13581 : owned_value(std::forward<Args>(args)...)
13582 {}
13583
13584 // class should be movable only
13585 json_ref(json_ref &&) noexcept = default;
13586 json_ref(const json_ref &) = delete;
13587 json_ref &operator=(const json_ref &) = delete;
13588 json_ref &operator=(json_ref &&) = delete;
13589 ~json_ref() = default;
13590
13591 value_type moved_or_copied() const
13592 {
13593 if (value_ref == nullptr)
13594 {
13595 return std::move(owned_value);
13596 }
13597
13598 return *value_ref;
13599 }
13600
13601 value_type const &operator*() const
13602 {
13603 return value_ref ? *value_ref : owned_value;
13604 }
13605
13606 value_type const *operator->() const
13607 {
13608 return & **this;
13609 }
13610
13611private:
13612 mutable value_type owned_value = nullptr;
13613 value_type const *value_ref = nullptr;
13614};
13615} // namespace detail
13616} // namespace nlohmann
13617
13618// #include <nlohmann/detail/macro_scope.hpp>
13619
13620// #include <nlohmann/detail/string_escape.hpp>
13621
13622// #include <nlohmann/detail/meta/cpp_future.hpp>
13623
13624// #include <nlohmann/detail/meta/type_traits.hpp>
13625
13626// #include <nlohmann/detail/output/binary_writer.hpp>
13627
13628
13629#include <algorithm> // reverse
13630#include <array> // array
13631#include <cmath> // isnan, isinf
13632#include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
13633#include <cstring> // memcpy
13634#include <limits> // numeric_limits
13635#include <string> // string
13636#include <utility> // move
13637
13638// #include <nlohmann/detail/input/binary_reader.hpp>
13639
13640// #include <nlohmann/detail/macro_scope.hpp>
13641
13642// #include <nlohmann/detail/output/output_adapters.hpp>
13643
13644
13645#include <algorithm> // copy
13646#include <cstddef> // size_t
13647#include <iterator> // back_inserter
13648#include <memory> // shared_ptr, make_shared
13649#include <string> // basic_string
13650#include <vector> // vector
13651
13652#ifndef JSON_NO_IO
13653#include <ios> // streamsize
13654#include <ostream> // basic_ostream
13655#endif // JSON_NO_IO
13656
13657// #include <nlohmann/detail/macro_scope.hpp>
13658
13659
13660namespace nlohmann
13661{
13662namespace detail
13663{
13665template<typename CharType> struct output_adapter_protocol
13666{
13667 virtual void write_character(CharType c) = 0;
13668 virtual void write_characters(const CharType *s, std::size_t length) = 0;
13669 virtual ~output_adapter_protocol() = default;
13670
13671 output_adapter_protocol() = default;
13673 output_adapter_protocol(output_adapter_protocol &&) noexcept = default;
13674 output_adapter_protocol &operator=(const output_adapter_protocol &) = default;
13675 output_adapter_protocol &operator=(output_adapter_protocol &&) noexcept = default;
13676};
13677
13679template<typename CharType>
13680using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
13681
13683template<typename CharType, typename AllocatorType = std::allocator<CharType>>
13685{
13686public:
13687 explicit output_vector_adapter(std::vector<CharType, AllocatorType> &vec) noexcept
13688 : v(vec)
13689 {}
13690
13691 void write_character(CharType c) override
13692 {
13693 v.push_back(c);
13694 }
13695
13696 JSON_HEDLEY_NON_NULL(2)
13697 void write_characters(const CharType *s, std::size_t length) override
13698 {
13699 std::copy(s, s + length, std::back_inserter(v));
13700 }
13701
13702private:
13703 std::vector<CharType, AllocatorType> &v;
13704};
13705
13706#ifndef JSON_NO_IO
13708template<typename CharType>
13710{
13711public:
13712 explicit output_stream_adapter(std::basic_ostream<CharType> &s) noexcept
13713 : stream(s)
13714 {}
13715
13716 void write_character(CharType c) override
13717 {
13718 stream.put(c);
13719 }
13720
13721 JSON_HEDLEY_NON_NULL(2)
13722 void write_characters(const CharType *s, std::size_t length) override
13723 {
13724 stream.write(s, static_cast<std::streamsize>(length));
13725 }
13726
13727private:
13728 std::basic_ostream<CharType> &stream;
13729};
13730#endif // JSON_NO_IO
13731
13733template<typename CharType, typename StringType = std::basic_string<CharType>>
13735{
13736public:
13737 explicit output_string_adapter(StringType &s) noexcept
13738 : str(s)
13739 {}
13740
13741 void write_character(CharType c) override
13742 {
13743 str.push_back(c);
13744 }
13745
13746 JSON_HEDLEY_NON_NULL(2)
13747 void write_characters(const CharType *s, std::size_t length) override
13748 {
13749 str.append(s, length);
13750 }
13751
13752private:
13753 StringType &str;
13754};
13755
13756template<typename CharType, typename StringType = std::basic_string<CharType>>
13758{
13759public:
13760 template<typename AllocatorType = std::allocator<CharType>>
13761 output_adapter(std::vector<CharType, AllocatorType> &vec)
13762 : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
13763
13764#ifndef JSON_NO_IO
13765 output_adapter(std::basic_ostream<CharType> &s)
13766 : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
13767#endif // JSON_NO_IO
13768
13769 output_adapter(StringType &s)
13770 : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
13771
13773 {
13774 return oa;
13775 }
13776
13777private:
13778 output_adapter_t<CharType> oa = nullptr;
13779};
13780} // namespace detail
13781} // namespace nlohmann
13782
13783
13784namespace nlohmann
13785{
13786namespace detail
13787{
13789// binary writer //
13791
13795template<typename BasicJsonType, typename CharType>
13797{
13798 using string_t = typename BasicJsonType::string_t;
13799 using binary_t = typename BasicJsonType::binary_t;
13800 using number_float_t = typename BasicJsonType::number_float_t;
13801
13802public:
13808 explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
13809 {
13810 JSON_ASSERT(oa);
13811 }
13812
13817 void write_bson(const BasicJsonType &j)
13818 {
13819 switch (j.type())
13820 {
13821 case value_t::object:
13822 {
13823 write_bson_object(*j.m_value.object);
13824 break;
13825 }
13826
13827 case value_t::null:
13828 case value_t::array:
13829 case value_t::string:
13830 case value_t::boolean:
13834 case value_t::binary:
13835 case value_t::discarded:
13836 default:
13837 {
13838 JSON_THROW(type_error::create(317, "to serialize to BSON, top-level type must be object, but is " + std::string(j.type_name()), j));
13839 }
13840 }
13841 }
13842
13846 void write_cbor(const BasicJsonType &j)
13847 {
13848 switch (j.type())
13849 {
13850 case value_t::null:
13851 {
13852 oa->write_character(to_char_type(0xF6));
13853 break;
13854 }
13855
13856 case value_t::boolean:
13857 {
13858 oa->write_character(j.m_value.boolean
13859 ? to_char_type(0xF5)
13860 : to_char_type(0xF4));
13861 break;
13862 }
13863
13865 {
13866 if (j.m_value.number_integer >= 0)
13867 {
13868 // CBOR does not differentiate between positive signed
13869 // integers and unsigned integers. Therefore, we used the
13870 // code from the value_t::number_unsigned case here.
13871 if (j.m_value.number_integer <= 0x17)
13872 {
13873 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13874 }
13875
13876 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
13877 {
13878 oa->write_character(to_char_type(0x18));
13879 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
13880 }
13881
13882 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
13883 {
13884 oa->write_character(to_char_type(0x19));
13885 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
13886 }
13887
13888 else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
13889 {
13890 oa->write_character(to_char_type(0x1A));
13891 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
13892 }
13893
13894 else
13895 {
13896 oa->write_character(to_char_type(0x1B));
13897 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
13898 }
13899 }
13900
13901 else
13902 {
13903 // The conversions below encode the sign in the first
13904 // byte, and the value is converted to a positive number.
13905 const auto positive_number = -1 - j.m_value.number_integer;
13906
13907 if (j.m_value.number_integer >= -24)
13908 {
13909 write_number(static_cast<std::uint8_t>(0x20 + positive_number));
13910 }
13911
13912 else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
13913 {
13914 oa->write_character(to_char_type(0x38));
13915 write_number(static_cast<std::uint8_t>(positive_number));
13916 }
13917
13918 else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
13919 {
13920 oa->write_character(to_char_type(0x39));
13921 write_number(static_cast<std::uint16_t>(positive_number));
13922 }
13923
13924 else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
13925 {
13926 oa->write_character(to_char_type(0x3A));
13927 write_number(static_cast<std::uint32_t>(positive_number));
13928 }
13929
13930 else
13931 {
13932 oa->write_character(to_char_type(0x3B));
13933 write_number(static_cast<std::uint64_t>(positive_number));
13934 }
13935 }
13936
13937 break;
13938 }
13939
13941 {
13942 if (j.m_value.number_unsigned <= 0x17)
13943 {
13944 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13945 }
13946
13947 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
13948 {
13949 oa->write_character(to_char_type(0x18));
13950 write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
13951 }
13952
13953 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
13954 {
13955 oa->write_character(to_char_type(0x19));
13956 write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
13957 }
13958
13959 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
13960 {
13961 oa->write_character(to_char_type(0x1A));
13962 write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
13963 }
13964
13965 else
13966 {
13967 oa->write_character(to_char_type(0x1B));
13968 write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
13969 }
13970
13971 break;
13972 }
13973
13975 {
13976 if (std::isnan(j.m_value.number_float))
13977 {
13978 // NaN is 0xf97e00 in CBOR
13979 oa->write_character(to_char_type(0xF9));
13980 oa->write_character(to_char_type(0x7E));
13981 oa->write_character(to_char_type(0x00));
13982 }
13983
13984 else if (std::isinf(j.m_value.number_float))
13985 {
13986 // Infinity is 0xf97c00, -Infinity is 0xf9fc00
13987 oa->write_character(to_char_type(0xf9));
13988 oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
13989 oa->write_character(to_char_type(0x00));
13990 }
13991
13992 else
13993 {
13994 write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
13995 }
13996
13997 break;
13998 }
13999
14000 case value_t::string:
14001 {
14002 // step 1: write control byte and the string length
14003 const auto N = j.m_value.string->size();
14004
14005 if (N <= 0x17)
14006 {
14007 write_number(static_cast<std::uint8_t>(0x60 + N));
14008 }
14009
14010 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14011 {
14012 oa->write_character(to_char_type(0x78));
14013 write_number(static_cast<std::uint8_t>(N));
14014 }
14015
14016 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14017 {
14018 oa->write_character(to_char_type(0x79));
14019 write_number(static_cast<std::uint16_t>(N));
14020 }
14021
14022 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14023 {
14024 oa->write_character(to_char_type(0x7A));
14025 write_number(static_cast<std::uint32_t>(N));
14026 }
14027
14028 // LCOV_EXCL_START
14029 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14030 {
14031 oa->write_character(to_char_type(0x7B));
14032 write_number(static_cast<std::uint64_t>(N));
14033 }
14034
14035 // LCOV_EXCL_STOP
14036 // step 2: write the string
14037 oa->write_characters(
14038 reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
14039 j.m_value.string->size());
14040 break;
14041 }
14042
14043 case value_t::array:
14044 {
14045 // step 1: write control byte and the array size
14046 const auto N = j.m_value.array->size();
14047
14048 if (N <= 0x17)
14049 {
14050 write_number(static_cast<std::uint8_t>(0x80 + N));
14051 }
14052
14053 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14054 {
14055 oa->write_character(to_char_type(0x98));
14056 write_number(static_cast<std::uint8_t>(N));
14057 }
14058
14059 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14060 {
14061 oa->write_character(to_char_type(0x99));
14062 write_number(static_cast<std::uint16_t>(N));
14063 }
14064
14065 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14066 {
14067 oa->write_character(to_char_type(0x9A));
14068 write_number(static_cast<std::uint32_t>(N));
14069 }
14070
14071 // LCOV_EXCL_START
14072 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14073 {
14074 oa->write_character(to_char_type(0x9B));
14075 write_number(static_cast<std::uint64_t>(N));
14076 }
14077
14078 // LCOV_EXCL_STOP
14079
14080 // step 2: write each element
14081 for (const auto &el : *j.m_value.array)
14082 {
14083 write_cbor(el);
14084 }
14085
14086 break;
14087 }
14088
14089 case value_t::binary:
14090 {
14091 if (j.m_value.binary->has_subtype())
14092 {
14093 if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
14094 {
14095 write_number(static_cast<std::uint8_t>(0xd8));
14096 write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
14097 }
14098
14099 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
14100 {
14101 write_number(static_cast<std::uint8_t>(0xd9));
14102 write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
14103 }
14104
14105 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
14106 {
14107 write_number(static_cast<std::uint8_t>(0xda));
14108 write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
14109 }
14110
14111 else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
14112 {
14113 write_number(static_cast<std::uint8_t>(0xdb));
14114 write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
14115 }
14116 }
14117
14118 // step 1: write control byte and the binary array size
14119 const auto N = j.m_value.binary->size();
14120
14121 if (N <= 0x17)
14122 {
14123 write_number(static_cast<std::uint8_t>(0x40 + N));
14124 }
14125
14126 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14127 {
14128 oa->write_character(to_char_type(0x58));
14129 write_number(static_cast<std::uint8_t>(N));
14130 }
14131
14132 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14133 {
14134 oa->write_character(to_char_type(0x59));
14135 write_number(static_cast<std::uint16_t>(N));
14136 }
14137
14138 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14139 {
14140 oa->write_character(to_char_type(0x5A));
14141 write_number(static_cast<std::uint32_t>(N));
14142 }
14143
14144 // LCOV_EXCL_START
14145 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14146 {
14147 oa->write_character(to_char_type(0x5B));
14148 write_number(static_cast<std::uint64_t>(N));
14149 }
14150
14151 // LCOV_EXCL_STOP
14152 // step 2: write each element
14153 oa->write_characters(
14154 reinterpret_cast<const CharType *>(j.m_value.binary->data()),
14155 N);
14156 break;
14157 }
14158
14159 case value_t::object:
14160 {
14161 // step 1: write control byte and the object size
14162 const auto N = j.m_value.object->size();
14163
14164 if (N <= 0x17)
14165 {
14166 write_number(static_cast<std::uint8_t>(0xA0 + N));
14167 }
14168
14169 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14170 {
14171 oa->write_character(to_char_type(0xB8));
14172 write_number(static_cast<std::uint8_t>(N));
14173 }
14174
14175 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14176 {
14177 oa->write_character(to_char_type(0xB9));
14178 write_number(static_cast<std::uint16_t>(N));
14179 }
14180
14181 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14182 {
14183 oa->write_character(to_char_type(0xBA));
14184 write_number(static_cast<std::uint32_t>(N));
14185 }
14186
14187 // LCOV_EXCL_START
14188 else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14189 {
14190 oa->write_character(to_char_type(0xBB));
14191 write_number(static_cast<std::uint64_t>(N));
14192 }
14193
14194 // LCOV_EXCL_STOP
14195
14196 // step 2: write each element
14197 for (const auto &el : *j.m_value.object)
14198 {
14199 write_cbor(el.first);
14200 write_cbor(el.second);
14201 }
14202
14203 break;
14204 }
14205
14206 case value_t::discarded:
14207 default:
14208 break;
14209 }
14210 }
14211
14215 void write_msgpack(const BasicJsonType &j)
14216 {
14217 switch (j.type())
14218 {
14219 case value_t::null: // nil
14220 {
14221 oa->write_character(to_char_type(0xC0));
14222 break;
14223 }
14224
14225 case value_t::boolean: // true and false
14226 {
14227 oa->write_character(j.m_value.boolean
14228 ? to_char_type(0xC3)
14229 : to_char_type(0xC2));
14230 break;
14231 }
14232
14234 {
14235 if (j.m_value.number_integer >= 0)
14236 {
14237 // MessagePack does not differentiate between positive
14238 // signed integers and unsigned integers. Therefore, we used
14239 // the code from the value_t::number_unsigned case here.
14240 if (j.m_value.number_unsigned < 128)
14241 {
14242 // positive fixnum
14243 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14244 }
14245
14246 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14247 {
14248 // uint 8
14249 oa->write_character(to_char_type(0xCC));
14250 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14251 }
14252
14253 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14254 {
14255 // uint 16
14256 oa->write_character(to_char_type(0xCD));
14257 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14258 }
14259
14260 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14261 {
14262 // uint 32
14263 oa->write_character(to_char_type(0xCE));
14264 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14265 }
14266
14267 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14268 {
14269 // uint 64
14270 oa->write_character(to_char_type(0xCF));
14271 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14272 }
14273 }
14274
14275 else
14276 {
14277 if (j.m_value.number_integer >= -32)
14278 {
14279 // negative fixnum
14280 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14281 }
14282
14283 else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14284 j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14285 {
14286 // int 8
14287 oa->write_character(to_char_type(0xD0));
14288 write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14289 }
14290
14291 else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14292 j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14293 {
14294 // int 16
14295 oa->write_character(to_char_type(0xD1));
14296 write_number(static_cast<std::int16_t>(j.m_value.number_integer));
14297 }
14298
14299 else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14300 j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14301 {
14302 // int 32
14303 oa->write_character(to_char_type(0xD2));
14304 write_number(static_cast<std::int32_t>(j.m_value.number_integer));
14305 }
14306
14307 else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14308 j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14309 {
14310 // int 64
14311 oa->write_character(to_char_type(0xD3));
14312 write_number(static_cast<std::int64_t>(j.m_value.number_integer));
14313 }
14314 }
14315
14316 break;
14317 }
14318
14320 {
14321 if (j.m_value.number_unsigned < 128)
14322 {
14323 // positive fixnum
14324 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14325 }
14326
14327 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14328 {
14329 // uint 8
14330 oa->write_character(to_char_type(0xCC));
14331 write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14332 }
14333
14334 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14335 {
14336 // uint 16
14337 oa->write_character(to_char_type(0xCD));
14338 write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14339 }
14340
14341 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14342 {
14343 // uint 32
14344 oa->write_character(to_char_type(0xCE));
14345 write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14346 }
14347
14348 else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14349 {
14350 // uint 64
14351 oa->write_character(to_char_type(0xCF));
14352 write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14353 }
14354
14355 break;
14356 }
14357
14359 {
14360 write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
14361 break;
14362 }
14363
14364 case value_t::string:
14365 {
14366 // step 1: write control byte and the string length
14367 const auto N = j.m_value.string->size();
14368
14369 if (N <= 31)
14370 {
14371 // fixstr
14372 write_number(static_cast<std::uint8_t>(0xA0 | N));
14373 }
14374
14375 else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14376 {
14377 // str 8
14378 oa->write_character(to_char_type(0xD9));
14379 write_number(static_cast<std::uint8_t>(N));
14380 }
14381
14382 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14383 {
14384 // str 16
14385 oa->write_character(to_char_type(0xDA));
14386 write_number(static_cast<std::uint16_t>(N));
14387 }
14388
14389 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14390 {
14391 // str 32
14392 oa->write_character(to_char_type(0xDB));
14393 write_number(static_cast<std::uint32_t>(N));
14394 }
14395
14396 // step 2: write the string
14397 oa->write_characters(
14398 reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
14399 j.m_value.string->size());
14400 break;
14401 }
14402
14403 case value_t::array:
14404 {
14405 // step 1: write control byte and the array size
14406 const auto N = j.m_value.array->size();
14407
14408 if (N <= 15)
14409 {
14410 // fixarray
14411 write_number(static_cast<std::uint8_t>(0x90 | N));
14412 }
14413
14414 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14415 {
14416 // array 16
14417 oa->write_character(to_char_type(0xDC));
14418 write_number(static_cast<std::uint16_t>(N));
14419 }
14420
14421 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14422 {
14423 // array 32
14424 oa->write_character(to_char_type(0xDD));
14425 write_number(static_cast<std::uint32_t>(N));
14426 }
14427
14428 // step 2: write each element
14429 for (const auto &el : *j.m_value.array)
14430 {
14431 write_msgpack(el);
14432 }
14433
14434 break;
14435 }
14436
14437 case value_t::binary:
14438 {
14439 // step 0: determine if the binary type has a set subtype to
14440 // determine whether or not to use the ext or fixext types
14441 const bool use_ext = j.m_value.binary->has_subtype();
14442 // step 1: write control byte and the byte string length
14443 const auto N = j.m_value.binary->size();
14444
14445 if (N <= (std::numeric_limits<std::uint8_t>::max)())
14446 {
14447 std::uint8_t output_type{};
14448 bool fixed = true;
14449
14450 if (use_ext)
14451 {
14452 switch (N)
14453 {
14454 case 1:
14455 output_type = 0xD4; // fixext 1
14456 break;
14457
14458 case 2:
14459 output_type = 0xD5; // fixext 2
14460 break;
14461
14462 case 4:
14463 output_type = 0xD6; // fixext 4
14464 break;
14465
14466 case 8:
14467 output_type = 0xD7; // fixext 8
14468 break;
14469
14470 case 16:
14471 output_type = 0xD8; // fixext 16
14472 break;
14473
14474 default:
14475 output_type = 0xC7; // ext 8
14476 fixed = false;
14477 break;
14478 }
14479 }
14480
14481 else
14482 {
14483 output_type = 0xC4; // bin 8
14484 fixed = false;
14485 }
14486
14487 oa->write_character(to_char_type(output_type));
14488
14489 if (!fixed)
14490 {
14491 write_number(static_cast<std::uint8_t>(N));
14492 }
14493 }
14494
14495 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14496 {
14497 std::uint8_t output_type = use_ext
14498 ? 0xC8 // ext 16
14499 : 0xC5; // bin 16
14500 oa->write_character(to_char_type(output_type));
14501 write_number(static_cast<std::uint16_t>(N));
14502 }
14503
14504 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14505 {
14506 std::uint8_t output_type = use_ext
14507 ? 0xC9 // ext 32
14508 : 0xC6; // bin 32
14509 oa->write_character(to_char_type(output_type));
14510 write_number(static_cast<std::uint32_t>(N));
14511 }
14512
14513 // step 1.5: if this is an ext type, write the subtype
14514 if (use_ext)
14515 {
14516 write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14517 }
14518
14519 // step 2: write the byte string
14520 oa->write_characters(
14521 reinterpret_cast<const CharType *>(j.m_value.binary->data()),
14522 N);
14523 break;
14524 }
14525
14526 case value_t::object:
14527 {
14528 // step 1: write control byte and the object size
14529 const auto N = j.m_value.object->size();
14530
14531 if (N <= 15)
14532 {
14533 // fixmap
14534 write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
14535 }
14536
14537 else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14538 {
14539 // map 16
14540 oa->write_character(to_char_type(0xDE));
14541 write_number(static_cast<std::uint16_t>(N));
14542 }
14543
14544 else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14545 {
14546 // map 32
14547 oa->write_character(to_char_type(0xDF));
14548 write_number(static_cast<std::uint32_t>(N));
14549 }
14550
14551 // step 2: write each element
14552 for (const auto &el : *j.m_value.object)
14553 {
14554 write_msgpack(el.first);
14555 write_msgpack(el.second);
14556 }
14557
14558 break;
14559 }
14560
14561 case value_t::discarded:
14562 default:
14563 break;
14564 }
14565 }
14566
14573 void write_ubjson(const BasicJsonType &j, const bool use_count,
14574 const bool use_type, const bool add_prefix = true)
14575 {
14576 switch (j.type())
14577 {
14578 case value_t::null:
14579 {
14580 if (add_prefix)
14581 {
14582 oa->write_character(to_char_type('Z'));
14583 }
14584
14585 break;
14586 }
14587
14588 case value_t::boolean:
14589 {
14590 if (add_prefix)
14591 {
14592 oa->write_character(j.m_value.boolean
14593 ? to_char_type('T')
14594 : to_char_type('F'));
14595 }
14596
14597 break;
14598 }
14599
14601 {
14602 write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix);
14603 break;
14604 }
14605
14607 {
14608 write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix);
14609 break;
14610 }
14611
14613 {
14614 write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix);
14615 break;
14616 }
14617
14618 case value_t::string:
14619 {
14620 if (add_prefix)
14621 {
14622 oa->write_character(to_char_type('S'));
14623 }
14624
14625 write_number_with_ubjson_prefix(j.m_value.string->size(), true);
14626 oa->write_characters(
14627 reinterpret_cast<const CharType *>(j.m_value.string->c_str()),
14628 j.m_value.string->size());
14629 break;
14630 }
14631
14632 case value_t::array:
14633 {
14634 if (add_prefix)
14635 {
14636 oa->write_character(to_char_type('['));
14637 }
14638
14639 bool prefix_required = true;
14640
14641 if (use_type && !j.m_value.array->empty())
14642 {
14643 JSON_ASSERT(use_count);
14644 const CharType first_prefix = ubjson_prefix(j.front());
14645 const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
14646 [this, first_prefix](const BasicJsonType & v)
14647 {
14648 return ubjson_prefix(v) == first_prefix;
14649 });
14650
14651 if (same_prefix)
14652 {
14653 prefix_required = false;
14654 oa->write_character(to_char_type('$'));
14655 oa->write_character(first_prefix);
14656 }
14657 }
14658
14659 if (use_count)
14660 {
14661 oa->write_character(to_char_type('#'));
14662 write_number_with_ubjson_prefix(j.m_value.array->size(), true);
14663 }
14664
14665 for (const auto &el : *j.m_value.array)
14666 {
14667 write_ubjson(el, use_count, use_type, prefix_required);
14668 }
14669
14670 if (!use_count)
14671 {
14672 oa->write_character(to_char_type(']'));
14673 }
14674
14675 break;
14676 }
14677
14678 case value_t::binary:
14679 {
14680 if (add_prefix)
14681 {
14682 oa->write_character(to_char_type('['));
14683 }
14684
14685 if (use_type && !j.m_value.binary->empty())
14686 {
14687 JSON_ASSERT(use_count);
14688 oa->write_character(to_char_type('$'));
14689 oa->write_character('U');
14690 }
14691
14692 if (use_count)
14693 {
14694 oa->write_character(to_char_type('#'));
14695 write_number_with_ubjson_prefix(j.m_value.binary->size(), true);
14696 }
14697
14698 if (use_type)
14699 {
14700 oa->write_characters(
14701 reinterpret_cast<const CharType *>(j.m_value.binary->data()),
14702 j.m_value.binary->size());
14703 }
14704
14705 else
14706 {
14707 for (size_t i = 0; i < j.m_value.binary->size(); ++i)
14708 {
14709 oa->write_character(to_char_type('U'));
14710 oa->write_character(j.m_value.binary->data()[i]);
14711 }
14712 }
14713
14714 if (!use_count)
14715 {
14716 oa->write_character(to_char_type(']'));
14717 }
14718
14719 break;
14720 }
14721
14722 case value_t::object:
14723 {
14724 if (add_prefix)
14725 {
14726 oa->write_character(to_char_type('{'));
14727 }
14728
14729 bool prefix_required = true;
14730
14731 if (use_type && !j.m_value.object->empty())
14732 {
14733 JSON_ASSERT(use_count);
14734 const CharType first_prefix = ubjson_prefix(j.front());
14735 const bool same_prefix = std::all_of(j.begin(), j.end(),
14736 [this, first_prefix](const BasicJsonType & v)
14737 {
14738 return ubjson_prefix(v) == first_prefix;
14739 });
14740
14741 if (same_prefix)
14742 {
14743 prefix_required = false;
14744 oa->write_character(to_char_type('$'));
14745 oa->write_character(first_prefix);
14746 }
14747 }
14748
14749 if (use_count)
14750 {
14751 oa->write_character(to_char_type('#'));
14752 write_number_with_ubjson_prefix(j.m_value.object->size(), true);
14753 }
14754
14755 for (const auto &el : *j.m_value.object)
14756 {
14757 write_number_with_ubjson_prefix(el.first.size(), true);
14758 oa->write_characters(
14759 reinterpret_cast<const CharType *>(el.first.c_str()),
14760 el.first.size());
14761 write_ubjson(el.second, use_count, use_type, prefix_required);
14762 }
14763
14764 if (!use_count)
14765 {
14766 oa->write_character(to_char_type('}'));
14767 }
14768
14769 break;
14770 }
14771
14772 case value_t::discarded:
14773 default:
14774 break;
14775 }
14776 }
14777
14778private:
14780 // BSON //
14782
14787 static std::size_t calc_bson_entry_header_size(const string_t &name, const BasicJsonType &j)
14788 {
14789 const auto it = name.find(static_cast<typename string_t::value_type>(0));
14790
14791 if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
14792 {
14793 JSON_THROW(out_of_range::create(409, "BSON key cannot contain code point U+0000 (at byte " + std::to_string(it) + ")", j));
14794 static_cast<void>(j);
14795 }
14796
14797 return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
14798 }
14799
14803 void write_bson_entry_header(const string_t &name,
14804 const std::uint8_t element_type)
14805 {
14806 oa->write_character(to_char_type(element_type)); // boolean
14807 oa->write_characters(
14808 reinterpret_cast<const CharType *>(name.c_str()),
14809 name.size() + 1u);
14810 }
14811
14815 void write_bson_boolean(const string_t &name,
14816 const bool value)
14817 {
14818 write_bson_entry_header(name, 0x08);
14819 oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
14820 }
14821
14825 void write_bson_double(const string_t &name,
14826 const double value)
14827 {
14828 write_bson_entry_header(name, 0x01);
14829 write_number<double, true>(value);
14830 }
14831
14835 static std::size_t calc_bson_string_size(const string_t &value)
14836 {
14837 return sizeof(std::int32_t) + value.size() + 1ul;
14838 }
14839
14843 void write_bson_string(const string_t &name,
14844 const string_t &value)
14845 {
14846 write_bson_entry_header(name, 0x02);
14847 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size() + 1ul));
14848 oa->write_characters(
14849 reinterpret_cast<const CharType *>(value.c_str()),
14850 value.size() + 1);
14851 }
14852
14856 void write_bson_null(const string_t &name)
14857 {
14858 write_bson_entry_header(name, 0x0A);
14859 }
14860
14864 static std::size_t calc_bson_integer_size(const std::int64_t value)
14865 {
14866 return (std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)()
14867 ? sizeof(std::int32_t)
14868 : sizeof(std::int64_t);
14869 }
14870
14874 void write_bson_integer(const string_t &name,
14875 const std::int64_t value)
14876 {
14877 if ((std::numeric_limits<std::int32_t>::min)() <= value && value <= (std::numeric_limits<std::int32_t>::max)())
14878 {
14879 write_bson_entry_header(name, 0x10); // int32
14880 write_number<std::int32_t, true>(static_cast<std::int32_t>(value));
14881 }
14882
14883 else
14884 {
14885 write_bson_entry_header(name, 0x12); // int64
14886 write_number<std::int64_t, true>(static_cast<std::int64_t>(value));
14887 }
14888 }
14889
14893 static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
14894 {
14895 return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14896 ? sizeof(std::int32_t)
14897 : sizeof(std::int64_t);
14898 }
14899
14903 void write_bson_unsigned(const string_t &name,
14904 const BasicJsonType &j)
14905 {
14906 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
14907 {
14908 write_bson_entry_header(name, 0x10 /* int32 */);
14909 write_number<std::int32_t, true>(static_cast<std::int32_t>(j.m_value.number_unsigned));
14910 }
14911
14912 else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
14913 {
14914 write_bson_entry_header(name, 0x12 /* int64 */);
14915 write_number<std::int64_t, true>(static_cast<std::int64_t>(j.m_value.number_unsigned));
14916 }
14917
14918 else
14919 {
14920 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));
14921 }
14922 }
14923
14927 void write_bson_object_entry(const string_t &name,
14928 const typename BasicJsonType::object_t &value)
14929 {
14930 write_bson_entry_header(name, 0x03); // object
14932 }
14933
14937 static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
14938 {
14939 std::size_t array_index = 0ul;
14940 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)
14941 {
14942 return result + calc_bson_element_size(std::to_string(array_index++), el);
14943 });
14944 return sizeof(std::int32_t) + embedded_document_size + 1ul;
14945 }
14946
14950 static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t &value)
14951 {
14952 return sizeof(std::int32_t) + value.size() + 1ul;
14953 }
14954
14958 void write_bson_array(const string_t &name,
14959 const typename BasicJsonType::array_t &value)
14960 {
14961 write_bson_entry_header(name, 0x04); // array
14962 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_array_size(value)));
14963 std::size_t array_index = 0ul;
14964
14965 for (const auto &el : value)
14966 {
14967 write_bson_element(std::to_string(array_index++), el);
14968 }
14969
14970 oa->write_character(to_char_type(0x00));
14971 }
14972
14976 void write_bson_binary(const string_t &name,
14977 const binary_t &value)
14978 {
14979 write_bson_entry_header(name, 0x05);
14980 write_number<std::int32_t, true>(static_cast<std::int32_t>(value.size()));
14981 write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : std::uint8_t(0x00));
14982 oa->write_characters(reinterpret_cast<const CharType *>(value.data()), value.size());
14983 }
14984
14989 static std::size_t calc_bson_element_size(const string_t &name,
14990 const BasicJsonType &j)
14991 {
14992 const auto header_size = calc_bson_entry_header_size(name, j);
14993
14994 switch (j.type())
14995 {
14996 case value_t::object:
14997 return header_size + calc_bson_object_size(*j.m_value.object);
14998
14999 case value_t::array:
15000 return header_size + calc_bson_array_size(*j.m_value.array);
15001
15002 case value_t::binary:
15003 return header_size + calc_bson_binary_size(*j.m_value.binary);
15004
15005 case value_t::boolean:
15006 return header_size + 1ul;
15007
15009 return header_size + 8ul;
15010
15012 return header_size + calc_bson_integer_size(j.m_value.number_integer);
15013
15015 return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
15016
15017 case value_t::string:
15018 return header_size + calc_bson_string_size(*j.m_value.string);
15019
15020 case value_t::null:
15021 return header_size + 0ul;
15022
15023 // LCOV_EXCL_START
15024 case value_t::discarded:
15025 default:
15026 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
15027 return 0ul;
15028 // LCOV_EXCL_STOP
15029 }
15030 }
15031
15038 void write_bson_element(const string_t &name,
15039 const BasicJsonType &j)
15040 {
15041 switch (j.type())
15042 {
15043 case value_t::object:
15044 return write_bson_object_entry(name, *j.m_value.object);
15045
15046 case value_t::array:
15047 return write_bson_array(name, *j.m_value.array);
15048
15049 case value_t::binary:
15050 return write_bson_binary(name, *j.m_value.binary);
15051
15052 case value_t::boolean:
15053 return write_bson_boolean(name, j.m_value.boolean);
15054
15056 return write_bson_double(name, j.m_value.number_float);
15057
15059 return write_bson_integer(name, j.m_value.number_integer);
15060
15062 return write_bson_unsigned(name, j);
15063
15064 case value_t::string:
15065 return write_bson_string(name, *j.m_value.string);
15066
15067 case value_t::null:
15068 return write_bson_null(name);
15069
15070 // LCOV_EXCL_START
15071 case value_t::discarded:
15072 default:
15073 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
15074 return;
15075 // LCOV_EXCL_STOP
15076 }
15077 }
15078
15085 static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
15086 {
15087 std::size_t document_size = std::accumulate(value.begin(), value.end(), std::size_t(0),
15088 [](size_t result, const typename BasicJsonType::object_t::value_type & el)
15089 {
15090 return result += calc_bson_element_size(el.first, el.second);
15091 });
15092 return sizeof(std::int32_t) + document_size + 1ul;
15093 }
15094
15099 void write_bson_object(const typename BasicJsonType::object_t &value)
15100 {
15101 write_number<std::int32_t, true>(static_cast<std::int32_t>(calc_bson_object_size(value)));
15102
15103 for (const auto &el : value)
15104 {
15105 write_bson_element(el.first, el.second);
15106 }
15107
15108 oa->write_character(to_char_type(0x00));
15109 }
15110
15112 // CBOR //
15114
15115 static constexpr CharType get_cbor_float_prefix(float /*unused*/)
15116 {
15117 return to_char_type(0xFA); // Single-Precision Float
15118 }
15119
15120 static constexpr CharType get_cbor_float_prefix(double /*unused*/)
15121 {
15122 return to_char_type(0xFB); // Double-Precision Float
15123 }
15124
15126 // MsgPack //
15128
15129 static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
15130 {
15131 return to_char_type(0xCA); // float 32
15132 }
15133
15134 static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
15135 {
15136 return to_char_type(0xCB); // float 64
15137 }
15138
15140 // UBJSON //
15142
15143 // UBJSON: write number (floating point)
15144 template<typename NumberType, typename std::enable_if<
15145 std::is_floating_point<NumberType>::value, int>::type = 0>
15146 void write_number_with_ubjson_prefix(const NumberType n,
15147 const bool add_prefix)
15148 {
15149 if (add_prefix)
15150 {
15151 oa->write_character(get_ubjson_float_prefix(n));
15152 }
15153
15154 write_number(n);
15155 }
15156
15157 // UBJSON: write number (unsigned integer)
15158 template<typename NumberType, typename std::enable_if<
15159 std::is_unsigned<NumberType>::value, int>::type = 0>
15160 void write_number_with_ubjson_prefix(const NumberType n,
15161 const bool add_prefix)
15162 {
15163 if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15164 {
15165 if (add_prefix)
15166 {
15167 oa->write_character(to_char_type('i')); // int8
15168 }
15169
15170 write_number(static_cast<std::uint8_t>(n));
15171 }
15172
15173 else if (n <= (std::numeric_limits<std::uint8_t>::max)())
15174 {
15175 if (add_prefix)
15176 {
15177 oa->write_character(to_char_type('U')); // uint8
15178 }
15179
15180 write_number(static_cast<std::uint8_t>(n));
15181 }
15182
15183 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15184 {
15185 if (add_prefix)
15186 {
15187 oa->write_character(to_char_type('I')); // int16
15188 }
15189
15190 write_number(static_cast<std::int16_t>(n));
15191 }
15192
15193 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15194 {
15195 if (add_prefix)
15196 {
15197 oa->write_character(to_char_type('l')); // int32
15198 }
15199
15200 write_number(static_cast<std::int32_t>(n));
15201 }
15202
15203 else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15204 {
15205 if (add_prefix)
15206 {
15207 oa->write_character(to_char_type('L')); // int64
15208 }
15209
15210 write_number(static_cast<std::int64_t>(n));
15211 }
15212
15213 else
15214 {
15215 if (add_prefix)
15216 {
15217 oa->write_character(to_char_type('H')); // high-precision number
15218 }
15219
15220 const auto number = BasicJsonType(n).dump();
15221 write_number_with_ubjson_prefix(number.size(), true);
15222
15223 for (std::size_t i = 0; i < number.size(); ++i)
15224 {
15225 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15226 }
15227 }
15228 }
15229
15230 // UBJSON: write number (signed integer)
15231 template < typename NumberType, typename std::enable_if <
15232 std::is_signed<NumberType>::value &&
15233 !std::is_floating_point<NumberType>::value, int >::type = 0 >
15234 void write_number_with_ubjson_prefix(const NumberType n,
15235 const bool add_prefix)
15236 {
15237 if ((std::numeric_limits<std::int8_t>::min)() <= n && n <= (std::numeric_limits<std::int8_t>::max)())
15238 {
15239 if (add_prefix)
15240 {
15241 oa->write_character(to_char_type('i')); // int8
15242 }
15243
15244 write_number(static_cast<std::int8_t>(n));
15245 }
15246
15247 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)()))
15248 {
15249 if (add_prefix)
15250 {
15251 oa->write_character(to_char_type('U')); // uint8
15252 }
15253
15254 write_number(static_cast<std::uint8_t>(n));
15255 }
15256
15257 else if ((std::numeric_limits<std::int16_t>::min)() <= n && n <= (std::numeric_limits<std::int16_t>::max)())
15258 {
15259 if (add_prefix)
15260 {
15261 oa->write_character(to_char_type('I')); // int16
15262 }
15263
15264 write_number(static_cast<std::int16_t>(n));
15265 }
15266
15267 else if ((std::numeric_limits<std::int32_t>::min)() <= n && n <= (std::numeric_limits<std::int32_t>::max)())
15268 {
15269 if (add_prefix)
15270 {
15271 oa->write_character(to_char_type('l')); // int32
15272 }
15273
15274 write_number(static_cast<std::int32_t>(n));
15275 }
15276
15277 else if ((std::numeric_limits<std::int64_t>::min)() <= n && n <= (std::numeric_limits<std::int64_t>::max)())
15278 {
15279 if (add_prefix)
15280 {
15281 oa->write_character(to_char_type('L')); // int64
15282 }
15283
15284 write_number(static_cast<std::int64_t>(n));
15285 }
15286
15287 // LCOV_EXCL_START
15288 else
15289 {
15290 if (add_prefix)
15291 {
15292 oa->write_character(to_char_type('H')); // high-precision number
15293 }
15294
15295 const auto number = BasicJsonType(n).dump();
15296 write_number_with_ubjson_prefix(number.size(), true);
15297
15298 for (std::size_t i = 0; i < number.size(); ++i)
15299 {
15300 oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15301 }
15302 }
15303
15304 // LCOV_EXCL_STOP
15305 }
15306
15310 CharType ubjson_prefix(const BasicJsonType &j) const noexcept
15311 {
15312 switch (j.type())
15313 {
15314 case value_t::null:
15315 return 'Z';
15316
15317 case value_t::boolean:
15318 return j.m_value.boolean ? 'T' : 'F';
15319
15321 {
15322 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)())
15323 {
15324 return 'i';
15325 }
15326
15327 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)())
15328 {
15329 return 'U';
15330 }
15331
15332 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)())
15333 {
15334 return 'I';
15335 }
15336
15337 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)())
15338 {
15339 return 'l';
15340 }
15341
15342 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)())
15343 {
15344 return 'L';
15345 }
15346
15347 // anything else is treated as high-precision number
15348 return 'H'; // LCOV_EXCL_LINE
15349 }
15350
15352 {
15353 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15354 {
15355 return 'i';
15356 }
15357
15358 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15359 {
15360 return 'U';
15361 }
15362
15363 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15364 {
15365 return 'I';
15366 }
15367
15368 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15369 {
15370 return 'l';
15371 }
15372
15373 if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15374 {
15375 return 'L';
15376 }
15377
15378 // anything else is treated as high-precision number
15379 return 'H'; // LCOV_EXCL_LINE
15380 }
15381
15383 return get_ubjson_float_prefix(j.m_value.number_float);
15384
15385 case value_t::string:
15386 return 'S';
15387
15388 case value_t::array: // fallthrough
15389 case value_t::binary:
15390 return '[';
15391
15392 case value_t::object:
15393 return '{';
15394
15395 case value_t::discarded:
15396 default: // discarded values
15397 return 'N';
15398 }
15399 }
15400
15401 static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15402 {
15403 return 'd'; // float 32
15404 }
15405
15406 static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15407 {
15408 return 'D'; // float 64
15409 }
15410
15412 // Utility functions //
15414
15415 /*
15416 @brief write a number to output input
15417 @param[in] n number of type @a NumberType
15418 @tparam NumberType the type of the number
15419 @tparam OutputIsLittleEndian Set to true if output data is
15420 required to be little endian
15421
15422 @note This function needs to respect the system's endianess, because bytes
15423 in CBOR, MessagePack, and UBJSON are stored in network order (big
15424 endian) and therefore need reordering on little endian systems.
15425 */
15426 template<typename NumberType, bool OutputIsLittleEndian = false>
15427 void write_number(const NumberType n)
15428 {
15429 // step 1: write number to array of length NumberType
15430 std::array<CharType, sizeof(NumberType)> vec{};
15431 std::memcpy(vec.data(), &n, sizeof(NumberType));
15432
15433 // step 2: write array to output (with possible reordering)
15434 if (is_little_endian != OutputIsLittleEndian)
15435 {
15436 // reverse byte order prior to conversion if necessary
15437 std::reverse(vec.begin(), vec.end());
15438 }
15439
15440 oa->write_characters(vec.data(), sizeof(NumberType));
15441 }
15442
15443 void write_compact_float(const number_float_t n, detail::input_format_t format)
15444 {
15445#ifdef __GNUC__
15446#pragma GCC diagnostic push
15447#pragma GCC diagnostic ignored "-Wfloat-equal"
15448#endif
15449
15450 if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
15451 static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
15452 static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
15453 {
15454 oa->write_character(format == detail::input_format_t::cbor
15455 ? get_cbor_float_prefix(static_cast<float>(n))
15456 : get_msgpack_float_prefix(static_cast<float>(n)));
15457 write_number(static_cast<float>(n));
15458 }
15459
15460 else
15461 {
15462 oa->write_character(format == detail::input_format_t::cbor
15463 ? get_cbor_float_prefix(n)
15464 : get_msgpack_float_prefix(n));
15465 write_number(n);
15466 }
15467
15468#ifdef __GNUC__
15469#pragma GCC diagnostic pop
15470#endif
15471 }
15472
15473public:
15474 // The following to_char_type functions are implement the conversion
15475 // between uint8_t and CharType. In case CharType is not unsigned,
15476 // such a conversion is required to allow values greater than 128.
15477 // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
15478 template < typename C = CharType,
15479 enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
15480 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15481 {
15482 return *reinterpret_cast<char *>(&x);
15483 }
15484
15485 template < typename C = CharType,
15486 enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
15487 static CharType to_char_type(std::uint8_t x) noexcept
15488 {
15489 static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
15490 static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
15491 CharType result;
15492 std::memcpy(&result, &x, sizeof(x));
15493 return result;
15494 }
15495
15496 template<typename C = CharType,
15497 enable_if_t<std::is_unsigned<C>::value>* = nullptr>
15498 static constexpr CharType to_char_type(std::uint8_t x) noexcept
15499 {
15500 return x;
15501 }
15502
15503 template < typename InputCharType, typename C = CharType,
15504 enable_if_t <
15505 std::is_signed<C>::value &&
15506 std::is_signed<char>::value &&
15507 std::is_same<char, typename std::remove_cv<InputCharType>::type>::value
15508 > * = nullptr >
15509 static constexpr CharType to_char_type(InputCharType x) noexcept
15510 {
15511 return x;
15512 }
15513
15514private:
15517
15520};
15521} // namespace detail
15522} // namespace nlohmann
15523
15524// #include <nlohmann/detail/output/output_adapters.hpp>
15525
15526// #include <nlohmann/detail/output/serializer.hpp>
15527
15528
15529#include <algorithm> // reverse, remove, fill, find, none_of
15530#include <array> // array
15531#include <clocale> // localeconv, lconv
15532#include <cmath> // labs, isfinite, isnan, signbit
15533#include <cstddef> // size_t, ptrdiff_t
15534#include <cstdint> // uint8_t
15535#include <cstdio> // snprintf
15536#include <limits> // numeric_limits
15537#include <string> // string, char_traits
15538#include <type_traits> // is_same
15539#include <utility> // move
15540
15541// #include <nlohmann/detail/conversions/to_chars.hpp>
15542
15543
15544#include <array> // array
15545#include <cmath> // signbit, isfinite
15546#include <cstdint> // intN_t, uintN_t
15547#include <cstring> // memcpy, memmove
15548#include <limits> // numeric_limits
15549#include <type_traits> // conditional
15550
15551// #include <nlohmann/detail/macro_scope.hpp>
15552
15553
15554namespace nlohmann
15555{
15556namespace detail
15557{
15558
15578namespace dtoa_impl
15579{
15580
15581template<typename Target, typename Source>
15582Target reinterpret_bits(const Source source)
15583{
15584 static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
15585 Target target;
15586 std::memcpy(&target, &source, sizeof(Source));
15587 return target;
15588}
15589
15590struct diyfp // f * 2^e
15591{
15592 static constexpr int kPrecision = 64; // = q
15593
15594 std::uint64_t f = 0;
15595 int e = 0;
15596
15597 constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
15598
15603 static diyfp sub(const diyfp &x, const diyfp &y) noexcept
15604 {
15605 JSON_ASSERT(x.e == y.e);
15606 JSON_ASSERT(x.f >= y.f);
15607 return {x.f - y.f, x.e};
15608 }
15609
15614 static diyfp mul(const diyfp &x, const diyfp &y) noexcept
15615 {
15616 static_assert(kPrecision == 64, "internal error");
15617 // Computes:
15618 // f = round((x.f * y.f) / 2^q)
15619 // e = x.e + y.e + q
15620 // Emulate the 64-bit * 64-bit multiplication:
15621 //
15622 // p = u * v
15623 // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
15624 // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
15625 // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
15626 // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
15627 // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
15628 // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
15629 // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
15630 //
15631 // (Since Q might be larger than 2^32 - 1)
15632 //
15633 // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
15634 //
15635 // (Q_hi + H does not overflow a 64-bit int)
15636 //
15637 // = p_lo + 2^64 p_hi
15638 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15639 const std::uint64_t u_hi = x.f >> 32u;
15640 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15641 const std::uint64_t v_hi = y.f >> 32u;
15642 const std::uint64_t p0 = u_lo * v_lo;
15643 const std::uint64_t p1 = u_lo * v_hi;
15644 const std::uint64_t p2 = u_hi * v_lo;
15645 const std::uint64_t p3 = u_hi * v_hi;
15646 const std::uint64_t p0_hi = p0 >> 32u;
15647 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15648 const std::uint64_t p1_hi = p1 >> 32u;
15649 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15650 const std::uint64_t p2_hi = p2 >> 32u;
15651 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15652 // The full product might now be computed as
15653 //
15654 // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
15655 // p_lo = p0_lo + (Q << 32)
15656 //
15657 // But in this particular case here, the full p_lo is not required.
15658 // Effectively we only need to add the highest bit in p_lo to p_hi (and
15659 // Q_hi + 1 does not overflow).
15660 Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
15661 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15662 return {h, x.e + y.e + 64};
15663 }
15664
15669 static diyfp normalize(diyfp x) noexcept
15670 {
15671 JSON_ASSERT(x.f != 0);
15672
15673 while ((x.f >> 63u) == 0)
15674 {
15675 x.f <<= 1u;
15676 x.e--;
15677 }
15678
15679 return x;
15680 }
15681
15686 static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
15687 {
15688 const int delta = x.e - target_exponent;
15689 JSON_ASSERT(delta >= 0);
15690 JSON_ASSERT(((x.f << delta) >> delta) == x.f);
15691 return {x.f << delta, target_exponent};
15692 }
15693};
15694
15696{
15697 diyfp w;
15698 diyfp minus;
15699 diyfp plus;
15700};
15701
15708template<typename FloatType>
15710{
15711 JSON_ASSERT(std::isfinite(value));
15712 JSON_ASSERT(value > 0);
15713 // Convert the IEEE representation into a diyfp.
15714 //
15715 // If v is denormal:
15716 // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
15717 // If v is normalized:
15718 // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
15719 static_assert(std::numeric_limits<FloatType>::is_iec559,
15720 "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
15721 constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
15722 constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
15723 constexpr int kMinExp = 1 - kBias;
15724 constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
15725 using bits_type = typename std::conditional<kPrecision == 24, std::uint32_t, std::uint64_t >::type;
15726 const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
15727 const std::uint64_t E = bits >> (kPrecision - 1);
15728 const std::uint64_t F = bits & (kHiddenBit - 1);
15729 const bool is_denormal = E == 0;
15730 const diyfp v = is_denormal
15731 ? diyfp(F, kMinExp)
15732 : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
15733 // Compute the boundaries m- and m+ of the floating-point value
15734 // v = f * 2^e.
15735 //
15736 // Determine v- and v+, the floating-point predecessor and successor if v,
15737 // respectively.
15738 //
15739 // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
15740 // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
15741 //
15742 // v+ = v + 2^e
15743 //
15744 // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
15745 // between m- and m+ round to v, regardless of how the input rounding
15746 // algorithm breaks ties.
15747 //
15748 // ---+-------------+-------------+-------------+-------------+--- (A)
15749 // v- m- v m+ v+
15750 //
15751 // -----------------+------+------+-------------+-------------+--- (B)
15752 // v- m- v m+ v+
15753 const bool lower_boundary_is_closer = F == 0 && E > 1;
15754 const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
15755 const diyfp m_minus = lower_boundary_is_closer
15756 ? diyfp(4 * v.f - 1, v.e - 2) // (B)
15757 : diyfp(2 * v.f - 1, v.e - 1); // (A)
15758 // Determine the normalized w+ = m+.
15759 const diyfp w_plus = diyfp::normalize(m_plus);
15760 // Determine w- = m- such that e_(w-) = e_(w+).
15761 const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
15762 return {diyfp::normalize(v), w_minus, w_plus};
15763}
15764
15765// Given normalized diyfp w, Grisu needs to find a (normalized) cached
15766// power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
15767// within a certain range [alpha, gamma] (Definition 3.2 from [1])
15768//
15769// alpha <= e = e_c + e_w + q <= gamma
15770//
15771// or
15772//
15773// f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
15774// <= f_c * f_w * 2^gamma
15775//
15776// Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
15777//
15778// 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
15779//
15780// or
15781//
15782// 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
15783//
15784// The choice of (alpha,gamma) determines the size of the table and the form of
15785// the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
15786// in practice:
15787//
15788// The idea is to cut the number c * w = f * 2^e into two parts, which can be
15789// processed independently: An integral part p1, and a fractional part p2:
15790//
15791// f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
15792// = (f div 2^-e) + (f mod 2^-e) * 2^e
15793// = p1 + p2 * 2^e
15794//
15795// The conversion of p1 into decimal form requires a series of divisions and
15796// modulos by (a power of) 10. These operations are faster for 32-bit than for
15797// 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
15798// achieved by choosing
15799//
15800// -e >= 32 or e <= -32 := gamma
15801//
15802// In order to convert the fractional part
15803//
15804// p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
15805//
15806// into decimal form, the fraction is repeatedly multiplied by 10 and the digits
15807// d[-i] are extracted in order:
15808//
15809// (10 * p2) div 2^-e = d[-1]
15810// (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
15811//
15812// The multiplication by 10 must not overflow. It is sufficient to choose
15813//
15814// 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
15815//
15816// Since p2 = f mod 2^-e < 2^-e,
15817//
15818// -e <= 60 or e >= -60 := alpha
15819
15820constexpr int kAlpha = -60;
15821constexpr int kGamma = -32;
15822
15823struct cached_power // c = f * 2^e ~= 10^k
15824{
15825 std::uint64_t f;
15826 int e;
15827 int k;
15828};
15829
15838{
15839 // Now
15840 //
15841 // alpha <= e_c + e + q <= gamma (1)
15842 // ==> f_c * 2^alpha <= c * 2^e * 2^q
15843 //
15844 // and since the c's are normalized, 2^(q-1) <= f_c,
15845 //
15846 // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
15847 // ==> 2^(alpha - e - 1) <= c
15848 //
15849 // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
15850 //
15851 // k = ceil( log_10( 2^(alpha - e - 1) ) )
15852 // = ceil( (alpha - e - 1) * log_10(2) )
15853 //
15854 // From the paper:
15855 // "In theory the result of the procedure could be wrong since c is rounded,
15856 // and the computation itself is approximated [...]. In practice, however,
15857 // this simple function is sufficient."
15858 //
15859 // For IEEE double precision floating-point numbers converted into
15860 // normalized diyfp's w = f * 2^e, with q = 64,
15861 //
15862 // e >= -1022 (min IEEE exponent)
15863 // -52 (p - 1)
15864 // -52 (p - 1, possibly normalize denormal IEEE numbers)
15865 // -11 (normalize the diyfp)
15866 // = -1137
15867 //
15868 // and
15869 //
15870 // e <= +1023 (max IEEE exponent)
15871 // -52 (p - 1)
15872 // -11 (normalize the diyfp)
15873 // = 960
15874 //
15875 // This binary exponent range [-1137,960] results in a decimal exponent
15876 // range [-307,324]. One does not need to store a cached power for each
15877 // k in this range. For each such k it suffices to find a cached power
15878 // such that the exponent of the product lies in [alpha,gamma].
15879 // This implies that the difference of the decimal exponents of adjacent
15880 // table entries must be less than or equal to
15881 //
15882 // floor( (gamma - alpha) * log_10(2) ) = 8.
15883 //
15884 // (A smaller distance gamma-alpha would require a larger table.)
15885 // NB:
15886 // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
15887 constexpr int kCachedPowersMinDecExp = -300;
15888 constexpr int kCachedPowersDecStep = 8;
15889 static constexpr std::array<cached_power, 79> kCachedPowers =
15890 {
15891 {
15892 { 0xAB70FE17C79AC6CA, -1060, -300 },
15893 { 0xFF77B1FCBEBCDC4F, -1034, -292 },
15894 { 0xBE5691EF416BD60C, -1007, -284 },
15895 { 0x8DD01FAD907FFC3C, -980, -276 },
15896 { 0xD3515C2831559A83, -954, -268 },
15897 { 0x9D71AC8FADA6C9B5, -927, -260 },
15898 { 0xEA9C227723EE8BCB, -901, -252 },
15899 { 0xAECC49914078536D, -874, -244 },
15900 { 0x823C12795DB6CE57, -847, -236 },
15901 { 0xC21094364DFB5637, -821, -228 },
15902 { 0x9096EA6F3848984F, -794, -220 },
15903 { 0xD77485CB25823AC7, -768, -212 },
15904 { 0xA086CFCD97BF97F4, -741, -204 },
15905 { 0xEF340A98172AACE5, -715, -196 },
15906 { 0xB23867FB2A35B28E, -688, -188 },
15907 { 0x84C8D4DFD2C63F3B, -661, -180 },
15908 { 0xC5DD44271AD3CDBA, -635, -172 },
15909 { 0x936B9FCEBB25C996, -608, -164 },
15910 { 0xDBAC6C247D62A584, -582, -156 },
15911 { 0xA3AB66580D5FDAF6, -555, -148 },
15912 { 0xF3E2F893DEC3F126, -529, -140 },
15913 { 0xB5B5ADA8AAFF80B8, -502, -132 },
15914 { 0x87625F056C7C4A8B, -475, -124 },
15915 { 0xC9BCFF6034C13053, -449, -116 },
15916 { 0x964E858C91BA2655, -422, -108 },
15917 { 0xDFF9772470297EBD, -396, -100 },
15918 { 0xA6DFBD9FB8E5B88F, -369, -92 },
15919 { 0xF8A95FCF88747D94, -343, -84 },
15920 { 0xB94470938FA89BCF, -316, -76 },
15921 { 0x8A08F0F8BF0F156B, -289, -68 },
15922 { 0xCDB02555653131B6, -263, -60 },
15923 { 0x993FE2C6D07B7FAC, -236, -52 },
15924 { 0xE45C10C42A2B3B06, -210, -44 },
15925 { 0xAA242499697392D3, -183, -36 },
15926 { 0xFD87B5F28300CA0E, -157, -28 },
15927 { 0xBCE5086492111AEB, -130, -20 },
15928 { 0x8CBCCC096F5088CC, -103, -12 },
15929 { 0xD1B71758E219652C, -77, -4 },
15930 { 0x9C40000000000000, -50, 4 },
15931 { 0xE8D4A51000000000, -24, 12 },
15932 { 0xAD78EBC5AC620000, 3, 20 },
15933 { 0x813F3978F8940984, 30, 28 },
15934 { 0xC097CE7BC90715B3, 56, 36 },
15935 { 0x8F7E32CE7BEA5C70, 83, 44 },
15936 { 0xD5D238A4ABE98068, 109, 52 },
15937 { 0x9F4F2726179A2245, 136, 60 },
15938 { 0xED63A231D4C4FB27, 162, 68 },
15939 { 0xB0DE65388CC8ADA8, 189, 76 },
15940 { 0x83C7088E1AAB65DB, 216, 84 },
15941 { 0xC45D1DF942711D9A, 242, 92 },
15942 { 0x924D692CA61BE758, 269, 100 },
15943 { 0xDA01EE641A708DEA, 295, 108 },
15944 { 0xA26DA3999AEF774A, 322, 116 },
15945 { 0xF209787BB47D6B85, 348, 124 },
15946 { 0xB454E4A179DD1877, 375, 132 },
15947 { 0x865B86925B9BC5C2, 402, 140 },
15948 { 0xC83553C5C8965D3D, 428, 148 },
15949 { 0x952AB45CFA97A0B3, 455, 156 },
15950 { 0xDE469FBD99A05FE3, 481, 164 },
15951 { 0xA59BC234DB398C25, 508, 172 },
15952 { 0xF6C69A72A3989F5C, 534, 180 },
15953 { 0xB7DCBF5354E9BECE, 561, 188 },
15954 { 0x88FCF317F22241E2, 588, 196 },
15955 { 0xCC20CE9BD35C78A5, 614, 204 },
15956 { 0x98165AF37B2153DF, 641, 212 },
15957 { 0xE2A0B5DC971F303A, 667, 220 },
15958 { 0xA8D9D1535CE3B396, 694, 228 },
15959 { 0xFB9B7CD9A4A7443C, 720, 236 },
15960 { 0xBB764C4CA7A44410, 747, 244 },
15961 { 0x8BAB8EEFB6409C1A, 774, 252 },
15962 { 0xD01FEF10A657842C, 800, 260 },
15963 { 0x9B10A4E5E9913129, 827, 268 },
15964 { 0xE7109BFBA19C0C9D, 853, 276 },
15965 { 0xAC2820D9623BF429, 880, 284 },
15966 { 0x80444B5E7AA7CF85, 907, 292 },
15967 { 0xBF21E44003ACDD2D, 933, 300 },
15968 { 0x8E679C2F5E44FF8F, 960, 308 },
15969 { 0xD433179D9C8CB841, 986, 316 },
15970 { 0x9E19DB92B4E31BA9, 1013, 324 },
15971 }
15972 };
15973 // This computation gives exactly the same results for k as
15974 // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
15975 // for |e| <= 1500, but doesn't require floating-point operations.
15976 // NB: log_10(2) ~= 78913 / 2^18
15977 JSON_ASSERT(e >= -1500);
15978 JSON_ASSERT(e <= 1500);
15979 const int f = kAlpha - e - 1;
15980 const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
15981 const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
15982 JSON_ASSERT(index >= 0);
15983 JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
15984 const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
15985 JSON_ASSERT(kAlpha <= cached.e + e + 64);
15986 JSON_ASSERT(kGamma >= cached.e + e + 64);
15987 return cached;
15988}
15989
15994inline int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
15995{
15996 // LCOV_EXCL_START
15997 if (n >= 1000000000)
15998 {
15999 pow10 = 1000000000;
16000 return 10;
16001 }
16002
16003 // LCOV_EXCL_STOP
16004 if (n >= 100000000)
16005 {
16006 pow10 = 100000000;
16007 return 9;
16008 }
16009
16010 if (n >= 10000000)
16011 {
16012 pow10 = 10000000;
16013 return 8;
16014 }
16015
16016 if (n >= 1000000)
16017 {
16018 pow10 = 1000000;
16019 return 7;
16020 }
16021
16022 if (n >= 100000)
16023 {
16024 pow10 = 100000;
16025 return 6;
16026 }
16027
16028 if (n >= 10000)
16029 {
16030 pow10 = 10000;
16031 return 5;
16032 }
16033
16034 if (n >= 1000)
16035 {
16036 pow10 = 1000;
16037 return 4;
16038 }
16039
16040 if (n >= 100)
16041 {
16042 pow10 = 100;
16043 return 3;
16044 }
16045
16046 if (n >= 10)
16047 {
16048 pow10 = 10;
16049 return 2;
16050 }
16051
16052 pow10 = 1;
16053 return 1;
16054}
16055
16056inline void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta,
16057 std::uint64_t rest, std::uint64_t ten_k)
16058{
16059 JSON_ASSERT(len >= 1);
16060 JSON_ASSERT(dist <= delta);
16061 JSON_ASSERT(rest <= delta);
16062 JSON_ASSERT(ten_k > 0);
16063
16064 // <--------------------------- delta ---->
16065 // <---- dist --------->
16066 // --------------[------------------+-------------------]--------------
16067 // M- w M+
16068 //
16069 // ten_k
16070 // <------>
16071 // <---- rest ---->
16072 // --------------[------------------+----+--------------]--------------
16073 // w V
16074 // = buf * 10^k
16075 //
16076 // ten_k represents a unit-in-the-last-place in the decimal representation
16077 // stored in buf.
16078 // Decrement buf by ten_k while this takes buf closer to w.
16079
16080 // The tests are written in this order to avoid overflow in unsigned
16081 // integer arithmetic.
16082
16083 while (rest < dist
16084 && delta - rest >= ten_k
16085 && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
16086 {
16087 JSON_ASSERT(buf[len - 1] != '0');
16088 buf[len - 1]--;
16089 rest += ten_k;
16090 }
16091}
16092
16097inline void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent,
16098 diyfp M_minus, diyfp w, diyfp M_plus)
16099{
16100 static_assert(kAlpha >= -60, "internal error");
16101 static_assert(kGamma <= -32, "internal error");
16102 // Generates the digits (and the exponent) of a decimal floating-point
16103 // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
16104 // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
16105 //
16106 // <--------------------------- delta ---->
16107 // <---- dist --------->
16108 // --------------[------------------+-------------------]--------------
16109 // M- w M+
16110 //
16111 // Grisu2 generates the digits of M+ from left to right and stops as soon as
16112 // V is in [M-,M+].
16113 JSON_ASSERT(M_plus.e >= kAlpha);
16114 JSON_ASSERT(M_plus.e <= kGamma);
16115 std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
16116 std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
16117 // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
16118 //
16119 // M+ = f * 2^e
16120 // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
16121 // = ((p1 ) * 2^-e + (p2 )) * 2^e
16122 // = p1 + p2 * 2^e
16123 const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
16124 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.)
16125 std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
16126 // 1)
16127 //
16128 // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
16129 JSON_ASSERT(p1 > 0);
16130 std::uint32_t pow10{};
16131 const int k = find_largest_pow10(p1, pow10);
16132 // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
16133 //
16134 // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
16135 // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
16136 //
16137 // M+ = p1 + p2 * 2^e
16138 // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
16139 // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
16140 // = d[k-1] * 10^(k-1) + ( rest) * 2^e
16141 //
16142 // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
16143 //
16144 // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
16145 //
16146 // but stop as soon as
16147 //
16148 // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
16149 int n = k;
16150
16151 while (n > 0)
16152 {
16153 // Invariants:
16154 // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
16155 // pow10 = 10^(n-1) <= p1 < 10^n
16156 //
16157 const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
16158 const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
16159 //
16160 // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
16161 // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
16162 //
16163 JSON_ASSERT(d <= 9);
16164 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16165 //
16166 // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
16167 //
16168 p1 = r;
16169 n--;
16170 //
16171 // M+ = buffer * 10^n + (p1 + p2 * 2^e)
16172 // pow10 = 10^n
16173 //
16174 // Now check if enough digits have been generated.
16175 // Compute
16176 //
16177 // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
16178 //
16179 // Note:
16180 // Since rest and delta share the same exponent e, it suffices to
16181 // compare the significands.
16182 const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
16183
16184 if (rest <= delta)
16185 {
16186 // V = buffer * 10^n, with M- <= V <= M+.
16187 decimal_exponent += n;
16188 // We may now just stop. But instead look if the buffer could be
16189 // decremented to bring V closer to w.
16190 //
16191 // pow10 = 10^n is now 1 ulp in the decimal representation V.
16192 // The rounding procedure works with diyfp's with an implicit
16193 // exponent of e.
16194 //
16195 // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
16196 //
16197 const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
16198 grisu2_round(buffer, length, dist, delta, rest, ten_n);
16199 return;
16200 }
16201
16202 pow10 /= 10;
16203 //
16204 // pow10 = 10^(n-1) <= p1 < 10^n
16205 // Invariants restored.
16206 }
16207
16208 // 2)
16209 //
16210 // The digits of the integral part have been generated:
16211 //
16212 // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
16213 // = buffer + p2 * 2^e
16214 //
16215 // Now generate the digits of the fractional part p2 * 2^e.
16216 //
16217 // Note:
16218 // No decimal point is generated: the exponent is adjusted instead.
16219 //
16220 // p2 actually represents the fraction
16221 //
16222 // p2 * 2^e
16223 // = p2 / 2^-e
16224 // = d[-1] / 10^1 + d[-2] / 10^2 + ...
16225 //
16226 // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
16227 //
16228 // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
16229 // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
16230 //
16231 // using
16232 //
16233 // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
16234 // = ( d) * 2^-e + ( r)
16235 //
16236 // or
16237 // 10^m * p2 * 2^e = d + r * 2^e
16238 //
16239 // i.e.
16240 //
16241 // M+ = buffer + p2 * 2^e
16242 // = buffer + 10^-m * (d + r * 2^e)
16243 // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
16244 //
16245 // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
16246 JSON_ASSERT(p2 > delta);
16247 int m = 0;
16248
16249 for (;;)
16250 {
16251 // Invariant:
16252 // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
16253 // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
16254 // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
16255 // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
16256 //
16257 JSON_ASSERT(p2 <= (std::numeric_limits<std::uint64_t>::max)() / 10);
16258 p2 *= 10;
16259 const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
16260 const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
16261 //
16262 // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
16263 // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
16264 // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
16265 //
16266 JSON_ASSERT(d <= 9);
16267 buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16268 //
16269 // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
16270 //
16271 p2 = r;
16272 m++;
16273 //
16274 // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
16275 // Invariant restored.
16276 // Check if enough digits have been generated.
16277 //
16278 // 10^-m * p2 * 2^e <= delta * 2^e
16279 // p2 * 2^e <= 10^m * delta * 2^e
16280 // p2 <= 10^m * delta
16281 delta *= 10;
16282 dist *= 10;
16283
16284 if (p2 <= delta)
16285 {
16286 break;
16287 }
16288 }
16289
16290 // V = buffer * 10^-m, with M- <= V <= M+.
16291 decimal_exponent -= m;
16292 // 1 ulp in the decimal representation is now 10^-m.
16293 // Since delta and dist are now scaled by 10^m, we need to do the
16294 // same with ulp in order to keep the units in sync.
16295 //
16296 // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16297 //
16298 const std::uint64_t ten_m = one.f;
16299 grisu2_round(buffer, length, dist, delta, p2, ten_m);
16300 // By construction this algorithm generates the shortest possible decimal
16301 // number (Loitsch, Theorem 6.2) which rounds back to w.
16302 // For an input number of precision p, at least
16303 //
16304 // N = 1 + ceil(p * log_10(2))
16305 //
16306 // decimal digits are sufficient to identify all binary floating-point
16307 // numbers (Matula, "In-and-Out conversions").
16308 // This implies that the algorithm does not produce more than N decimal
16309 // digits.
16310 //
16311 // N = 17 for p = 53 (IEEE double precision)
16312 // N = 9 for p = 24 (IEEE single precision)
16313}
16314
16320JSON_HEDLEY_NON_NULL(1)
16321inline void grisu2(char *buf, int &len, int &decimal_exponent,
16322 diyfp m_minus, diyfp v, diyfp m_plus)
16323{
16324 JSON_ASSERT(m_plus.e == m_minus.e);
16325 JSON_ASSERT(m_plus.e == v.e);
16326 // --------(-----------------------+-----------------------)-------- (A)
16327 // m- v m+
16328 //
16329 // --------------------(-----------+-----------------------)-------- (B)
16330 // m- v m+
16331 //
16332 // First scale v (and m- and m+) such that the exponent is in the range
16333 // [alpha, gamma].
16334 const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
16335 const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
16336 // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
16337 const diyfp w = diyfp::mul(v, c_minus_k);
16338 const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
16339 const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
16340 // ----(---+---)---------------(---+---)---------------(---+---)----
16341 // w- w w+
16342 // = c*m- = c*v = c*m+
16343 //
16344 // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
16345 // w+ are now off by a small amount.
16346 // In fact:
16347 //
16348 // w - v * 10^k < 1 ulp
16349 //
16350 // To account for this inaccuracy, add resp. subtract 1 ulp.
16351 //
16352 // --------+---[---------------(---+---)---------------]---+--------
16353 // w- M- w M+ w+
16354 //
16355 // Now any number in [M-, M+] (bounds included) will round to w when input,
16356 // regardless of how the input rounding algorithm breaks ties.
16357 //
16358 // And digit_gen generates the shortest possible such number in [M-, M+].
16359 // Note that this does not mean that Grisu2 always generates the shortest
16360 // possible number in the interval (m-, m+).
16361 const diyfp M_minus(w_minus.f + 1, w_minus.e);
16362 const diyfp M_plus (w_plus.f - 1, w_plus.e );
16363 decimal_exponent = -cached.k; // = -(-k) = k
16364 grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
16365}
16366
16372template<typename FloatType>
16373JSON_HEDLEY_NON_NULL(1)
16374void grisu2(char *buf, int &len, int &decimal_exponent, FloatType value)
16375{
16376 static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
16377 "internal error: not enough precision");
16378 JSON_ASSERT(std::isfinite(value));
16379 JSON_ASSERT(value > 0);
16380 // If the neighbors (and boundaries) of 'value' are always computed for double-precision
16381 // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
16382 // decimal representations are not exactly "short".
16383 //
16384 // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
16385 // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
16386 // and since sprintf promotes float's to double's, I think this is exactly what 'std::to_chars'
16387 // does.
16388 // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
16389 // representation using the corresponding std::from_chars function recovers value exactly". That
16390 // indicates that single precision floating-point numbers should be recovered using
16391 // 'std::strtof'.
16392 //
16393 // NB: If the neighbors are computed for single-precision numbers, there is a single float
16394 // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
16395 // value is off by 1 ulp.
16396#if 0
16397 const boundaries w = compute_boundaries(static_cast<double>(value));
16398#else
16400#endif
16401 grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
16402}
16403
16409JSON_HEDLEY_NON_NULL(1)
16410JSON_HEDLEY_RETURNS_NON_NULL
16411inline char *append_exponent(char *buf, int e)
16412{
16413 JSON_ASSERT(e > -1000);
16414 JSON_ASSERT(e < 1000);
16415
16416 if (e < 0)
16417 {
16418 e = -e;
16419 *buf++ = '-';
16420 }
16421
16422 else
16423 {
16424 *buf++ = '+';
16425 }
16426
16427 auto k = static_cast<std::uint32_t>(e);
16428
16429 if (k < 10)
16430 {
16431 // Always print at least two digits in the exponent.
16432 // This is for compatibility with printf("%g").
16433 *buf++ = '0';
16434 *buf++ = static_cast<char>('0' + k);
16435 }
16436
16437 else if (k < 100)
16438 {
16439 *buf++ = static_cast<char>('0' + k / 10);
16440 k %= 10;
16441 *buf++ = static_cast<char>('0' + k);
16442 }
16443
16444 else
16445 {
16446 *buf++ = static_cast<char>('0' + k / 100);
16447 k %= 100;
16448 *buf++ = static_cast<char>('0' + k / 10);
16449 k %= 10;
16450 *buf++ = static_cast<char>('0' + k);
16451 }
16452
16453 return buf;
16454}
16455
16465JSON_HEDLEY_NON_NULL(1)
16466JSON_HEDLEY_RETURNS_NON_NULL
16467inline char *format_buffer(char *buf, int len, int decimal_exponent,
16468 int min_exp, int max_exp)
16469{
16470 JSON_ASSERT(min_exp < 0);
16471 JSON_ASSERT(max_exp > 0);
16472 const int k = len;
16473 const int n = len + decimal_exponent;
16474
16475 // v = buf * 10^(n-k)
16476 // k is the length of the buffer (number of decimal digits)
16477 // n is the position of the decimal point relative to the start of the buffer.
16478
16479 if (k <= n && n <= max_exp)
16480 {
16481 // digits[000]
16482 // len <= max_exp + 2
16483 std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
16484 // Make it look like a floating-point number (#362, #378)
16485 buf[n + 0] = '.';
16486 buf[n + 1] = '0';
16487 return buf + (static_cast<size_t>(n) + 2);
16488 }
16489
16490 if (0 < n && n <= max_exp)
16491 {
16492 // dig.its
16493 // len <= max_digits10 + 1
16494 JSON_ASSERT(k > n);
16495 std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
16496 buf[n] = '.';
16497 return buf + (static_cast<size_t>(k) + 1U);
16498 }
16499
16500 if (min_exp < n && n <= 0)
16501 {
16502 // 0.[000]digits
16503 // len <= 2 + (-min_exp - 1) + max_digits10
16504 std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
16505 buf[0] = '0';
16506 buf[1] = '.';
16507 std::memset(buf + 2, '0', static_cast<size_t>(-n));
16508 return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
16509 }
16510
16511 if (k == 1)
16512 {
16513 // dE+123
16514 // len <= 1 + 5
16515 buf += 1;
16516 }
16517
16518 else
16519 {
16520 // d.igitsE+123
16521 // len <= max_digits10 + 1 + 5
16522 std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
16523 buf[1] = '.';
16524 buf += 1 + static_cast<size_t>(k);
16525 }
16526
16527 *buf++ = 'e';
16528 return append_exponent(buf, n - 1);
16529}
16530
16531} // namespace dtoa_impl
16532
16543template<typename FloatType>
16544JSON_HEDLEY_NON_NULL(1, 2)
16545JSON_HEDLEY_RETURNS_NON_NULL
16546char *to_chars(char *first, const char *last, FloatType value)
16547{
16548 static_cast<void>(last); // maybe unused - fix warning
16549 JSON_ASSERT(std::isfinite(value));
16550
16551 // Use signbit(value) instead of (value < 0) since signbit works for -0.
16552 if (std::signbit(value))
16553 {
16554 value = -value;
16555 *first++ = '-';
16556 }
16557
16558#ifdef __GNUC__
16559#pragma GCC diagnostic push
16560#pragma GCC diagnostic ignored "-Wfloat-equal"
16561#endif
16562
16563 if (value == 0) // +-0
16564 {
16565 *first++ = '0';
16566 // Make it look like a floating-point number (#362, #378)
16567 *first++ = '.';
16568 *first++ = '0';
16569 return first;
16570 }
16571
16572#ifdef __GNUC__
16573#pragma GCC diagnostic pop
16574#endif
16575 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
16576 // Compute v = buffer * 10^decimal_exponent.
16577 // The decimal digits are stored in the buffer, which needs to be interpreted
16578 // as an unsigned decimal integer.
16579 // len is the length of the buffer, i.e. the number of decimal digits.
16580 int len = 0;
16581 int decimal_exponent = 0;
16582 dtoa_impl::grisu2(first, len, decimal_exponent, value);
16583 JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
16584 // Format the buffer like printf("%.*g", prec, value)
16585 constexpr int kMinExp = -4;
16586 // Use digits10 here to increase compatibility with version 2.
16587 constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
16588 JSON_ASSERT(last - first >= kMaxExp + 2);
16589 JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
16590 JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
16591 return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
16592}
16593
16594} // namespace detail
16595} // namespace nlohmann
16596
16597// #include <nlohmann/detail/exceptions.hpp>
16598
16599// #include <nlohmann/detail/macro_scope.hpp>
16600
16601// #include <nlohmann/detail/meta/cpp_future.hpp>
16602
16603// #include <nlohmann/detail/output/binary_writer.hpp>
16604
16605// #include <nlohmann/detail/output/output_adapters.hpp>
16606
16607// #include <nlohmann/detail/value_t.hpp>
16608
16609
16610namespace nlohmann
16611{
16612namespace detail
16613{
16615// serialization //
16617
16620{
16621 strict,
16622 replace,
16623 ignore
16624};
16625
16626template<typename BasicJsonType>
16628{
16629 using string_t = typename BasicJsonType::string_t;
16630 using number_float_t = typename BasicJsonType::number_float_t;
16631 using number_integer_t = typename BasicJsonType::number_integer_t;
16632 using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
16633 using binary_char_t = typename BasicJsonType::binary_t::value_type;
16634 static constexpr std::uint8_t UTF8_ACCEPT = 0;
16635 static constexpr std::uint8_t UTF8_REJECT = 1;
16636
16637public:
16645 : o(std::move(s))
16646 , loc(std::localeconv())
16647 , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
16648 , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
16649 , indent_char(ichar)
16651 , error_handler(error_handler_)
16652 {}
16653
16654 // delete because of pointer members
16655 serializer(const serializer &) = delete;
16656 serializer &operator=(const serializer &) = delete;
16657 serializer(serializer &&) = delete;
16658 serializer &operator=(serializer &&) = delete;
16659 ~serializer() = default;
16660
16683 void dump(const BasicJsonType &val,
16684 const bool pretty_print,
16685 const bool ensure_ascii,
16686 const unsigned int indent_step,
16687 const unsigned int current_indent = 0)
16688 {
16689 switch (val.m_type)
16690 {
16691 case value_t::object:
16692 {
16693 if (val.m_value.object->empty())
16694 {
16695 o->write_characters("{}", 2);
16696 return;
16697 }
16698
16699 if (pretty_print)
16700 {
16701 o->write_characters("{\n", 2);
16702 // variable to hold indentation for recursive calls
16703 const auto new_indent = current_indent + indent_step;
16704
16705 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16706 {
16707 indent_string.resize(indent_string.size() * 2, ' ');
16708 }
16709
16710 // first n-1 elements
16711 auto i = val.m_value.object->cbegin();
16712
16713 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16714 {
16715 o->write_characters(indent_string.c_str(), new_indent);
16716 o->write_character('\"');
16717 dump_escaped(i->first, ensure_ascii);
16718 o->write_characters("\": ", 3);
16719 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16720 o->write_characters(",\n", 2);
16721 }
16722
16723 // last element
16724 JSON_ASSERT(i != val.m_value.object->cend());
16725 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16726 o->write_characters(indent_string.c_str(), new_indent);
16727 o->write_character('\"');
16728 dump_escaped(i->first, ensure_ascii);
16729 o->write_characters("\": ", 3);
16730 dump(i->second, true, ensure_ascii, indent_step, new_indent);
16731 o->write_character('\n');
16732 o->write_characters(indent_string.c_str(), current_indent);
16733 o->write_character('}');
16734 }
16735
16736 else
16737 {
16738 o->write_character('{');
16739 // first n-1 elements
16740 auto i = val.m_value.object->cbegin();
16741
16742 for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
16743 {
16744 o->write_character('\"');
16745 dump_escaped(i->first, ensure_ascii);
16746 o->write_characters("\":", 2);
16747 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16748 o->write_character(',');
16749 }
16750
16751 // last element
16752 JSON_ASSERT(i != val.m_value.object->cend());
16753 JSON_ASSERT(std::next(i) == val.m_value.object->cend());
16754 o->write_character('\"');
16755 dump_escaped(i->first, ensure_ascii);
16756 o->write_characters("\":", 2);
16757 dump(i->second, false, ensure_ascii, indent_step, current_indent);
16758 o->write_character('}');
16759 }
16760
16761 return;
16762 }
16763
16764 case value_t::array:
16765 {
16766 if (val.m_value.array->empty())
16767 {
16768 o->write_characters("[]", 2);
16769 return;
16770 }
16771
16772 if (pretty_print)
16773 {
16774 o->write_characters("[\n", 2);
16775 // variable to hold indentation for recursive calls
16776 const auto new_indent = current_indent + indent_step;
16777
16778 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16779 {
16780 indent_string.resize(indent_string.size() * 2, ' ');
16781 }
16782
16783 // first n-1 elements
16784 for (auto i = val.m_value.array->cbegin();
16785 i != val.m_value.array->cend() - 1; ++i)
16786 {
16787 o->write_characters(indent_string.c_str(), new_indent);
16788 dump(*i, true, ensure_ascii, indent_step, new_indent);
16789 o->write_characters(",\n", 2);
16790 }
16791
16792 // last element
16793 JSON_ASSERT(!val.m_value.array->empty());
16794 o->write_characters(indent_string.c_str(), new_indent);
16795 dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
16796 o->write_character('\n');
16797 o->write_characters(indent_string.c_str(), current_indent);
16798 o->write_character(']');
16799 }
16800
16801 else
16802 {
16803 o->write_character('[');
16804
16805 // first n-1 elements
16806 for (auto i = val.m_value.array->cbegin();
16807 i != val.m_value.array->cend() - 1; ++i)
16808 {
16809 dump(*i, false, ensure_ascii, indent_step, current_indent);
16810 o->write_character(',');
16811 }
16812
16813 // last element
16814 JSON_ASSERT(!val.m_value.array->empty());
16815 dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
16816 o->write_character(']');
16817 }
16818
16819 return;
16820 }
16821
16822 case value_t::string:
16823 {
16824 o->write_character('\"');
16825 dump_escaped(*val.m_value.string, ensure_ascii);
16826 o->write_character('\"');
16827 return;
16828 }
16829
16830 case value_t::binary:
16831 {
16832 if (pretty_print)
16833 {
16834 o->write_characters("{\n", 2);
16835 // variable to hold indentation for recursive calls
16836 const auto new_indent = current_indent + indent_step;
16837
16838 if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
16839 {
16840 indent_string.resize(indent_string.size() * 2, ' ');
16841 }
16842
16843 o->write_characters(indent_string.c_str(), new_indent);
16844 o->write_characters("\"bytes\": [", 10);
16845
16846 if (!val.m_value.binary->empty())
16847 {
16848 for (auto i = val.m_value.binary->cbegin();
16849 i != val.m_value.binary->cend() - 1; ++i)
16850 {
16851 dump_integer(*i);
16852 o->write_characters(", ", 2);
16853 }
16854
16855 dump_integer(val.m_value.binary->back());
16856 }
16857
16858 o->write_characters("],\n", 3);
16859 o->write_characters(indent_string.c_str(), new_indent);
16860 o->write_characters("\"subtype\": ", 11);
16861
16862 if (val.m_value.binary->has_subtype())
16863 {
16864 dump_integer(val.m_value.binary->subtype());
16865 }
16866
16867 else
16868 {
16869 o->write_characters("null", 4);
16870 }
16871
16872 o->write_character('\n');
16873 o->write_characters(indent_string.c_str(), current_indent);
16874 o->write_character('}');
16875 }
16876
16877 else
16878 {
16879 o->write_characters("{\"bytes\":[", 10);
16880
16881 if (!val.m_value.binary->empty())
16882 {
16883 for (auto i = val.m_value.binary->cbegin();
16884 i != val.m_value.binary->cend() - 1; ++i)
16885 {
16886 dump_integer(*i);
16887 o->write_character(',');
16888 }
16889
16890 dump_integer(val.m_value.binary->back());
16891 }
16892
16893 o->write_characters("],\"subtype\":", 12);
16894
16895 if (val.m_value.binary->has_subtype())
16896 {
16897 dump_integer(val.m_value.binary->subtype());
16898 o->write_character('}');
16899 }
16900
16901 else
16902 {
16903 o->write_characters("null}", 5);
16904 }
16905 }
16906
16907 return;
16908 }
16909
16910 case value_t::boolean:
16911 {
16912 if (val.m_value.boolean)
16913 {
16914 o->write_characters("true", 4);
16915 }
16916
16917 else
16918 {
16919 o->write_characters("false", 5);
16920 }
16921
16922 return;
16923 }
16924
16926 {
16927 dump_integer(val.m_value.number_integer);
16928 return;
16929 }
16930
16932 {
16933 dump_integer(val.m_value.number_unsigned);
16934 return;
16935 }
16936
16938 {
16939 dump_float(val.m_value.number_float);
16940 return;
16941 }
16942
16943 case value_t::discarded:
16944 {
16945 o->write_characters("<discarded>", 11);
16946 return;
16947 }
16948
16949 case value_t::null:
16950 {
16951 o->write_characters("null", 4);
16952 return;
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
16960JSON_PRIVATE_UNLESS_TESTED:
16975 void dump_escaped(const string_t &s, const bool ensure_ascii)
16976 {
16977 std::uint32_t codepoint{};
16978 std::uint8_t state = UTF8_ACCEPT;
16979 std::size_t bytes = 0; // number of bytes written to string_buffer
16980 // number of bytes written at the point of the last valid byte
16981 std::size_t bytes_after_last_accept = 0;
16982 std::size_t undumped_chars = 0;
16983
16984 for (std::size_t i = 0; i < s.size(); ++i)
16985 {
16986 const auto byte = static_cast<std::uint8_t>(s[i]);
16987
16988 switch (decode(state, codepoint, byte))
16989 {
16990 case UTF8_ACCEPT: // decode found a new code point
16991 {
16992 switch (codepoint)
16993 {
16994 case 0x08: // backspace
16995 {
16996 string_buffer[bytes++] = '\\';
16997 string_buffer[bytes++] = 'b';
16998 break;
16999 }
17000
17001 case 0x09: // horizontal tab
17002 {
17003 string_buffer[bytes++] = '\\';
17004 string_buffer[bytes++] = 't';
17005 break;
17006 }
17007
17008 case 0x0A: // newline
17009 {
17010 string_buffer[bytes++] = '\\';
17011 string_buffer[bytes++] = 'n';
17012 break;
17013 }
17014
17015 case 0x0C: // formfeed
17016 {
17017 string_buffer[bytes++] = '\\';
17018 string_buffer[bytes++] = 'f';
17019 break;
17020 }
17021
17022 case 0x0D: // carriage return
17023 {
17024 string_buffer[bytes++] = '\\';
17025 string_buffer[bytes++] = 'r';
17026 break;
17027 }
17028
17029 case 0x22: // quotation mark
17030 {
17031 string_buffer[bytes++] = '\\';
17032 string_buffer[bytes++] = '\"';
17033 break;
17034 }
17035
17036 case 0x5C: // reverse solidus
17037 {
17038 string_buffer[bytes++] = '\\';
17039 string_buffer[bytes++] = '\\';
17040 break;
17041 }
17042
17043 default:
17044 {
17045 // escape control characters (0x00..0x1F) or, if
17046 // ensure_ascii parameter is used, non-ASCII characters
17047 if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
17048 {
17049 if (codepoint <= 0xFFFF)
17050 {
17051 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17052 (std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
17053 static_cast<std::uint16_t>(codepoint));
17054 bytes += 6;
17055 }
17056
17057 else
17058 {
17059 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17060 (std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
17061 static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
17062 static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu)));
17063 bytes += 12;
17064 }
17065 }
17066
17067 else
17068 {
17069 // copy byte to buffer (all previous bytes
17070 // been copied have in default case above)
17071 string_buffer[bytes++] = s[i];
17072 }
17073
17074 break;
17075 }
17076 }
17077
17078 // write buffer and reset index; there must be 13 bytes
17079 // left, as this is the maximal number of bytes to be
17080 // written ("\uxxxx\uxxxx\0") for one code point
17081 if (string_buffer.size() - bytes < 13)
17082 {
17083 o->write_characters(string_buffer.data(), bytes);
17084 bytes = 0;
17085 }
17086
17087 // remember the byte position of this accept
17088 bytes_after_last_accept = bytes;
17089 undumped_chars = 0;
17090 break;
17091 }
17092
17093 case UTF8_REJECT: // decode found invalid UTF-8 byte
17094 {
17095 switch (error_handler)
17096 {
17098 {
17099 std::string sn(9, '\0');
17100 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17101 (std::snprintf)(&sn[0], sn.size(), "%.2X", byte);
17102 JSON_THROW(type_error::create(316, "invalid UTF-8 byte at index " + std::to_string(i) + ": 0x" + sn, BasicJsonType()));
17103 }
17104
17107 {
17108 // in case we saw this character the first time, we
17109 // would like to read it again, because the byte
17110 // may be OK for itself, but just not OK for the
17111 // previous sequence
17112 if (undumped_chars > 0)
17113 {
17114 --i;
17115 }
17116
17117 // reset length buffer to the last accepted index;
17118 // thus removing/ignoring the invalid characters
17119 bytes = bytes_after_last_accept;
17120
17122 {
17123 // add a replacement character
17124 if (ensure_ascii)
17125 {
17126 string_buffer[bytes++] = '\\';
17127 string_buffer[bytes++] = 'u';
17128 string_buffer[bytes++] = 'f';
17129 string_buffer[bytes++] = 'f';
17130 string_buffer[bytes++] = 'f';
17131 string_buffer[bytes++] = 'd';
17132 }
17133
17134 else
17135 {
17136 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xEF');
17137 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBF');
17138 string_buffer[bytes++] = detail::binary_writer<BasicJsonType, char>::to_char_type('\xBD');
17139 }
17140
17141 // write buffer and reset index; there must be 13 bytes
17142 // left, as this is the maximal number of bytes to be
17143 // written ("\uxxxx\uxxxx\0") for one code point
17144 if (string_buffer.size() - bytes < 13)
17145 {
17146 o->write_characters(string_buffer.data(), bytes);
17147 bytes = 0;
17148 }
17149
17150 bytes_after_last_accept = bytes;
17151 }
17152
17153 undumped_chars = 0;
17154 // continue processing the string
17155 state = UTF8_ACCEPT;
17156 break;
17157 }
17158
17159 default: // LCOV_EXCL_LINE
17160 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17161 }
17162
17163 break;
17164 }
17165
17166 default: // decode found yet incomplete multi-byte code point
17167 {
17168 if (!ensure_ascii)
17169 {
17170 // code point will not be escaped - copy byte to buffer
17171 string_buffer[bytes++] = s[i];
17172 }
17173
17174 ++undumped_chars;
17175 break;
17176 }
17177 }
17178 }
17179
17180 // we finished processing the string
17181 if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
17182 {
17183 // write buffer
17184 if (bytes > 0)
17185 {
17186 o->write_characters(string_buffer.data(), bytes);
17187 }
17188 }
17189
17190 else
17191 {
17192 // we finish reading, but do not accept: string was incomplete
17193 switch (error_handler)
17194 {
17196 {
17197 std::string sn(9, '\0');
17198 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17199 (std::snprintf)(&sn[0], sn.size(), "%.2X", static_cast<std::uint8_t>(s.back()));
17200 JSON_THROW(type_error::create(316, "incomplete UTF-8 string; last byte: 0x" + sn, BasicJsonType()));
17201 }
17202
17204 {
17205 // write all accepted bytes
17206 o->write_characters(string_buffer.data(), bytes_after_last_accept);
17207 break;
17208 }
17209
17211 {
17212 // write all accepted bytes
17213 o->write_characters(string_buffer.data(), bytes_after_last_accept);
17214
17215 // add a replacement character
17216 if (ensure_ascii)
17217 {
17218 o->write_characters("\\ufffd", 6);
17219 }
17220
17221 else
17222 {
17223 o->write_characters("\xEF\xBF\xBD", 3);
17224 }
17225
17226 break;
17227 }
17228
17229 default: // LCOV_EXCL_LINE
17230 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17231 }
17232 }
17233 }
17234
17235private:
17244 inline unsigned int count_digits(number_unsigned_t x) noexcept
17245 {
17246 unsigned int n_digits = 1;
17247
17248 for (;;)
17249 {
17250 if (x < 10)
17251 {
17252 return n_digits;
17253 }
17254
17255 if (x < 100)
17256 {
17257 return n_digits + 1;
17258 }
17259
17260 if (x < 1000)
17261 {
17262 return n_digits + 2;
17263 }
17264
17265 if (x < 10000)
17266 {
17267 return n_digits + 3;
17268 }
17269
17270 x = x / 10000u;
17271 n_digits += 4;
17272 }
17273 }
17274
17284 template < typename NumberType, detail::enable_if_t <
17285 std::is_integral<NumberType>::value ||
17286 std::is_same<NumberType, number_unsigned_t>::value ||
17287 std::is_same<NumberType, number_integer_t>::value ||
17288 std::is_same<NumberType, binary_char_t>::value,
17289 int > = 0 >
17290 void dump_integer(NumberType x)
17291 {
17292 static constexpr std::array<std::array<char, 2>, 100> digits_to_99
17293 {
17294 {
17295 {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
17296 {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
17297 {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
17298 {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
17299 {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
17300 {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17301 {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17302 {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17303 {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17304 {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17305 }
17306 };
17307
17308 // special case for "0"
17309 if (x == 0)
17310 {
17311 o->write_character('0');
17312 return;
17313 }
17314
17315 // use a pointer to fill the buffer
17316 auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17317 const bool is_negative = std::is_signed<NumberType>::value && !(x >= 0); // see issue #755
17318 number_unsigned_t abs_value;
17319 unsigned int n_chars{};
17320
17321 if (is_negative)
17322 {
17323 *buffer_ptr = '-';
17324 abs_value = remove_sign(static_cast<number_integer_t>(x));
17325 // account one more byte for the minus sign
17326 n_chars = 1 + count_digits(abs_value);
17327 }
17328
17329 else
17330 {
17331 abs_value = static_cast<number_unsigned_t>(x);
17332 n_chars = count_digits(abs_value);
17333 }
17334
17335 // spare 1 byte for '\0'
17336 JSON_ASSERT(n_chars < number_buffer.size() - 1);
17337 // jump to the end to generate the string from backward
17338 // so we later avoid reversing the result
17339 buffer_ptr += n_chars;
17340
17341 // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
17342 // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
17343 while (abs_value >= 100)
17344 {
17345 const auto digits_index = static_cast<unsigned>((abs_value % 100));
17346 abs_value /= 100;
17347 *(--buffer_ptr) = digits_to_99[digits_index][1];
17348 *(--buffer_ptr) = digits_to_99[digits_index][0];
17349 }
17350
17351 if (abs_value >= 10)
17352 {
17353 const auto digits_index = static_cast<unsigned>(abs_value);
17354 *(--buffer_ptr) = digits_to_99[digits_index][1];
17355 *(--buffer_ptr) = digits_to_99[digits_index][0];
17356 }
17357
17358 else
17359 {
17360 *(--buffer_ptr) = static_cast<char>('0' + abs_value);
17361 }
17362
17363 o->write_characters(number_buffer.data(), n_chars);
17364 }
17365
17374 void dump_float(number_float_t x)
17375 {
17376 // NaN / inf
17377 if (!std::isfinite(x))
17378 {
17379 o->write_characters("null", 4);
17380 return;
17381 }
17382
17383 // If number_float_t is an IEEE-754 single or double precision number,
17384 // use the Grisu2 algorithm to produce short numbers which are
17385 // guaranteed to round-trip, using strtof and strtod, resp.
17386 //
17387 // NB: The test below works if <long double> == <double>.
17388 static constexpr bool is_ieee_single_or_double
17389 = (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) ||
17390 (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);
17391 dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
17392 }
17393
17394 void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
17395 {
17396 auto *begin = number_buffer.data();
17397 auto *end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
17398 o->write_characters(begin, static_cast<size_t>(end - begin));
17399 }
17400
17401 void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
17402 {
17403 // get number of digits for a float -> text -> float round-trip
17404 static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
17405 // the actual conversion
17406 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17407 std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
17408 // negative value indicates an error
17409 JSON_ASSERT(len > 0);
17410 // check if buffer was large enough
17411 JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
17412
17413 // erase thousands separator
17414 if (thousands_sep != '\0')
17415 {
17416 auto *const end = std::remove(number_buffer.begin(),
17417 number_buffer.begin() + len, thousands_sep);
17418 std::fill(end, number_buffer.end(), '\0');
17419 JSON_ASSERT((end - number_buffer.begin()) <= len);
17420 len = (end - number_buffer.begin());
17421 }
17422
17423 // convert decimal point to '.'
17424 if (decimal_point != '\0' && decimal_point != '.')
17425 {
17426 auto *const dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
17427
17428 if (dec_pos != number_buffer.end())
17429 {
17430 *dec_pos = '.';
17431 }
17432 }
17433
17434 o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
17435 // determine if need to append ".0"
17436 const bool value_is_int_like =
17437 std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
17438 [](char c)
17439 {
17440 return c == '.' || c == 'e';
17441 });
17442
17443 if (value_is_int_like)
17444 {
17445 o->write_characters(".0", 2);
17446 }
17447 }
17448
17470 static std::uint8_t decode(std::uint8_t &state, std::uint32_t &codep, const std::uint8_t byte) noexcept
17471 {
17472 static const std::array<std::uint8_t, 400> utf8d =
17473 {
17474 {
17475 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
17476 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
17477 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
17478 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
17479 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
17480 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
17481 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
17482 0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
17483 0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
17484 0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
17485 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
17486 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
17487 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
17488 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
17489 }
17490 };
17491 JSON_ASSERT(byte < utf8d.size());
17492 const std::uint8_t type = utf8d[byte];
17493 codep = (state != UTF8_ACCEPT)
17494 ? (byte & 0x3fu) | (codep << 6u)
17495 : (0xFFu >> type) & (byte);
17496 std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
17497 JSON_ASSERT(index < 400);
17498 state = utf8d[index];
17499 return state;
17500 }
17501
17502 /*
17503 * Overload to make the compiler happy while it is instantiating
17504 * dump_integer for number_unsigned_t.
17505 * Must never be called.
17506 */
17507 number_unsigned_t remove_sign(number_unsigned_t x)
17508 {
17509 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17510 return x; // LCOV_EXCL_LINE
17511 }
17512
17513 /*
17514 * Helper function for dump_integer
17515 *
17516 * This function takes a negative signed integer and returns its absolute
17517 * value as unsigned integer. The plus/minus shuffling is necessary as we can
17518 * not directly remove the sign of an arbitrary signed integer as the
17519 * absolute values of INT_MIN and INT_MAX are usually not the same. See
17520 * #1708 for details.
17521 */
17522 inline number_unsigned_t remove_sign(number_integer_t x) noexcept
17523 {
17524 JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
17525 return static_cast<number_unsigned_t>(-(x + 1)) + 1;
17526 }
17527
17528private:
17530 output_adapter_t<char> o = nullptr;
17531
17533 std::array<char, 64> number_buffer{{}};
17534
17536 const std::lconv *loc = nullptr;
17538 const char thousands_sep = '\0';
17540 const char decimal_point = '\0';
17541
17543 std::array<char, 512> string_buffer{{}};
17544
17546 const char indent_char;
17549
17552};
17553} // namespace detail
17554} // namespace nlohmann
17555
17556// #include <nlohmann/detail/value_t.hpp>
17557
17558// #include <nlohmann/json_fwd.hpp>
17559
17560// #include <nlohmann/ordered_map.hpp>
17561
17562
17563#include <functional> // less
17564#include <initializer_list> // initializer_list
17565#include <iterator> // input_iterator_tag, iterator_traits
17566#include <memory> // allocator
17567#include <stdexcept> // for out_of_range
17568#include <type_traits> // enable_if, is_convertible
17569#include <utility> // pair
17570#include <vector> // vector
17571
17572// #include <nlohmann/detail/macro_scope.hpp>
17573
17574
17575namespace nlohmann
17576{
17577
17580template <class Key, class T, class IgnoredLess = std::less<Key>,
17581 class Allocator = std::allocator<std::pair<const Key, T>>>
17582 struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
17583{
17584 using key_type = Key;
17585 using mapped_type = T;
17586 using Container = std::vector<std::pair<const Key, T>, Allocator>;
17587 using typename Container::iterator;
17588 using typename Container::const_iterator;
17589 using typename Container::size_type;
17590 using typename Container::value_type;
17591
17592 // Explicit constructors instead of `using Container::Container`
17593 // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
17594 ordered_map(const Allocator &alloc = Allocator()) : Container{alloc} {}
17595 template <class It>
17596 ordered_map(It first, It last, const Allocator &alloc = Allocator())
17597 : Container{first, last, alloc} {}
17598 ordered_map(std::initializer_list<T> init, const Allocator &alloc = Allocator() )
17599 : Container{init, alloc} {}
17600
17601 std::pair<iterator, bool> emplace(const key_type &key, T &&t)
17602 {
17603 for (auto it = this->begin(); it != this->end(); ++it)
17604 {
17605 if (it->first == key)
17606 {
17607 return {it, false};
17608 }
17609 }
17610
17611 Container::emplace_back(key, t);
17612 return {--this->end(), true};
17613 }
17614
17615 T &operator[](const Key &key)
17616 {
17617 return emplace(key, T{}).first->second;
17618 }
17619
17620 const T &operator[](const Key &key) const
17621 {
17622 return at(key);
17623 }
17624
17625 T &at(const Key &key)
17626 {
17627 for (auto it = this->begin(); it != this->end(); ++it)
17628 {
17629 if (it->first == key)
17630 {
17631 return it->second;
17632 }
17633 }
17634
17635 JSON_THROW(std::out_of_range("key not found"));
17636 }
17637
17638 const T &at(const Key &key) const
17639 {
17640 for (auto it = this->begin(); it != this->end(); ++it)
17641 {
17642 if (it->first == key)
17643 {
17644 return it->second;
17645 }
17646 }
17647
17648 JSON_THROW(std::out_of_range("key not found"));
17649 }
17650
17651 size_type erase(const Key &key)
17652 {
17653 for (auto it = this->begin(); it != this->end(); ++it)
17654 {
17655 if (it->first == key)
17656 {
17657 // Since we cannot move const Keys, re-construct them in place
17658 for (auto next = it; ++next != this->end(); ++it)
17659 {
17660 it->~value_type(); // Destroy but keep allocation
17661 new (&*it) value_type{std::move(*next)};
17662 }
17663
17664 Container::pop_back();
17665 return 1;
17666 }
17667 }
17668
17669 return 0;
17670 }
17671
17672 iterator erase(iterator pos)
17673 {
17674 auto it = pos;
17675
17676 // Since we cannot move const Keys, re-construct them in place
17677 for (auto next = it; ++next != this->end(); ++it)
17678 {
17679 it->~value_type(); // Destroy but keep allocation
17680 new (&*it) value_type{std::move(*next)};
17681 }
17682
17683 Container::pop_back();
17684 return pos;
17685 }
17686
17687 size_type count(const Key &key) const
17688 {
17689 for (auto it = this->begin(); it != this->end(); ++it)
17690 {
17691 if (it->first == key)
17692 {
17693 return 1;
17694 }
17695 }
17696
17697 return 0;
17698 }
17699
17700 iterator find(const Key &key)
17701 {
17702 for (auto it = this->begin(); it != this->end(); ++it)
17703 {
17704 if (it->first == key)
17705 {
17706 return it;
17707 }
17708 }
17709
17710 return Container::end();
17711 }
17712
17713 const_iterator find(const Key &key) const
17714 {
17715 for (auto it = this->begin(); it != this->end(); ++it)
17716 {
17717 if (it->first == key)
17718 {
17719 return it;
17720 }
17721 }
17722
17723 return Container::end();
17724 }
17725
17726 std::pair<iterator, bool> insert( value_type &&value )
17727 {
17728 return emplace(value.first, std::move(value.second));
17729 }
17730
17731 std::pair<iterator, bool> insert( const value_type &value )
17732 {
17733 for (auto it = this->begin(); it != this->end(); ++it)
17734 {
17735 if (it->first == value.first)
17736 {
17737 return {it, false};
17738 }
17739 }
17740
17741 Container::push_back(value);
17742 return {--this->end(), true};
17743 }
17744
17745 template<typename InputIt>
17746 using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
17747 std::input_iterator_tag>::value>::type;
17748
17749 template<typename InputIt, typename = require_input_iter<InputIt>>
17750 void insert(InputIt first, InputIt last)
17751 {
17752 for (auto it = first; it != last; ++it)
17753 {
17754 insert(*it);
17755 }
17756 }
17757};
17758
17759} // namespace nlohmann
17760
17761
17762#if defined(JSON_HAS_CPP_17)
17763#include <string_view>
17764#endif
17765
17771namespace nlohmann
17772{
17773
17858NLOHMANN_BASIC_JSON_TPL_DECLARATION
17859class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
17860{
17861private:
17862 template<detail::value_t> friend struct detail::external_constructor;
17863 friend ::nlohmann::json_pointer<basic_json>;
17864
17865 template<typename BasicJsonType, typename InputType>
17866 friend class ::nlohmann::detail::parser;
17867 friend ::nlohmann::detail::serializer<basic_json>;
17868 template<typename BasicJsonType>
17869 friend class ::nlohmann::detail::iter_impl;
17870 template<typename BasicJsonType, typename CharType>
17871 friend class ::nlohmann::detail::binary_writer;
17872 template<typename BasicJsonType, typename InputType, typename SAX>
17873 friend class ::nlohmann::detail::binary_reader;
17874 template<typename BasicJsonType>
17875 friend class ::nlohmann::detail::json_sax_dom_parser;
17876 template<typename BasicJsonType>
17877 friend class ::nlohmann::detail::json_sax_dom_callback_parser;
17878 friend class ::nlohmann::detail::exception;
17879
17881 using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
17882
17883JSON_PRIVATE_UNLESS_TESTED:
17884 // convenience aliases for types residing in namespace detail;
17886
17887 template<typename InputAdapterType>
17888 static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
17889 InputAdapterType adapter,
17890 detail::parser_callback_t<basic_json>cb = nullptr,
17891 const bool allow_exceptions = true,
17892 const bool ignore_comments = false
17893 )
17894 {
17895 return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
17896 std::move(cb), allow_exceptions, ignore_comments);
17897 }
17898
17899private:
17900 using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
17901 template<typename BasicJsonType>
17903 template<typename BasicJsonType>
17905 template<typename Iterator>
17906 using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
17907 template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
17908
17909 template<typename CharType>
17910 using output_adapter_t = ::nlohmann::detail::output_adapter_t<CharType>;
17911
17912 template<typename InputType>
17914 template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
17915
17916JSON_PRIVATE_UNLESS_TESTED:
17918
17919public:
17920 using value_t = detail::value_t;
17923 template<typename T, typename SFINAE>
17924 using json_serializer = JSONSerializer<T, SFINAE>;
17930 using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
17931
17935
17937 // exceptions //
17939
17943
17956
17958
17959
17961 // container types //
17963
17968
17971
17976
17978 using difference_type = std::ptrdiff_t;
17980 using size_type = std::size_t;
17981
17983 using allocator_type = AllocatorType<basic_json>;
17984
17986 using pointer = typename std::allocator_traits<allocator_type>::pointer;
17988 using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
17989
17998
18000
18001
18006 {
18007 return allocator_type();
18008 }
18009
18036 JSON_HEDLEY_WARN_UNUSED_RESULT
18038 {
18039 basic_json result;
18040 result["copyright"] = "(C) 2013-2021 Niels Lohmann";
18041 result["name"] = "JSON for Modern C++";
18042 result["url"] = "https://github.com/nlohmann/json";
18043 result["version"]["string"] =
18044 std::to_string(NLOHMANN_JSON_VERSION_MAJOR) + "." +
18045 std::to_string(NLOHMANN_JSON_VERSION_MINOR) + "." +
18046 std::to_string(NLOHMANN_JSON_VERSION_PATCH);
18047 result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
18048 result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
18049 result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
18050#ifdef _WIN32
18051 result["platform"] = "win32";
18052#elif defined __linux__
18053 result["platform"] = "linux";
18054#elif defined __APPLE__
18055 result["platform"] = "apple";
18056#elif defined __unix__
18057 result["platform"] = "unix";
18058#else
18059 result["platform"] = "unknown";
18060#endif
18061#if defined(__ICC) || defined(__INTEL_COMPILER)
18062 result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
18063#elif defined(__clang__)
18064 result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
18065#elif defined(__GNUC__) || defined(__GNUG__)
18066 result["compiler"] = {{"family", "gcc"}, {"version", std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + std::to_string(__GNUC_PATCHLEVEL__)}};
18067#elif defined(__HP_cc) || defined(__HP_aCC)
18068 result["compiler"] = "hp"
18069#elif defined(__IBMCPP__)
18070 result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
18071#elif defined(_MSC_VER)
18072 result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
18073#elif defined(__PGI)
18074 result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
18075#elif defined(__SUNPRO_CC)
18076 result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
18077#else
18078 result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
18079#endif
18080#ifdef __cplusplus
18081 result["compiler"]["c++"] = std::to_string(__cplusplus);
18082#else
18083 result["compiler"]["c++"] = "unknown";
18084#endif
18085 return result;
18086 }
18087
18088
18090 // JSON value data types //
18092
18097
18098#if defined(JSON_HAS_CPP_14)
18099 // Use transparent comparator if possible, combined with perfect forwarding
18100 // on find() and count() calls prevents unnecessary string construction.
18101 using object_comparator_t = std::less<>;
18102#else
18103 using object_comparator_t = std::less<StringType>;
18104#endif
18105
18189 using object_t = ObjectType<StringType,
18190 basic_json,
18191 object_comparator_t,
18192 AllocatorType<std::pair<const StringType,
18193 basic_json>>>;
18194
18239 using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
18240
18292 using string_t = StringType;
18293
18318 using boolean_t = BooleanType;
18319
18390 using number_integer_t = NumberIntegerType;
18391
18461 using number_unsigned_t = NumberUnsignedType;
18462
18529 using number_float_t = NumberFloatType;
18530
18602
18603private:
18604
18606 template<typename T, typename... Args>
18607 JSON_HEDLEY_RETURNS_NON_NULL
18608 static T *create(Args &&... args)
18609 {
18610 AllocatorType<T> alloc;
18611 using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18612 auto deleter = [&](T * obj)
18613 {
18614 AllocatorTraits::deallocate(alloc, obj, 1);
18615 };
18616 std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18617 AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18618 JSON_ASSERT(obj != nullptr);
18619 return obj.release();
18620 }
18621
18623 // JSON value storage //
18625
18626JSON_PRIVATE_UNLESS_TESTED:
18652 union json_value
18653 {
18670
18672 json_value() = default;
18674 json_value(boolean_t v) noexcept : boolean(v) {}
18683 {
18684 switch (t)
18685 {
18686 case value_t::object:
18687 {
18688 object = create<object_t>();
18689 break;
18690 }
18691
18692 case value_t::array:
18693 {
18694 array = create<array_t>();
18695 break;
18696 }
18697
18698 case value_t::string:
18699 {
18700 string = create<string_t>("");
18701 break;
18702 }
18703
18704 case value_t::binary:
18705 {
18706 binary = create<binary_t>();
18707 break;
18708 }
18709
18710 case value_t::boolean:
18711 {
18712 boolean = boolean_t(false);
18713 break;
18714 }
18715
18717 {
18719 break;
18720 }
18721
18723 {
18725 break;
18726 }
18727
18729 {
18731 break;
18732 }
18733
18734 case value_t::null:
18735 {
18736 object = nullptr; // silence warning, see #821
18737 break;
18738 }
18739
18740 case value_t::discarded:
18741 default:
18742 {
18743 object = nullptr; // silence warning, see #821
18744
18745 if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
18746 {
18747 JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.2", basic_json())); // LCOV_EXCL_LINE
18748 }
18749
18750 break;
18751 }
18752 }
18753 }
18754
18757 {
18758 string = create<string_t>(value);
18759 }
18760
18763 {
18764 string = create<string_t>(std::move(value));
18765 }
18766
18769 {
18770 object = create<object_t>(value);
18771 }
18772
18775 {
18776 object = create<object_t>(std::move(value));
18777 }
18778
18781 {
18782 array = create<array_t>(value);
18783 }
18784
18787 {
18788 array = create<array_t>(std::move(value));
18789 }
18790
18793 {
18794 binary = create<binary_t>(value);
18795 }
18796
18799 {
18800 binary = create<binary_t>(std::move(value));
18801 }
18802
18805 {
18806 binary = create<binary_t>(value);
18807 }
18808
18811 {
18812 binary = create<binary_t>(std::move(value));
18813 }
18814
18815 void destroy(value_t t)
18816 {
18817 if (t == value_t::array || t == value_t::object)
18818 {
18819 // flatten the current json_value to a heap-allocated stack
18820 std::vector<basic_json> stack;
18821
18822 // move the top-level items to stack
18823 if (t == value_t::array)
18824 {
18825 stack.reserve(array->size());
18826 std::move(array->begin(), array->end(), std::back_inserter(stack));
18827 }
18828
18829 else
18830 {
18831 stack.reserve(object->size());
18832
18833 for (auto &&it : *object)
18834 {
18835 stack.push_back(std::move(it.second));
18836 }
18837 }
18838
18839 while (!stack.empty())
18840 {
18841 // move the last item to local variable to be processed
18842 basic_json current_item(std::move(stack.back()));
18843 stack.pop_back();
18844
18845 // if current_item is array/object, move
18846 // its children to the stack to be processed later
18847 if (current_item.is_array())
18848 {
18849 std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
18850 current_item.m_value.array->clear();
18851 }
18852
18853 else if (current_item.is_object())
18854 {
18855 for (auto &&it : *current_item.m_value.object)
18856 {
18857 stack.push_back(std::move(it.second));
18858 }
18859
18860 current_item.m_value.object->clear();
18861 }
18862
18863 // it's now safe that current_item get destructed
18864 // since it doesn't have any children
18865 }
18866 }
18867
18868 switch (t)
18869 {
18870 case value_t::object:
18871 {
18872 AllocatorType<object_t> alloc;
18873 std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
18874 std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
18875 break;
18876 }
18877
18878 case value_t::array:
18879 {
18880 AllocatorType<array_t> alloc;
18881 std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
18882 std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
18883 break;
18884 }
18885
18886 case value_t::string:
18887 {
18888 AllocatorType<string_t> alloc;
18889 std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
18890 std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
18891 break;
18892 }
18893
18894 case value_t::binary:
18895 {
18896 AllocatorType<binary_t> alloc;
18897 std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
18898 std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
18899 break;
18900 }
18901
18902 case value_t::null:
18903 case value_t::boolean:
18907 case value_t::discarded:
18908 default:
18909 {
18910 break;
18911 }
18912 }
18913 }
18914 };
18915
18916private:
18935 void assert_invariant(bool check_parents = true) const noexcept
18936 {
18937 JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
18938 JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
18939 JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
18940 JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
18941#if JSON_DIAGNOSTICS
18942 JSON_TRY
18943 {
18944 // cppcheck-suppress assertWithSideEffect
18945 JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
18946 {
18947 return j.m_parent == this;
18948 }));
18949 }
18950 JSON_CATCH(...) {} // LCOV_EXCL_LINE
18951#endif
18952 static_cast<void>(check_parents);
18953 }
18954
18955 void set_parents()
18956 {
18957#if JSON_DIAGNOSTICS
18958
18959 switch (m_type)
18960 {
18961 case value_t::array:
18962 {
18963 for (auto &element : *m_value.array)
18964 {
18965 element.m_parent = this;
18966 }
18967
18968 break;
18969 }
18970
18971 case value_t::object:
18972 {
18973 for (auto &element : *m_value.object)
18974 {
18975 element.second.m_parent = this;
18976 }
18977
18978 break;
18979 }
18980
18981 case value_t::null:
18982 case value_t::string:
18983 case value_t::boolean:
18987 case value_t::binary:
18988 case value_t::discarded:
18989 default:
18990 break;
18991 }
18992
18993#endif
18994 }
18995
18996 iterator set_parents(iterator it, typename iterator::difference_type count)
18997 {
18998#if JSON_DIAGNOSTICS
18999
19000 for (typename iterator::difference_type i = 0; i < count; ++i)
19001 {
19002 (it + i)->m_parent = this;
19003 }
19004
19005#else
19006 static_cast<void>(count);
19007#endif
19008 return it;
19009 }
19010
19011 reference set_parent(reference j, std::size_t old_capacity = std::size_t(-1))
19012 {
19013#if JSON_DIAGNOSTICS
19014
19015 if (old_capacity != std::size_t(-1))
19016 {
19017 // see https://github.com/nlohmann/json/issues/2838
19018 JSON_ASSERT(type() == value_t::array);
19019
19020 if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
19021 {
19022 // capacity has changed: update all parents
19023 set_parents();
19024 return j;
19025 }
19026 }
19027
19028 // ordered_json uses a vector internally, so pointers could have
19029 // been invalidated; see https://github.com/nlohmann/json/issues/2962
19030#ifdef JSON_HEDLEY_MSVC_VERSION
19031#pragma warning(push )
19032#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
19033#endif
19034
19035 if (detail::is_ordered_map<object_t>::value)
19036 {
19037 set_parents();
19038 return j;
19039 }
19040
19041#ifdef JSON_HEDLEY_MSVC_VERSION
19042#pragma warning( pop )
19043#endif
19044 j.m_parent = this;
19045#else
19046 static_cast<void>(j);
19047 static_cast<void>(old_capacity);
19048#endif
19049 return j;
19050 }
19051
19052public:
19054 // JSON parser callback //
19056
19073
19123 using parser_callback_t = detail::parser_callback_t<basic_json>;
19124
19126 // constructors //
19128
19133
19165 : m_type(v), m_value(v)
19166 {
19168 }
19169
19188 basic_json(std::nullptr_t = nullptr) noexcept
19189 : basic_json(value_t::null)
19190 {
19192 }
19193
19256 template < typename CompatibleType,
19257 typename U = detail::uncvref_t<CompatibleType>,
19258 detail::enable_if_t <
19260 basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
19261 JSONSerializer<U>::to_json(std::declval<basic_json_t &>(),
19262 std::forward<CompatibleType>(val))))
19263 {
19264 JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
19265 set_parents();
19267 }
19268
19295 template < typename BasicJsonType,
19296 detail::enable_if_t <
19297 detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
19298 basic_json(const BasicJsonType &val)
19299 {
19300 using other_boolean_t = typename BasicJsonType::boolean_t;
19301 using other_number_float_t = typename BasicJsonType::number_float_t;
19302 using other_number_integer_t = typename BasicJsonType::number_integer_t;
19303 using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
19304 using other_string_t = typename BasicJsonType::string_t;
19305 using other_object_t = typename BasicJsonType::object_t;
19306 using other_array_t = typename BasicJsonType::array_t;
19307 using other_binary_t = typename BasicJsonType::binary_t;
19308
19309 switch (val.type())
19310 {
19311 case value_t::boolean:
19312 JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
19313 break;
19314
19316 JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
19317 break;
19318
19320 JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
19321 break;
19322
19324 JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
19325 break;
19326
19327 case value_t::string:
19328 JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t &>());
19329 break;
19330
19331 case value_t::object:
19332 JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t &>());
19333 break;
19334
19335 case value_t::array:
19336 JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t &>());
19337 break;
19338
19339 case value_t::binary:
19340 JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t &>());
19341 break;
19342
19343 case value_t::null:
19344 *this = nullptr;
19345 break;
19346
19347 case value_t::discarded:
19348 m_type = value_t::discarded;
19349 break;
19350
19351 default: // LCOV_EXCL_LINE
19352 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19353 }
19354
19355 set_parents();
19357 }
19358
19434 bool type_deduction = true,
19435 value_t manual_type = value_t::array)
19436 {
19437 // check if each element is an array with two elements whose first
19438 // element is a string
19439 bool is_an_object = std::all_of(init.begin(), init.end(),
19440 [](const detail::json_ref<basic_json> &element_ref)
19441 {
19442 return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19443 });
19444
19445 // adjust type if type deduction is not wanted
19446 if (!type_deduction)
19447 {
19448 // if array is wanted, do not create an object though possible
19449 if (manual_type == value_t::array)
19450 {
19451 is_an_object = false;
19452 }
19453
19454 // if object is wanted but impossible, throw an exception
19455 if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19456 {
19457 JSON_THROW(type_error::create(301, "cannot create object from initializer list", basic_json()));
19458 }
19459 }
19460
19461 if (is_an_object)
19462 {
19463 // the initializer list is a list of pairs -> create object
19464 m_type = value_t::object;
19466
19467 for (auto &element_ref : init)
19468 {
19469 auto element = element_ref.moved_or_copied();
19470 m_value.object->emplace(
19471 std::move(*((*element.m_value.array)[0].m_value.string)),
19472 std::move((*element.m_value.array)[1]));
19473 }
19474 }
19475
19476 else
19477 {
19478 // the initializer list describes an array -> create array
19479 m_type = value_t::array;
19480 m_value.array = create<array_t>(init.begin(), init.end());
19481 }
19482
19483 set_parents();
19485 }
19486
19514 JSON_HEDLEY_WARN_UNUSED_RESULT
19515 static basic_json binary(const typename binary_t::container_type &init)
19516 {
19517 auto res = basic_json();
19518 res.m_type = value_t::binary;
19519 res.m_value = init;
19520 return res;
19521 }
19522
19551 JSON_HEDLEY_WARN_UNUSED_RESULT
19552 static basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
19553 {
19554 auto res = basic_json();
19555 res.m_type = value_t::binary;
19556 res.m_value = binary_t(init, subtype);
19557 return res;
19558 }
19559
19561 JSON_HEDLEY_WARN_UNUSED_RESULT
19563 {
19564 auto res = basic_json();
19565 res.m_type = value_t::binary;
19566 res.m_value = std::move(init);
19567 return res;
19568 }
19569
19571 JSON_HEDLEY_WARN_UNUSED_RESULT
19572 static basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
19573 {
19574 auto res = basic_json();
19575 res.m_type = value_t::binary;
19576 res.m_value = binary_t(std::move(init), subtype);
19577 return res;
19578 }
19579
19617 JSON_HEDLEY_WARN_UNUSED_RESULT
19619 {
19620 return basic_json(init, false, value_t::array);
19621 }
19622
19661 JSON_HEDLEY_WARN_UNUSED_RESULT
19663 {
19664 return basic_json(init, false, value_t::object);
19665 }
19666
19690 : m_type(value_t::array)
19691 {
19692 m_value.array = create<array_t>(cnt, val);
19693 set_parents();
19695 }
19696
19752 template < class InputIT, typename std::enable_if <
19753 std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19754 std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19755 basic_json(InputIT first, InputIT last)
19756 {
19757 JSON_ASSERT(first.m_object != nullptr);
19758 JSON_ASSERT(last.m_object != nullptr);
19759
19760 // make sure iterator fits the current value
19761 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19762 {
19763 JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", basic_json()));
19764 }
19765
19766 // copy type from first iterator
19767 m_type = first.m_object->m_type;
19768
19769 // check if iterator range is complete for primitive values
19770 switch (m_type)
19771 {
19772 case value_t::boolean:
19776 case value_t::string:
19777 {
19778 if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19779 || !last.m_it.primitive_iterator.is_end()))
19780 {
19781 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *first.m_object));
19782 }
19783
19784 break;
19785 }
19786
19787 case value_t::null:
19788 case value_t::object:
19789 case value_t::array:
19790 case value_t::binary:
19791 case value_t::discarded:
19792 default:
19793 break;
19794 }
19795
19796 switch (m_type)
19797 {
19799 {
19800 m_value.number_integer = first.m_object->m_value.number_integer;
19801 break;
19802 }
19803
19805 {
19806 m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19807 break;
19808 }
19809
19811 {
19812 m_value.number_float = first.m_object->m_value.number_float;
19813 break;
19814 }
19815
19816 case value_t::boolean:
19817 {
19818 m_value.boolean = first.m_object->m_value.boolean;
19819 break;
19820 }
19821
19822 case value_t::string:
19823 {
19824 m_value = *first.m_object->m_value.string;
19825 break;
19826 }
19827
19828 case value_t::object:
19829 {
19830 m_value.object = create<object_t>(first.m_it.object_iterator,
19831 last.m_it.object_iterator);
19832 break;
19833 }
19834
19835 case value_t::array:
19836 {
19837 m_value.array = create<array_t>(first.m_it.array_iterator,
19838 last.m_it.array_iterator);
19839 break;
19840 }
19841
19842 case value_t::binary:
19843 {
19844 m_value = *first.m_object->m_value.binary;
19845 break;
19846 }
19847
19848 case value_t::null:
19849 case value_t::discarded:
19850 default:
19851 JSON_THROW(invalid_iterator::create(206, "cannot construct with iterators from " + std::string(first.m_object->type_name()), *first.m_object));
19852 }
19853
19854 set_parents();
19856 }
19857
19858
19860 // other constructors and destructor //
19862
19863 template<typename JsonRef,
19864 detail::enable_if_t<detail::conjunction<detail::is_json_ref<JsonRef>,
19865 std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19866 basic_json(const JsonRef &ref) : basic_json(ref.moved_or_copied()) {}
19867
19894 : m_type(other.m_type)
19895 {
19896 // check of passed value is valid
19897 other.assert_invariant();
19898
19899 switch (m_type)
19900 {
19901 case value_t::object:
19902 {
19903 m_value = *other.m_value.object;
19904 break;
19905 }
19906
19907 case value_t::array:
19908 {
19909 m_value = *other.m_value.array;
19910 break;
19911 }
19912
19913 case value_t::string:
19914 {
19915 m_value = *other.m_value.string;
19916 break;
19917 }
19918
19919 case value_t::boolean:
19920 {
19921 m_value = other.m_value.boolean;
19922 break;
19923 }
19924
19926 {
19927 m_value = other.m_value.number_integer;
19928 break;
19929 }
19930
19932 {
19933 m_value = other.m_value.number_unsigned;
19934 break;
19935 }
19936
19938 {
19939 m_value = other.m_value.number_float;
19940 break;
19941 }
19942
19943 case value_t::binary:
19944 {
19945 m_value = *other.m_value.binary;
19946 break;
19947 }
19948
19949 case value_t::null:
19950 case value_t::discarded:
19951 default:
19952 break;
19953 }
19954
19955 set_parents();
19957 }
19958
19985 basic_json(basic_json &&other) noexcept
19986 : m_type(std::move(other.m_type)),
19987 m_value(std::move(other.m_value))
19988 {
19989 // check that passed value is valid
19990 other.assert_invariant(false);
19991 // invalidate payload
19992 other.m_type = value_t::null;
19993 other.m_value = {};
19994 set_parents();
19996 }
19997
20022 std::is_nothrow_move_constructible<value_t>::value &&
20023 std::is_nothrow_move_assignable<value_t>::value &&
20024 std::is_nothrow_move_constructible<json_value>::value &&
20025 std::is_nothrow_move_assignable<json_value>::value
20026 )
20027 {
20028 // check that passed value is valid
20029 other.assert_invariant();
20030 using std::swap;
20031 swap(m_type, other.m_type);
20032 swap(m_value, other.m_value);
20033 set_parents();
20035 return *this;
20036 }
20037
20053 ~basic_json() noexcept
20054 {
20055 assert_invariant(false);
20056 m_value.destroy(m_type);
20057 }
20058
20060
20061public:
20063 // object inspection //
20065
20069
20117 string_t dump(const int indent = -1,
20118 const char indent_char = ' ',
20119 const bool ensure_ascii = false,
20120 const error_handler_t error_handler = error_handler_t::strict) const
20121 {
20122 string_t result;
20123 serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
20124
20125 if (indent >= 0)
20126 {
20127 s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
20128 }
20129
20130 else
20131 {
20132 s.dump(*this, false, ensure_ascii, 0);
20133 }
20134
20135 return result;
20136 }
20137
20171 constexpr value_t type() const noexcept
20172 {
20173 return m_type;
20174 }
20175
20202 constexpr bool is_primitive() const noexcept
20203 {
20204 return is_null() || is_string() || is_boolean() || is_number() || is_binary();
20205 }
20206
20229 constexpr bool is_structured() const noexcept
20230 {
20231 return is_array() || is_object();
20232 }
20233
20251 constexpr bool is_null() const noexcept
20252 {
20253 return m_type == value_t::null;
20254 }
20255
20273 constexpr bool is_boolean() const noexcept
20274 {
20275 return m_type == value_t::boolean;
20276 }
20277
20303 constexpr bool is_number() const noexcept
20304 {
20305 return is_number_integer() || is_number_float();
20306 }
20307
20332 constexpr bool is_number_integer() const noexcept
20333 {
20334 return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
20335 }
20336
20360 constexpr bool is_number_unsigned() const noexcept
20361 {
20362 return m_type == value_t::number_unsigned;
20363 }
20364
20388 constexpr bool is_number_float() const noexcept
20389 {
20390 return m_type == value_t::number_float;
20391 }
20392
20410 constexpr bool is_object() const noexcept
20411 {
20412 return m_type == value_t::object;
20413 }
20414
20432 constexpr bool is_array() const noexcept
20433 {
20434 return m_type == value_t::array;
20435 }
20436
20454 constexpr bool is_string() const noexcept
20455 {
20456 return m_type == value_t::string;
20457 }
20458
20476 constexpr bool is_binary() const noexcept
20477 {
20478 return m_type == value_t::binary;
20479 }
20480
20503 constexpr bool is_discarded() const noexcept
20504 {
20505 return m_type == value_t::discarded;
20506 }
20507
20529 constexpr operator value_t() const noexcept
20530 {
20531 return m_type;
20532 }
20533
20535
20536private:
20538 // value access //
20540
20542 boolean_t get_impl(boolean_t * /*unused*/) const
20543 {
20544 if (JSON_HEDLEY_LIKELY(is_boolean()))
20545 {
20546 return m_value.boolean;
20547 }
20548
20549 JSON_THROW(type_error::create(302, "type must be boolean, but is " + std::string(type_name()), *this));
20550 }
20551
20553 object_t *get_impl_ptr(object_t * /*unused*/) noexcept
20554 {
20555 return is_object() ? m_value.object : nullptr;
20556 }
20557
20559 constexpr const object_t *get_impl_ptr(const object_t * /*unused*/) const noexcept
20560 {
20561 return is_object() ? m_value.object : nullptr;
20562 }
20563
20565 array_t *get_impl_ptr(array_t * /*unused*/) noexcept
20566 {
20567 return is_array() ? m_value.array : nullptr;
20568 }
20569
20571 constexpr const array_t *get_impl_ptr(const array_t * /*unused*/) const noexcept
20572 {
20573 return is_array() ? m_value.array : nullptr;
20574 }
20575
20577 string_t *get_impl_ptr(string_t * /*unused*/) noexcept
20578 {
20579 return is_string() ? m_value.string : nullptr;
20580 }
20581
20583 constexpr const string_t *get_impl_ptr(const string_t * /*unused*/) const noexcept
20584 {
20585 return is_string() ? m_value.string : nullptr;
20586 }
20587
20589 boolean_t *get_impl_ptr(boolean_t * /*unused*/) noexcept
20590 {
20591 return is_boolean() ? &m_value.boolean : nullptr;
20592 }
20593
20595 constexpr const boolean_t *get_impl_ptr(const boolean_t * /*unused*/) const noexcept
20596 {
20597 return is_boolean() ? &m_value.boolean : nullptr;
20598 }
20599
20602 {
20603 return is_number_integer() ? &m_value.number_integer : nullptr;
20604 }
20605
20607 constexpr const number_integer_t *get_impl_ptr(const number_integer_t * /*unused*/) const noexcept
20608 {
20609 return is_number_integer() ? &m_value.number_integer : nullptr;
20610 }
20611
20614 {
20615 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20616 }
20617
20619 constexpr const number_unsigned_t *get_impl_ptr(const number_unsigned_t * /*unused*/) const noexcept
20620 {
20621 return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20622 }
20623
20626 {
20627 return is_number_float() ? &m_value.number_float : nullptr;
20628 }
20629
20631 constexpr const number_float_t *get_impl_ptr(const number_float_t * /*unused*/) const noexcept
20632 {
20633 return is_number_float() ? &m_value.number_float : nullptr;
20634 }
20635
20637 binary_t *get_impl_ptr(binary_t * /*unused*/) noexcept
20638 {
20639 return is_binary() ? m_value.binary : nullptr;
20640 }
20641
20643 constexpr const binary_t *get_impl_ptr(const binary_t * /*unused*/) const noexcept
20644 {
20645 return is_binary() ? m_value.binary : nullptr;
20646 }
20647
20659 template<typename ReferenceType, typename ThisType>
20660 static ReferenceType get_ref_impl(ThisType &obj)
20661 {
20662 // delegate the call to get_ptr<>()
20663 auto *ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20664
20665 if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20666 {
20667 return *ptr;
20668 }
20669
20670 JSON_THROW(type_error::create(303, "incompatible ReferenceType for get_ref, actual type is " + std::string(obj.type_name()), obj));
20671 }
20672
20673public:
20677
20704 template<typename PointerType, typename std::enable_if<
20705 std::is_pointer<PointerType>::value, int>::type = 0>
20706 auto get_ptr() noexcept -> decltype(std::declval<basic_json_t &>().get_impl_ptr(std::declval<PointerType>()))
20707 {
20708 // delegate the call to get_impl_ptr<>()
20709 return get_impl_ptr(static_cast<PointerType>(nullptr));
20710 }
20711
20716 template < typename PointerType, typename std::enable_if <
20717 std::is_pointer<PointerType>::value &&
20718 std::is_const<typename std::remove_pointer<PointerType>::type>::value, int >::type = 0 >
20719 constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t &>().get_impl_ptr(std::declval<PointerType>()))
20720 {
20721 // delegate the call to get_impl_ptr<>() const
20722 return get_impl_ptr(static_cast<PointerType>(nullptr));
20723 }
20724
20725private:
20764 template < typename ValueType,
20765 detail::enable_if_t <
20768 int > = 0 >
20769 ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20770 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t &>(), std::declval<ValueType &>())))
20771 {
20772 ValueType ret{};
20773 JSONSerializer<ValueType>::from_json(*this, ret);
20774 return ret;
20775 }
20776
20807 template < typename ValueType,
20808 detail::enable_if_t <
20810 int > = 0 >
20811 ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20812 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t &>())))
20813 {
20814 return JSONSerializer<ValueType>::from_json(*this);
20815 }
20816
20832 template < typename BasicJsonType,
20833 detail::enable_if_t <
20835 int > = 0 >
20836 BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20837 {
20838 return *this;
20839 }
20840
20855 template<typename BasicJsonType,
20856 detail::enable_if_t<
20857 std::is_same<BasicJsonType, basic_json_t>::value,
20858 int> = 0>
20860 {
20861 return *this;
20862 }
20863
20868 template<typename PointerType,
20869 detail::enable_if_t<
20870 std::is_pointer<PointerType>::value,
20871 int> = 0>
20872 constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20873 -> decltype(std::declval<const basic_json_t &>().template get_ptr<PointerType>())
20874 {
20875 // delegate the call to get_ptr
20876 return get_ptr<PointerType>();
20877 }
20878
20879public:
20903 template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20904#if defined(JSON_HAS_CPP_14)
20905 constexpr
20906#endif
20907 auto get() const noexcept(
20908 noexcept(std::declval<const basic_json_t &>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20909 -> decltype(std::declval<const basic_json_t &>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20910 {
20911 // we cannot static_assert on ValueTypeCV being non-const, because
20912 // there is support for get<const basic_json_t>(), which is why we
20913 // still need the uncvref
20914 static_assert(!std::is_reference<ValueTypeCV>::value,
20915 "get() cannot be used with reference types, you might want to use get_ref()");
20916 return get_impl<ValueType>(detail::priority_tag<4> {});
20917 }
20918
20946 template<typename PointerType, typename std::enable_if<
20947 std::is_pointer<PointerType>::value, int>::type = 0>
20948 auto get() noexcept -> decltype(std::declval<basic_json_t &>().template get_ptr<PointerType>())
20949 {
20950 // delegate the call to get_ptr
20951 return get_ptr<PointerType>();
20952 }
20953
20987 template < typename ValueType,
20988 detail::enable_if_t <
20991 int > = 0 >
20992 ValueType & get_to(ValueType &v) const noexcept(noexcept(
20993 JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t &>(), v)))
20994 {
20995 JSONSerializer<ValueType>::from_json(*this, v);
20996 return v;
20997 }
20998
20999 // specialization to allow to call get_to with a basic_json value
21000 // see https://github.com/nlohmann/json/issues/2175
21001 template<typename ValueType,
21002 detail::enable_if_t <
21004 int> = 0>
21005 ValueType & get_to(ValueType &v) const
21006 {
21007 v = *this;
21008 return v;
21009 }
21010
21011 template <
21012 typename T, std::size_t N,
21013 typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21014 detail::enable_if_t <
21015 detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
21016 Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
21017 noexcept(noexcept(JSONSerializer<Array>::from_json(
21018 std::declval<const basic_json_t &>(), v)))
21019 {
21020 JSONSerializer<Array>::from_json(*this, v);
21021 return v;
21022 }
21023
21050 template<typename ReferenceType, typename std::enable_if<
21051 std::is_reference<ReferenceType>::value, int>::type = 0>
21052 ReferenceType get_ref()
21053 {
21054 // delegate call to get_ref_impl
21055 return get_ref_impl<ReferenceType>(*this);
21056 }
21057
21062 template < typename ReferenceType, typename std::enable_if <
21063 std::is_reference<ReferenceType>::value &&
21064 std::is_const<typename std::remove_reference<ReferenceType>::type>::value, int >::type = 0 >
21065 ReferenceType get_ref() const
21066 {
21067 // delegate call to get_ref_impl
21068 return get_ref_impl<ReferenceType>(*this);
21069 }
21070
21100 template < typename ValueType, typename std::enable_if <
21107
21108#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
21110#endif
21112 >::value, int >::type = 0 >
21113 JSON_EXPLICIT operator ValueType() const
21114 {
21115 // delegate the call to get<>() const
21116 return get<ValueType>();
21117 }
21118
21129 {
21130 if (!is_binary())
21131 {
21132 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
21133 }
21134
21135 return *get_ptr<binary_t *>();
21136 }
21137
21139 const binary_t &get_binary() const
21140 {
21141 if (!is_binary())
21142 {
21143 JSON_THROW(type_error::create(302, "type must be binary, but is " + std::string(type_name()), *this));
21144 }
21145
21146 return *get_ptr<const binary_t *>();
21147 }
21148
21150
21151
21153 // element access //
21155
21159
21187 {
21188 // at only works for arrays
21189 if (JSON_HEDLEY_LIKELY(is_array()))
21190 {
21191 JSON_TRY
21192 {
21193 return set_parent(m_value.array->at(idx));
21194 }
21195 JSON_CATCH (std::out_of_range &)
21196 {
21197 // create better exception explanation
21198 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21199 }
21200 }
21201
21202 else
21203 {
21204 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21205 }
21206 }
21207
21235 {
21236 // at only works for arrays
21237 if (JSON_HEDLEY_LIKELY(is_array()))
21238 {
21239 JSON_TRY
21240 {
21241 return m_value.array->at(idx);
21242 }
21243 JSON_CATCH (std::out_of_range &)
21244 {
21245 // create better exception explanation
21246 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
21247 }
21248 }
21249
21250 else
21251 {
21252 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21253 }
21254 }
21255
21286 reference at(const typename object_t::key_type &key)
21287 {
21288 // at only works for objects
21289 if (JSON_HEDLEY_LIKELY(is_object()))
21290 {
21291 JSON_TRY
21292 {
21293 return set_parent(m_value.object->at(key));
21294 }
21295 JSON_CATCH (std::out_of_range &)
21296 {
21297 // create better exception explanation
21298 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21299 }
21300 }
21301
21302 else
21303 {
21304 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21305 }
21306 }
21307
21338 const_reference at(const typename object_t::key_type &key) const
21339 {
21340 // at only works for objects
21341 if (JSON_HEDLEY_LIKELY(is_object()))
21342 {
21343 JSON_TRY
21344 {
21345 return m_value.object->at(key);
21346 }
21347 JSON_CATCH (std::out_of_range &)
21348 {
21349 // create better exception explanation
21350 JSON_THROW(out_of_range::create(403, "key '" + key + "' not found", *this));
21351 }
21352 }
21353
21354 else
21355 {
21356 JSON_THROW(type_error::create(304, "cannot use at() with " + std::string(type_name()), *this));
21357 }
21358 }
21359
21386 {
21387 // implicitly convert null value to an empty array
21388 if (is_null())
21389 {
21390 m_type = value_t::array;
21391 m_value.array = create<array_t>();
21393 }
21394
21395 // operator[] only works for arrays
21396 if (JSON_HEDLEY_LIKELY(is_array()))
21397 {
21398 // fill up array with null values if given idx is outside range
21399 if (idx >= m_value.array->size())
21400 {
21401#if JSON_DIAGNOSTICS
21402 // remember array size before resizing
21403 const auto previous_size = m_value.array->size();
21404#endif
21405 m_value.array->resize(idx + 1);
21406#if JSON_DIAGNOSTICS
21407 // set parent for values added above
21408 set_parents(begin() + static_cast<typename iterator::difference_type>(previous_size), static_cast<typename iterator::difference_type>(idx + 1 - previous_size));
21409#endif
21410 }
21411
21412 return m_value.array->operator[](idx);
21413 }
21414
21415 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21416 }
21417
21438 {
21439 // const operator[] only works for arrays
21440 if (JSON_HEDLEY_LIKELY(is_array()))
21441 {
21442 return m_value.array->operator[](idx);
21443 }
21444
21445 JSON_THROW(type_error::create(305, "cannot use operator[] with a numeric argument with " + std::string(type_name()), *this));
21446 }
21447
21475 reference operator[](const typename object_t::key_type &key)
21476 {
21477 // implicitly convert null value to an empty object
21478 if (is_null())
21479 {
21480 m_type = value_t::object;
21481 m_value.object = create<object_t>();
21483 }
21484
21485 // operator[] only works for objects
21486 if (JSON_HEDLEY_LIKELY(is_object()))
21487 {
21488 return set_parent(m_value.object->operator[](key));
21489 }
21490
21491 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21492 }
21493
21524 const_reference operator[](const typename object_t::key_type &key) const
21525 {
21526 // const operator[] only works for objects
21527 if (JSON_HEDLEY_LIKELY(is_object()))
21528 {
21529 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21530 return m_value.object->find(key)->second;
21531 }
21532
21533 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21534 }
21535
21563 template<typename T>
21564 JSON_HEDLEY_NON_NULL(2)
21565 reference operator[](T *key)
21566 {
21567 // implicitly convert null to object
21568 if (is_null())
21569 {
21570 m_type = value_t::object;
21573 }
21574
21575 // at only works for objects
21576 if (JSON_HEDLEY_LIKELY(is_object()))
21577 {
21578 return set_parent(m_value.object->operator[](key));
21579 }
21580
21581 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21582 }
21583
21614 template<typename T>
21615 JSON_HEDLEY_NON_NULL(2)
21616 const_reference operator[](T *key) const
21617 {
21618 // at only works for objects
21619 if (JSON_HEDLEY_LIKELY(is_object()))
21620 {
21621 JSON_ASSERT(m_value.object->find(key) != m_value.object->end());
21622 return m_value.object->find(key)->second;
21623 }
21624
21625 JSON_THROW(type_error::create(305, "cannot use operator[] with a string argument with " + std::string(type_name()), *this));
21626 }
21627
21678 // using std::is_convertible in a std::enable_if will fail when using explicit conversions
21679 template < class ValueType, typename std::enable_if <
21681 && !std::is_same<value_t, ValueType>::value, int >::type = 0 >
21682 ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
21683 {
21684 // at only works for objects
21685 if (JSON_HEDLEY_LIKELY(is_object()))
21686 {
21687 // if key is found, return value and given default value otherwise
21688 const auto it = find(key);
21689
21690 if (it != end())
21691 {
21692 return it->template get<ValueType>();
21693 }
21694
21695 return default_value;
21696 }
21697
21698 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21699 }
21700
21705 string_t value(const typename object_t::key_type &key, const char *default_value) const
21706 {
21707 return value(key, string_t(default_value));
21708 }
21709
21753 template<class ValueType, typename std::enable_if<
21755 ValueType value(const json_pointer &ptr, const ValueType &default_value) const
21756 {
21757 // at only works for objects
21758 if (JSON_HEDLEY_LIKELY(is_object()))
21759 {
21760 // if pointer resolves a value, return it or use default value
21761 JSON_TRY
21762 {
21763 return ptr.get_checked(this).template get<ValueType>();
21764 }
21765 JSON_INTERNAL_CATCH (out_of_range &)
21766 {
21767 return default_value;
21768 }
21769 }
21770
21771 JSON_THROW(type_error::create(306, "cannot use value() with " + std::string(type_name()), *this));
21772 }
21773
21778 JSON_HEDLEY_NON_NULL(3)
21779 string_t value(const json_pointer &ptr, const char *default_value) const
21780 {
21781 return value(ptr, string_t(default_value));
21782 }
21783
21810 {
21811 return *begin();
21812 }
21813
21818 {
21819 return *cbegin();
21820 }
21821
21854 {
21855 auto tmp = end();
21856 --tmp;
21857 return *tmp;
21858 }
21859
21864 {
21865 auto tmp = cend();
21866 --tmp;
21867 return *tmp;
21868 }
21869
21916 template < class IteratorType, typename std::enable_if <
21917 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
21918 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
21919 = 0 >
21920 IteratorType erase(IteratorType pos)
21921 {
21922 // make sure iterator fits the current value
21923 if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
21924 {
21925 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
21926 }
21927
21928 IteratorType result = end();
21929
21930 switch (m_type)
21931 {
21932 case value_t::boolean:
21936 case value_t::string:
21937 case value_t::binary:
21938 {
21939 if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
21940 {
21941 JSON_THROW(invalid_iterator::create(205, "iterator out of range", *this));
21942 }
21943
21944 if (is_string())
21945 {
21946 AllocatorType<string_t> alloc;
21947 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21948 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21949 m_value.string = nullptr;
21950 }
21951
21952 else if (is_binary())
21953 {
21954 AllocatorType<binary_t> alloc;
21955 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21956 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21957 m_value.binary = nullptr;
21958 }
21959
21960 m_type = value_t::null;
21962 break;
21963 }
21964
21965 case value_t::object:
21966 {
21967 result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
21968 break;
21969 }
21970
21971 case value_t::array:
21972 {
21973 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
21974 break;
21975 }
21976
21977 case value_t::null:
21978 case value_t::discarded:
21979 default:
21980 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
21981 }
21982
21983 return result;
21984 }
21985
22032 template < class IteratorType, typename std::enable_if <
22033 std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
22034 std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int >::type
22035 = 0 >
22036 IteratorType erase(IteratorType first, IteratorType last)
22037 {
22038 // make sure iterator fits the current value
22039 if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
22040 {
22041 JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", *this));
22042 }
22043
22044 IteratorType result = end();
22045
22046 switch (m_type)
22047 {
22048 case value_t::boolean:
22052 case value_t::string:
22053 case value_t::binary:
22054 {
22055 if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
22056 || !last.m_it.primitive_iterator.is_end()))
22057 {
22058 JSON_THROW(invalid_iterator::create(204, "iterators out of range", *this));
22059 }
22060
22061 if (is_string())
22062 {
22063 AllocatorType<string_t> alloc;
22064 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
22065 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
22066 m_value.string = nullptr;
22067 }
22068
22069 else if (is_binary())
22070 {
22071 AllocatorType<binary_t> alloc;
22072 std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
22073 std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
22074 m_value.binary = nullptr;
22075 }
22076
22077 m_type = value_t::null;
22079 break;
22080 }
22081
22082 case value_t::object:
22083 {
22084 result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
22085 last.m_it.object_iterator);
22086 break;
22087 }
22088
22089 case value_t::array:
22090 {
22091 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
22092 last.m_it.array_iterator);
22093 break;
22094 }
22095
22096 case value_t::null:
22097 case value_t::discarded:
22098 default:
22099 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
22100 }
22101
22102 return result;
22103 }
22104
22134 size_type erase(const typename object_t::key_type &key)
22135 {
22136 // this erase only works for objects
22137 if (JSON_HEDLEY_LIKELY(is_object()))
22138 {
22139 return m_value.object->erase(key);
22140 }
22141
22142 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
22143 }
22144
22169 void erase(const size_type idx)
22170 {
22171 // this erase only works for arrays
22172 if (JSON_HEDLEY_LIKELY(is_array()))
22173 {
22174 if (JSON_HEDLEY_UNLIKELY(idx >= size()))
22175 {
22176 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", *this));
22177 }
22178
22179 m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
22180 }
22181
22182 else
22183 {
22184 JSON_THROW(type_error::create(307, "cannot use erase() with " + std::string(type_name()), *this));
22185 }
22186 }
22187
22189
22190
22192 // lookup //
22194
22197
22222 template<typename KeyT>
22223 iterator find(KeyT &&key)
22224 {
22225 auto result = end();
22226
22227 if (is_object())
22228 {
22229 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
22230 }
22231
22232 return result;
22233 }
22234
22239 template<typename KeyT>
22240 const_iterator find(KeyT &&key) const
22241 {
22242 auto result = cend();
22243
22244 if (is_object())
22245 {
22246 result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
22247 }
22248
22249 return result;
22250 }
22251
22273 template<typename KeyT>
22274 size_type count(KeyT &&key) const
22275 {
22276 // return 0 for all nonobject types
22277 return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
22278 }
22279
22305 template < typename KeyT, typename std::enable_if <
22306 !std::is_same<typename std::decay<KeyT>::type, json_pointer>::value, int >::type = 0 >
22307 bool contains(KeyT && key) const
22308 {
22309 return is_object() && m_value.object->find(std::forward<KeyT>(key)) != m_value.object->end();
22310 }
22311
22338 bool contains(const json_pointer &ptr) const
22339 {
22340 return ptr.contains(this);
22341 }
22342
22344
22345
22347 // iterators //
22349
22352
22377 iterator begin() noexcept
22378 {
22379 iterator result(this);
22380 result.set_begin();
22381 return result;
22382 }
22383
22387 const_iterator begin() const noexcept
22388 {
22389 return cbegin();
22390 }
22391
22417 const_iterator cbegin() const noexcept
22418 {
22419 const_iterator result(this);
22420 result.set_begin();
22421 return result;
22422 }
22423
22448 iterator end() noexcept
22449 {
22450 iterator result(this);
22451 result.set_end();
22452 return result;
22453 }
22454
22458 const_iterator end() const noexcept
22459 {
22460 return cend();
22461 }
22462
22488 const_iterator cend() const noexcept
22489 {
22490 const_iterator result(this);
22491 result.set_end();
22492 return result;
22493 }
22494
22519 {
22520 return reverse_iterator(end());
22521 }
22522
22527 {
22528 return crbegin();
22529 }
22530
22556 {
22557 return reverse_iterator(begin());
22558 }
22559
22564 {
22565 return crend();
22566 }
22567
22593 {
22594 return const_reverse_iterator(cend());
22595 }
22596
22622 {
22624 }
22625
22626public:
22684 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22686 {
22687 return ref.items();
22688 }
22689
22693 JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
22695 {
22696 return ref.items();
22697 }
22698
22768 {
22769 return iteration_proxy<iterator>(*this);
22770 }
22771
22776 {
22777 return iteration_proxy<const_iterator>(*this);
22778 }
22779
22781
22782
22784 // capacity //
22786
22789
22832 bool empty() const noexcept
22833 {
22834 switch (m_type)
22835 {
22836 case value_t::null:
22837 {
22838 // null values are empty
22839 return true;
22840 }
22841
22842 case value_t::array:
22843 {
22844 // delegate call to array_t::empty()
22845 return m_value.array->empty();
22846 }
22847
22848 case value_t::object:
22849 {
22850 // delegate call to object_t::empty()
22851 return m_value.object->empty();
22852 }
22853
22854 case value_t::string:
22855 case value_t::boolean:
22859 case value_t::binary:
22860 case value_t::discarded:
22861 default:
22862 {
22863 // all other types are nonempty
22864 return false;
22865 }
22866 }
22867 }
22868
22912 size_type size() const noexcept
22913 {
22914 switch (m_type)
22915 {
22916 case value_t::null:
22917 {
22918 // null values are empty
22919 return 0;
22920 }
22921
22922 case value_t::array:
22923 {
22924 // delegate call to array_t::size()
22925 return m_value.array->size();
22926 }
22927
22928 case value_t::object:
22929 {
22930 // delegate call to object_t::size()
22931 return m_value.object->size();
22932 }
22933
22934 case value_t::string:
22935 case value_t::boolean:
22939 case value_t::binary:
22940 case value_t::discarded:
22941 default:
22942 {
22943 // all other types have size 1
22944 return 1;
22945 }
22946 }
22947 }
22948
22990 size_type max_size() const noexcept
22991 {
22992 switch (m_type)
22993 {
22994 case value_t::array:
22995 {
22996 // delegate call to array_t::max_size()
22997 return m_value.array->max_size();
22998 }
22999
23000 case value_t::object:
23001 {
23002 // delegate call to object_t::max_size()
23003 return m_value.object->max_size();
23004 }
23005
23006 case value_t::null:
23007 case value_t::string:
23008 case value_t::boolean:
23012 case value_t::binary:
23013 case value_t::discarded:
23014 default:
23015 {
23016 // all other types have max_size() == size()
23017 return size();
23018 }
23019 }
23020 }
23021
23023
23024
23026 // modifiers //
23028
23031
23069 void clear() noexcept
23070 {
23071 switch (m_type)
23072 {
23074 {
23075 m_value.number_integer = 0;
23076 break;
23077 }
23078
23080 {
23081 m_value.number_unsigned = 0;
23082 break;
23083 }
23084
23086 {
23087 m_value.number_float = 0.0;
23088 break;
23089 }
23090
23091 case value_t::boolean:
23092 {
23093 m_value.boolean = false;
23094 break;
23095 }
23096
23097 case value_t::string:
23098 {
23099 m_value.string->clear();
23100 break;
23101 }
23102
23103 case value_t::binary:
23104 {
23105 m_value.binary->clear();
23106 break;
23107 }
23108
23109 case value_t::array:
23110 {
23111 m_value.array->clear();
23112 break;
23113 }
23114
23115 case value_t::object:
23116 {
23117 m_value.object->clear();
23118 break;
23119 }
23120
23121 case value_t::null:
23122 case value_t::discarded:
23123 default:
23124 break;
23125 }
23126 }
23127
23149 {
23150 // push_back only works for null objects or arrays
23151 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23152 {
23153 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
23154 }
23155
23156 // transform null object into an array
23157 if (is_null())
23158 {
23159 m_type = value_t::array;
23162 }
23163
23164 // add element to array (move semantics)
23165 const auto old_capacity = m_value.array->capacity();
23166 m_value.array->push_back(std::move(val));
23167 set_parent(m_value.array->back(), old_capacity);
23168 // if val is moved from, basic_json move constructor marks it null so we do not call the destructor
23169 }
23170
23176 {
23177 push_back(std::move(val));
23178 return *this;
23179 }
23180
23185 void push_back(const basic_json &val)
23186 {
23187 // push_back only works for null objects or arrays
23188 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23189 {
23190 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
23191 }
23192
23193 // transform null object into an array
23194 if (is_null())
23195 {
23196 m_type = value_t::array;
23199 }
23200
23201 // add element to array
23202 const auto old_capacity = m_value.array->capacity();
23203 m_value.array->push_back(val);
23204 set_parent(m_value.array->back(), old_capacity);
23205 }
23206
23212 {
23213 push_back(val);
23214 return *this;
23215 }
23216
23237 void push_back(const typename object_t::value_type &val)
23238 {
23239 // push_back only works for null objects or objects
23240 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23241 {
23242 JSON_THROW(type_error::create(308, "cannot use push_back() with " + std::string(type_name()), *this));
23243 }
23244
23245 // transform null object into an object
23246 if (is_null())
23247 {
23248 m_type = value_t::object;
23251 }
23252
23253 // add element to object
23254 auto res = m_value.object->insert(val);
23255 set_parent(res.first->second);
23256 }
23257
23262 reference operator+=(const typename object_t::value_type &val)
23263 {
23264 push_back(val);
23265 return *this;
23266 }
23267
23294 {
23295 if (is_object() && init.size() == 2 && (*init.begin())->is_string())
23296 {
23297 basic_json &&key = init.begin()->moved_or_copied();
23298 push_back(typename object_t::value_type(
23299 std::move(key.get_ref<string_t &>()), (init.begin() + 1)->moved_or_copied()));
23300 }
23301
23302 else
23303 {
23304 push_back(basic_json(init));
23305 }
23306 }
23307
23313 {
23314 push_back(init);
23315 return *this;
23316 }
23317
23341 template<class... Args>
23342 reference emplace_back(Args &&... args)
23343 {
23344 // emplace_back only works for null objects or arrays
23345 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
23346 {
23347 JSON_THROW(type_error::create(311, "cannot use emplace_back() with " + std::string(type_name()), *this));
23348 }
23349
23350 // transform null object into an array
23351 if (is_null())
23352 {
23353 m_type = value_t::array;
23356 }
23357
23358 // add element to array (perfect forwarding)
23359 const auto old_capacity = m_value.array->capacity();
23360 m_value.array->emplace_back(std::forward<Args>(args)...);
23361 return set_parent(m_value.array->back(), old_capacity);
23362 }
23363
23391 template<class... Args>
23392 std::pair<iterator, bool> emplace(Args &&... args)
23393 {
23394 // emplace only works for null objects or arrays
23395 if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
23396 {
23397 JSON_THROW(type_error::create(311, "cannot use emplace() with " + std::string(type_name()), *this));
23398 }
23399
23400 // transform null object into an object
23401 if (is_null())
23402 {
23403 m_type = value_t::object;
23406 }
23407
23408 // add element to array (perfect forwarding)
23409 auto res = m_value.object->emplace(std::forward<Args>(args)...);
23410 set_parent(res.first->second);
23411 // create result iterator and set iterator to the result of emplace
23412 auto it = begin();
23413 it.m_it.object_iterator = res.first;
23414 // return pair of iterator and boolean
23415 return {it, res.second};
23416 }
23417
23421 template<typename... Args>
23423 {
23424 iterator result(this);
23425 JSON_ASSERT(m_value.array != nullptr);
23426 auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
23427 m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
23428 result.m_it.array_iterator = m_value.array->begin() + insert_pos;
23429 // This could have been written as:
23430 // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
23431 // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
23432 set_parents();
23433 return result;
23434 }
23435
23459 {
23460 // insert only works for arrays
23461 if (JSON_HEDLEY_LIKELY(is_array()))
23462 {
23463 // check if iterator pos fits to this JSON value
23464 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23465 {
23466 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23467 }
23468
23469 // insert to array and return iterator
23470 return insert_iterator(pos, val);
23471 }
23472
23473 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23474 }
23475
23481 {
23482 return insert(pos, val);
23483 }
23484
23510 {
23511 // insert only works for arrays
23512 if (JSON_HEDLEY_LIKELY(is_array()))
23513 {
23514 // check if iterator pos fits to this JSON value
23515 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23516 {
23517 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23518 }
23519
23520 // insert to array and return iterator
23521 return insert_iterator(pos, cnt, val);
23522 }
23523
23524 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23525 }
23526
23558 {
23559 // insert only works for arrays
23560 if (JSON_HEDLEY_UNLIKELY(!is_array()))
23561 {
23562 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23563 }
23564
23565 // check if iterator pos fits to this JSON value
23566 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23567 {
23568 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23569 }
23570
23571 // check if range iterators belong to the same JSON object
23572 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23573 {
23574 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23575 }
23576
23577 if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
23578 {
23579 JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", *this));
23580 }
23581
23582 // insert to array and return iterator
23583 return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
23584 }
23585
23611 {
23612 // insert only works for arrays
23613 if (JSON_HEDLEY_UNLIKELY(!is_array()))
23614 {
23615 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23616 }
23617
23618 // check if iterator pos fits to this JSON value
23619 if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
23620 {
23621 JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", *this));
23622 }
23623
23624 // insert to array and return iterator
23625 return insert_iterator(pos, ilist.begin(), ilist.end());
23626 }
23627
23652 {
23653 // insert only works for objects
23654 if (JSON_HEDLEY_UNLIKELY(!is_object()))
23655 {
23656 JSON_THROW(type_error::create(309, "cannot use insert() with " + std::string(type_name()), *this));
23657 }
23658
23659 // check if range iterators belong to the same JSON object
23660 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23661 {
23662 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23663 }
23664
23665 // passed iterators must belong to objects
23666 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
23667 {
23668 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23669 }
23670
23671 m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
23672 }
23673
23694 {
23695 // implicitly convert null value to an empty object
23696 if (is_null())
23697 {
23698 m_type = value_t::object;
23699 m_value.object = create<object_t>();
23701 }
23702
23703 if (JSON_HEDLEY_UNLIKELY(!is_object()))
23704 {
23705 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23706 }
23707
23708 if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
23709 {
23710 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
23711 }
23712
23713 for (auto it = j.cbegin(); it != j.cend(); ++it)
23714 {
23715 m_value.object->operator[](it.key()) = it.value();
23716#if JSON_DIAGNOSTICS
23717 m_value.object->operator[](it.key()).m_parent = this;
23718#endif
23719 }
23720 }
23721
23749 {
23750 // implicitly convert null value to an empty object
23751 if (is_null())
23752 {
23753 m_type = value_t::object;
23754 m_value.object = create<object_t>();
23756 }
23757
23758 if (JSON_HEDLEY_UNLIKELY(!is_object()))
23759 {
23760 JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
23761 }
23762
23763 // check if range iterators belong to the same JSON object
23764 if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
23765 {
23766 JSON_THROW(invalid_iterator::create(210, "iterators do not fit", *this));
23767 }
23768
23769 // passed iterators must belong to objects
23770 if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()
23771 || !last.m_object->is_object()))
23772 {
23773 JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", *this));
23774 }
23775
23776 for (auto it = first; it != last; ++it)
23777 {
23778 m_value.object->operator[](it.key()) = it.value();
23779#if JSON_DIAGNOSTICS
23780 m_value.object->operator[](it.key()).m_parent = this;
23781#endif
23782 }
23783 }
23784
23802 void swap(reference other) noexcept (
23803 std::is_nothrow_move_constructible<value_t>::value &&
23804 std::is_nothrow_move_assignable<value_t>::value &&
23805 std::is_nothrow_move_constructible<json_value>::value &&
23806 std::is_nothrow_move_assignable<json_value>::value
23807 )
23808 {
23809 std::swap(m_type, other.m_type);
23810 std::swap(m_value, other.m_value);
23811 set_parents();
23812 other.set_parents();
23814 }
23815
23834 friend void swap(reference left, reference right) noexcept (
23835 std::is_nothrow_move_constructible<value_t>::value &&
23836 std::is_nothrow_move_assignable<value_t>::value &&
23837 std::is_nothrow_move_constructible<json_value>::value &&
23838 std::is_nothrow_move_assignable<json_value>::value
23839 )
23840 {
23841 left.swap(right);
23842 }
23843
23864 void swap(array_t &other) // NOLINT(bugprone-exception-escape)
23865 {
23866 // swap only works for arrays
23867 if (JSON_HEDLEY_LIKELY(is_array()))
23868 {
23869 std::swap(*(m_value.array), other);
23870 }
23871
23872 else
23873 {
23874 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23875 }
23876 }
23877
23898 void swap(object_t &other) // NOLINT(bugprone-exception-escape)
23899 {
23900 // swap only works for objects
23901 if (JSON_HEDLEY_LIKELY(is_object()))
23902 {
23903 std::swap(*(m_value.object), other);
23904 }
23905
23906 else
23907 {
23908 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23909 }
23910 }
23911
23932 void swap(string_t &other) // NOLINT(bugprone-exception-escape)
23933 {
23934 // swap only works for strings
23935 if (JSON_HEDLEY_LIKELY(is_string()))
23936 {
23937 std::swap(*(m_value.string), other);
23938 }
23939
23940 else
23941 {
23942 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23943 }
23944 }
23945
23966 void swap(binary_t &other) // NOLINT(bugprone-exception-escape)
23967 {
23968 // swap only works for strings
23969 if (JSON_HEDLEY_LIKELY(is_binary()))
23970 {
23971 std::swap(*(m_value.binary), other);
23972 }
23973
23974 else
23975 {
23976 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23977 }
23978 }
23979
23981 void swap(typename binary_t::container_type &other) // NOLINT(bugprone-exception-escape)
23982 {
23983 // swap only works for strings
23984 if (JSON_HEDLEY_LIKELY(is_binary()))
23985 {
23986 std::swap(*(m_value.binary), other);
23987 }
23988
23989 else
23990 {
23991 JSON_THROW(type_error::create(310, "cannot use swap() with " + std::string(type_name()), *this));
23992 }
23993 }
23994
23996
23997public:
23999 // lexicographical comparison operators //
24001
24004
24060 friend bool operator==(const_reference lhs, const_reference rhs) noexcept
24061 {
24062#ifdef __GNUC__
24063#pragma GCC diagnostic push
24064#pragma GCC diagnostic ignored "-Wfloat-equal"
24065#endif
24066 const auto lhs_type = lhs.type();
24067 const auto rhs_type = rhs.type();
24068
24069 if (lhs_type == rhs_type)
24070 {
24071 switch (lhs_type)
24072 {
24073 case value_t::array:
24074 return *lhs.m_value.array == *rhs.m_value.array;
24075
24076 case value_t::object:
24077 return *lhs.m_value.object == *rhs.m_value.object;
24078
24079 case value_t::null:
24080 return true;
24081
24082 case value_t::string:
24083 return *lhs.m_value.string == *rhs.m_value.string;
24084
24085 case value_t::boolean:
24086 return lhs.m_value.boolean == rhs.m_value.boolean;
24087
24089 return lhs.m_value.number_integer == rhs.m_value.number_integer;
24090
24092 return lhs.m_value.number_unsigned == rhs.m_value.number_unsigned;
24093
24095 return lhs.m_value.number_float == rhs.m_value.number_float;
24096
24097 case value_t::binary:
24098 return *lhs.m_value.binary == *rhs.m_value.binary;
24099
24100 case value_t::discarded:
24101 default:
24102 return false;
24103 }
24104 }
24105
24106 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
24107 {
24108 return static_cast<number_float_t>(lhs.m_value.number_integer) == rhs.m_value.number_float;
24109 }
24110
24111 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
24112 {
24113 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
24114 }
24115
24116 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
24117 {
24118 return static_cast<number_float_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_float;
24119 }
24120
24121 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
24122 {
24123 return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_unsigned);
24124 }
24125
24126 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
24127 {
24128 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) == rhs.m_value.number_integer;
24129 }
24130
24131 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
24132 {
24133 return lhs.m_value.number_integer == static_cast<number_integer_t>(rhs.m_value.number_unsigned);
24134 }
24135
24136 return false;
24137#ifdef __GNUC__
24138#pragma GCC diagnostic pop
24139#endif
24140 }
24141
24146 template<typename ScalarType, typename std::enable_if<
24147 std::is_scalar<ScalarType>::value, int>::type = 0>
24148 friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
24149 {
24150 return lhs == basic_json(rhs);
24151 }
24152
24157 template<typename ScalarType, typename std::enable_if<
24158 std::is_scalar<ScalarType>::value, int>::type = 0>
24159 friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
24160 {
24161 return basic_json(lhs) == rhs;
24162 }
24163
24182 friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
24183 {
24184 return !(lhs == rhs);
24185 }
24186
24191 template<typename ScalarType, typename std::enable_if<
24192 std::is_scalar<ScalarType>::value, int>::type = 0>
24193 friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
24194 {
24195 return lhs != basic_json(rhs);
24196 }
24197
24202 template<typename ScalarType, typename std::enable_if<
24203 std::is_scalar<ScalarType>::value, int>::type = 0>
24204 friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
24205 {
24206 return basic_json(lhs) != rhs;
24207 }
24208
24235 friend bool operator<(const_reference lhs, const_reference rhs) noexcept
24236 {
24237 const auto lhs_type = lhs.type();
24238 const auto rhs_type = rhs.type();
24239
24240 if (lhs_type == rhs_type)
24241 {
24242 switch (lhs_type)
24243 {
24244 case value_t::array:
24245 // note parentheses are necessary, see
24246 // https://github.com/nlohmann/json/issues/1530
24247 return (*lhs.m_value.array) < (*rhs.m_value.array);
24248
24249 case value_t::object:
24250 return (*lhs.m_value.object) < (*rhs.m_value.object);
24251
24252 case value_t::null:
24253 return false;
24254
24255 case value_t::string:
24256 return (*lhs.m_value.string) < (*rhs.m_value.string);
24257
24258 case value_t::boolean:
24259 return (lhs.m_value.boolean) < (rhs.m_value.boolean);
24260
24262 return (lhs.m_value.number_integer) < (rhs.m_value.number_integer);
24263
24265 return (lhs.m_value.number_unsigned) < (rhs.m_value.number_unsigned);
24266
24268 return (lhs.m_value.number_float) < (rhs.m_value.number_float);
24269
24270 case value_t::binary:
24271 return (*lhs.m_value.binary) < (*rhs.m_value.binary);
24272
24273 case value_t::discarded:
24274 default:
24275 return false;
24276 }
24277 }
24278
24279 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float)
24280 {
24281 return static_cast<number_float_t>(lhs.m_value.number_integer) < rhs.m_value.number_float;
24282 }
24283
24284 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer)
24285 {
24286 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_integer);
24287 }
24288
24289 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float)
24290 {
24291 return static_cast<number_float_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_float;
24292 }
24293
24294 else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned)
24295 {
24296 return lhs.m_value.number_float < static_cast<number_float_t>(rhs.m_value.number_unsigned);
24297 }
24298
24299 else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned)
24300 {
24301 return lhs.m_value.number_integer < static_cast<number_integer_t>(rhs.m_value.number_unsigned);
24302 }
24303
24304 else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer)
24305 {
24306 return static_cast<number_integer_t>(lhs.m_value.number_unsigned) < rhs.m_value.number_integer;
24307 }
24308
24309 // We only reach this line if we cannot compare values. In that case,
24310 // we compare types. Note we have to call the operator explicitly,
24311 // because MSVC has problems otherwise.
24312 return operator<(lhs_type, rhs_type);
24313 }
24314
24319 template<typename ScalarType, typename std::enable_if<
24320 std::is_scalar<ScalarType>::value, int>::type = 0>
24321 friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
24322 {
24323 return lhs < basic_json(rhs);
24324 }
24325
24330 template<typename ScalarType, typename std::enable_if<
24331 std::is_scalar<ScalarType>::value, int>::type = 0>
24332 friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
24333 {
24334 return basic_json(lhs) < rhs;
24335 }
24336
24356 friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
24357 {
24358 return !(rhs < lhs);
24359 }
24360
24365 template<typename ScalarType, typename std::enable_if<
24366 std::is_scalar<ScalarType>::value, int>::type = 0>
24367 friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
24368 {
24369 return lhs <= basic_json(rhs);
24370 }
24371
24376 template<typename ScalarType, typename std::enable_if<
24377 std::is_scalar<ScalarType>::value, int>::type = 0>
24378 friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
24379 {
24380 return basic_json(lhs) <= rhs;
24381 }
24382
24402 friend bool operator>(const_reference lhs, const_reference rhs) noexcept
24403 {
24404 return !(lhs <= rhs);
24405 }
24406
24411 template<typename ScalarType, typename std::enable_if<
24412 std::is_scalar<ScalarType>::value, int>::type = 0>
24413 friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
24414 {
24415 return lhs > basic_json(rhs);
24416 }
24417
24422 template<typename ScalarType, typename std::enable_if<
24423 std::is_scalar<ScalarType>::value, int>::type = 0>
24424 friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
24425 {
24426 return basic_json(lhs) > rhs;
24427 }
24428
24448 friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
24449 {
24450 return !(lhs < rhs);
24451 }
24452
24457 template<typename ScalarType, typename std::enable_if<
24458 std::is_scalar<ScalarType>::value, int>::type = 0>
24459 friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
24460 {
24461 return lhs >= basic_json(rhs);
24462 }
24463
24468 template<typename ScalarType, typename std::enable_if<
24469 std::is_scalar<ScalarType>::value, int>::type = 0>
24470 friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
24471 {
24472 return basic_json(lhs) >= rhs;
24473 }
24474
24476
24478 // serialization //
24480
24483#ifndef JSON_NO_IO
24515 friend std::ostream &operator<<(std::ostream &o, const basic_json &j)
24516 {
24517 // read width member and use it as indentation parameter if nonzero
24518 const bool pretty_print = o.width() > 0;
24519 const auto indentation = pretty_print ? o.width() : 0;
24520 // reset width to 0 for subsequent calls to this stream
24521 o.width(0);
24522 // do the actual serialization
24523 serializer s(detail::output_adapter<char>(o), o.fill());
24524 s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
24525 return o;
24526 }
24527
24536 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream &, const basic_json &))
24537 friend std::ostream &operator>>(const basic_json &j, std::ostream &o)
24538 {
24539 return o << j;
24540 }
24541#endif // JSON_NO_IO
24543
24544
24546 // deserialization //
24548
24551
24603 template<typename InputType>
24604 JSON_HEDLEY_WARN_UNUSED_RESULT
24605 static basic_json parse(InputType &&i,
24606 const parser_callback_t cb = nullptr,
24607 const bool allow_exceptions = true,
24608 const bool ignore_comments = false)
24609 {
24610 basic_json result;
24611 parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
24612 return result;
24613 }
24614
24641 template<typename IteratorType>
24642 JSON_HEDLEY_WARN_UNUSED_RESULT
24643 static basic_json parse(IteratorType first,
24644 IteratorType last,
24645 const parser_callback_t cb = nullptr,
24646 const bool allow_exceptions = true,
24647 const bool ignore_comments = false)
24648 {
24649 basic_json result;
24650 parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
24651 return result;
24652 }
24653
24654 JSON_HEDLEY_WARN_UNUSED_RESULT
24655 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
24657 const parser_callback_t cb = nullptr,
24658 const bool allow_exceptions = true,
24659 const bool ignore_comments = false)
24660 {
24661 basic_json result;
24662 parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
24663 return result;
24664 }
24665
24696 template<typename InputType>
24697 static bool accept(InputType &&i,
24698 const bool ignore_comments = false)
24699 {
24700 return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
24701 }
24702
24703 template<typename IteratorType>
24704 static bool accept(IteratorType first, IteratorType last,
24705 const bool ignore_comments = false)
24706 {
24707 return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
24708 }
24709
24710 JSON_HEDLEY_WARN_UNUSED_RESULT
24711 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
24712 static bool accept(detail::span_input_adapter &&i,
24713 const bool ignore_comments = false)
24714 {
24715 return parser(i.get(), nullptr, false, ignore_comments).accept(true);
24716 }
24717
24758 template <typename InputType, typename SAX>
24759 JSON_HEDLEY_NON_NULL(2)
24760 static bool sax_parse(InputType &&i, SAX *sax,
24762 const bool strict = true,
24763 const bool ignore_comments = false)
24764 {
24765 auto ia = detail::input_adapter(std::forward<InputType>(i));
24766 return format == input_format_t::json
24767 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24768 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24769 }
24770
24771 template<class IteratorType, class SAX>
24772 JSON_HEDLEY_NON_NULL(3)
24773 static bool sax_parse(IteratorType first, IteratorType last, SAX *sax,
24774 input_format_t format = input_format_t::json,
24775 const bool strict = true,
24776 const bool ignore_comments = false)
24777 {
24778 auto ia = detail::input_adapter(std::move(first), std::move(last));
24779 return format == input_format_t::json
24780 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24781 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24782 }
24783
24784 template <typename SAX>
24785 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
24786 JSON_HEDLEY_NON_NULL(2)
24787 static bool sax_parse(detail::span_input_adapter &&i, SAX *sax,
24788 input_format_t format = input_format_t::json,
24789 const bool strict = true,
24790 const bool ignore_comments = false)
24791 {
24792 auto ia = i.get();
24793 return format == input_format_t::json
24794 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24795 ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
24796 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
24797 : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia)).sax_parse(format, sax, strict);
24798 }
24799#ifndef JSON_NO_IO
24808 JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream &, basic_json &))
24809 friend std::istream &operator<<(basic_json &j, std::istream &i)
24810 {
24811 return operator>>(i, j);
24812 }
24813
24839 friend std::istream &operator>>(std::istream &i, basic_json &j)
24840 {
24841 parser(detail::input_adapter(i)).parse(false, j);
24842 return i;
24843 }
24844#endif // JSON_NO_IO
24846
24848 // convenience functions //
24850
24882 JSON_HEDLEY_RETURNS_NON_NULL
24883 const char *type_name() const noexcept
24884 {
24885 {
24886 switch (m_type)
24887 {
24888 case value_t::null:
24889 return "null";
24890
24891 case value_t::object:
24892 return "object";
24893
24894 case value_t::array:
24895 return "array";
24896
24897 case value_t::string:
24898 return "string";
24899
24900 case value_t::boolean:
24901 return "boolean";
24902
24903 case value_t::binary:
24904 return "binary";
24905
24906 case value_t::discarded:
24907 return "discarded";
24908
24912 default:
24913 return "number";
24914 }
24915 }
24916 }
24917
24918
24919JSON_PRIVATE_UNLESS_TESTED:
24921 // member variables //
24923
24925 value_t m_type = value_t::null;
24926
24929
24930#if JSON_DIAGNOSTICS
24932 basic_json *m_parent = nullptr;
24933#endif
24934
24936 // binary serialization/deserialization //
24938
24941
24942public:
25041 static std::vector<std::uint8_t> to_cbor(const basic_json &j)
25042 {
25043 std::vector<std::uint8_t> result;
25044 to_cbor(j, result);
25045 return result;
25046 }
25047
25049 {
25050 binary_writer<std::uint8_t>(o).write_cbor(j);
25051 }
25052
25053 static void to_cbor(const basic_json &j, detail::output_adapter<char> o)
25054 {
25055 binary_writer<char>(o).write_cbor(j);
25056 }
25057
25136 static std::vector<std::uint8_t> to_msgpack(const basic_json &j)
25137 {
25138 std::vector<std::uint8_t> result;
25139 to_msgpack(j, result);
25140 return result;
25141 }
25142
25144 {
25145 binary_writer<std::uint8_t>(o).write_msgpack(j);
25146 }
25147
25148 static void to_msgpack(const basic_json &j, detail::output_adapter<char> o)
25149 {
25150 binary_writer<char>(o).write_msgpack(j);
25151 }
25152
25239 static std::vector<std::uint8_t> to_ubjson(const basic_json &j,
25240 const bool use_size = false,
25241 const bool use_type = false)
25242 {
25243 std::vector<std::uint8_t> result;
25244 to_ubjson(j, result, use_size, use_type);
25245 return result;
25246 }
25247
25249 const bool use_size = false, const bool use_type = false)
25250 {
25251 binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
25252 }
25253
25254 static void to_ubjson(const basic_json &j, detail::output_adapter<char> o,
25255 const bool use_size = false, const bool use_type = false)
25256 {
25257 binary_writer<char>(o).write_ubjson(j, use_size, use_type);
25258 }
25259
25260
25317 static std::vector<std::uint8_t> to_bson(const basic_json &j)
25318 {
25319 std::vector<std::uint8_t> result;
25320 to_bson(j, result);
25321 return result;
25322 }
25323
25333 {
25335 }
25336
25341 {
25343 }
25344
25345
25448 template<typename InputType>
25449 JSON_HEDLEY_WARN_UNUSED_RESULT
25450 static basic_json from_cbor(InputType &&i,
25451 const bool strict = true,
25452 const bool allow_exceptions = true,
25453 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25454 {
25455 basic_json result;
25456 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25457 auto ia = detail::input_adapter(std::forward<InputType>(i));
25458 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25459 return res ? result : basic_json(value_t::discarded);
25460 }
25461
25465 template<typename IteratorType>
25466 JSON_HEDLEY_WARN_UNUSED_RESULT
25467 static basic_json from_cbor(IteratorType first, IteratorType last,
25468 const bool strict = true,
25469 const bool allow_exceptions = true,
25470 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25471 {
25472 basic_json result;
25473 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25474 auto ia = detail::input_adapter(std::move(first), std::move(last));
25475 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25476 return res ? result : basic_json(value_t::discarded);
25477 }
25478
25479 template<typename T>
25480 JSON_HEDLEY_WARN_UNUSED_RESULT
25481 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25482 static basic_json from_cbor(const T *ptr, std::size_t len,
25483 const bool strict = true,
25484 const bool allow_exceptions = true,
25485 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25486 {
25487 return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
25488 }
25489
25490
25491 JSON_HEDLEY_WARN_UNUSED_RESULT
25492 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
25493 static basic_json from_cbor(detail::span_input_adapter &&i,
25494 const bool strict = true,
25495 const bool allow_exceptions = true,
25496 const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
25497 {
25498 basic_json result;
25499 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25500 auto ia = i.get();
25501 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25502 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
25503 return res ? result : basic_json(value_t::discarded);
25504 }
25505
25592 template<typename InputType>
25593 JSON_HEDLEY_WARN_UNUSED_RESULT
25594 static basic_json from_msgpack(InputType &&i,
25595 const bool strict = true,
25596 const bool allow_exceptions = true)
25597 {
25598 basic_json result;
25599 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25600 auto ia = detail::input_adapter(std::forward<InputType>(i));
25601 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25602 return res ? result : basic_json(value_t::discarded);
25603 }
25604
25608 template<typename IteratorType>
25609 JSON_HEDLEY_WARN_UNUSED_RESULT
25610 static basic_json from_msgpack(IteratorType first, IteratorType last,
25611 const bool strict = true,
25612 const bool allow_exceptions = true)
25613 {
25614 basic_json result;
25615 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25616 auto ia = detail::input_adapter(std::move(first), std::move(last));
25617 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25618 return res ? result : basic_json(value_t::discarded);
25619 }
25620
25621
25622 template<typename T>
25623 JSON_HEDLEY_WARN_UNUSED_RESULT
25624 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25625 static basic_json from_msgpack(const T *ptr, std::size_t len,
25626 const bool strict = true,
25627 const bool allow_exceptions = true)
25628 {
25629 return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
25630 }
25631
25632 JSON_HEDLEY_WARN_UNUSED_RESULT
25633 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
25634 static basic_json from_msgpack(detail::span_input_adapter &&i,
25635 const bool strict = true,
25636 const bool allow_exceptions = true)
25637 {
25638 basic_json result;
25639 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25640 auto ia = i.get();
25641 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25642 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::msgpack, &sdp, strict);
25643 return res ? result : basic_json(value_t::discarded);
25644 }
25645
25646
25709 template<typename InputType>
25710 JSON_HEDLEY_WARN_UNUSED_RESULT
25711 static basic_json from_ubjson(InputType &&i,
25712 const bool strict = true,
25713 const bool allow_exceptions = true)
25714 {
25715 basic_json result;
25716 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25717 auto ia = detail::input_adapter(std::forward<InputType>(i));
25718 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25719 return res ? result : basic_json(value_t::discarded);
25720 }
25721
25725 template<typename IteratorType>
25726 JSON_HEDLEY_WARN_UNUSED_RESULT
25727 static basic_json from_ubjson(IteratorType first, IteratorType last,
25728 const bool strict = true,
25729 const bool allow_exceptions = true)
25730 {
25731 basic_json result;
25732 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25733 auto ia = detail::input_adapter(std::move(first), std::move(last));
25734 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25735 return res ? result : basic_json(value_t::discarded);
25736 }
25737
25738 template<typename T>
25739 JSON_HEDLEY_WARN_UNUSED_RESULT
25740 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25741 static basic_json from_ubjson(const T *ptr, std::size_t len,
25742 const bool strict = true,
25743 const bool allow_exceptions = true)
25744 {
25745 return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
25746 }
25747
25748 JSON_HEDLEY_WARN_UNUSED_RESULT
25749 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
25750 static basic_json from_ubjson(detail::span_input_adapter &&i,
25751 const bool strict = true,
25752 const bool allow_exceptions = true)
25753 {
25754 basic_json result;
25755 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25756 auto ia = i.get();
25757 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25758 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::ubjson, &sdp, strict);
25759 return res ? result : basic_json(value_t::discarded);
25760 }
25761
25762
25823 template<typename InputType>
25824 JSON_HEDLEY_WARN_UNUSED_RESULT
25825 static basic_json from_bson(InputType &&i,
25826 const bool strict = true,
25827 const bool allow_exceptions = true)
25828 {
25829 basic_json result;
25830 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25831 auto ia = detail::input_adapter(std::forward<InputType>(i));
25832 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25833 return res ? result : basic_json(value_t::discarded);
25834 }
25835
25839 template<typename IteratorType>
25840 JSON_HEDLEY_WARN_UNUSED_RESULT
25841 static basic_json from_bson(IteratorType first, IteratorType last,
25842 const bool strict = true,
25843 const bool allow_exceptions = true)
25844 {
25845 basic_json result;
25846 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25847 auto ia = detail::input_adapter(std::move(first), std::move(last));
25848 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25849 return res ? result : basic_json(value_t::discarded);
25850 }
25851
25852 template<typename T>
25853 JSON_HEDLEY_WARN_UNUSED_RESULT
25854 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25855 static basic_json from_bson(const T *ptr, std::size_t len,
25856 const bool strict = true,
25857 const bool allow_exceptions = true)
25858 {
25859 return from_bson(ptr, ptr + len, strict, allow_exceptions);
25860 }
25861
25862 JSON_HEDLEY_WARN_UNUSED_RESULT
25863 JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
25864 static basic_json from_bson(detail::span_input_adapter &&i,
25865 const bool strict = true,
25866 const bool allow_exceptions = true)
25867 {
25868 basic_json result;
25869 detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
25870 auto ia = i.get();
25871 // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
25872 const bool res = binary_reader<decltype(ia)>(std::move(ia)).sax_parse(input_format_t::bson, &sdp, strict);
25873 return res ? result : basic_json(value_t::discarded);
25874 }
25876
25878 // JSON Pointer support //
25880
25883
25918 {
25919 return ptr.get_unchecked(this);
25920 }
25921
25946 {
25947 return ptr.get_unchecked(this);
25948 }
25949
25989 {
25990 return ptr.get_checked(this);
25991 }
25992
26032 {
26033 return ptr.get_checked(this);
26034 }
26035
26059 {
26061 json_pointer::flatten("", *this, result);
26062 return result;
26063 }
26064
26096 {
26097 return json_pointer::unflatten(*this);
26098 }
26099
26101
26103 // JSON Patch functions //
26105
26108
26156 basic_json patch(const basic_json &json_patch) const
26157 {
26158 // make a working copy to apply the patch to
26159 basic_json result = *this;
26160 // the valid JSON Patch operations
26161 enum class patch_operations {add, remove, replace, move, copy, test, invalid};
26162 const auto get_op = [](const std::string & op)
26163 {
26164 if (op == "add")
26165 {
26166 return patch_operations::add;
26167 }
26168
26169 if (op == "remove")
26170 {
26171 return patch_operations::remove;
26172 }
26173
26174 if (op == "replace")
26175 {
26176 return patch_operations::replace;
26177 }
26178
26179 if (op == "move")
26180 {
26181 return patch_operations::move;
26182 }
26183
26184 if (op == "copy")
26185 {
26186 return patch_operations::copy;
26187 }
26188
26189 if (op == "test")
26190 {
26191 return patch_operations::test;
26192 }
26193
26194 return patch_operations::invalid;
26195 };
26196 // wrapper for "add" operation; add value at ptr
26197 const auto operation_add = [&result](json_pointer & ptr, basic_json val)
26198 {
26199 // adding to the root of the target document means replacing it
26200 if (ptr.empty())
26201 {
26202 result = val;
26203 return;
26204 }
26205
26206 // make sure the top element of the pointer exists
26207 json_pointer top_pointer = ptr.top();
26208
26209 if (top_pointer != ptr)
26210 {
26211 result.at(top_pointer);
26212 }
26213
26214 // get reference to parent of JSON pointer ptr
26215 const auto last_path = ptr.back();
26216 ptr.pop_back();
26217 basic_json &parent = result[ptr];
26218
26219 switch (parent.m_type)
26220 {
26221 case value_t::null:
26222 case value_t::object:
26223 {
26224 // use operator[] to add value
26225 parent[last_path] = val;
26226 break;
26227 }
26228
26229 case value_t::array:
26230 {
26231 if (last_path == "-")
26232 {
26233 // special case: append to back
26234 parent.push_back(val);
26235 }
26236
26237 else
26238 {
26239 const auto idx = json_pointer::array_index(last_path);
26240
26241 if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
26242 {
26243 // avoid undefined behavior
26244 JSON_THROW(out_of_range::create(401, "array index " + std::to_string(idx) + " is out of range", parent));
26245 }
26246
26247 // default case: insert add offset
26248 parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
26249 }
26250
26251 break;
26252 }
26253
26254 // if there exists a parent it cannot be primitive
26255 case value_t::string: // LCOV_EXCL_LINE
26256 case value_t::boolean: // LCOV_EXCL_LINE
26257 case value_t::number_integer: // LCOV_EXCL_LINE
26258 case value_t::number_unsigned: // LCOV_EXCL_LINE
26259 case value_t::number_float: // LCOV_EXCL_LINE
26260 case value_t::binary: // LCOV_EXCL_LINE
26261 case value_t::discarded: // LCOV_EXCL_LINE
26262 default: // LCOV_EXCL_LINE
26263 JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
26264 }
26265 };
26266 // wrapper for "remove" operation; remove value at ptr
26267 const auto operation_remove = [this, &result](json_pointer & ptr)
26268 {
26269 // get reference to parent of JSON pointer ptr
26270 const auto last_path = ptr.back();
26271 ptr.pop_back();
26272 basic_json &parent = result.at(ptr);
26273
26274 // remove child
26275 if (parent.is_object())
26276 {
26277 // perform range check
26278 auto it = parent.find(last_path);
26279
26280 if (JSON_HEDLEY_LIKELY(it != parent.end()))
26281 {
26282 parent.erase(it);
26283 }
26284
26285 else
26286 {
26287 JSON_THROW(out_of_range::create(403, "key '" + last_path + "' not found", *this));
26288 }
26289 }
26290
26291 else if (parent.is_array())
26292 {
26293 // note erase performs range check
26294 parent.erase(json_pointer::array_index(last_path));
26295 }
26296 };
26297
26298 // type check: top level value must be an array
26299 if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
26300 {
26301 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", json_patch));
26302 }
26303
26304 // iterate and apply the operations
26305 for (const auto &val : json_patch)
26306 {
26307 // wrapper to get a value for an operation
26308 const auto get_value = [&val](const std::string & op,
26309 const std::string & member,
26310 bool string_type) -> basic_json &
26311 {
26312 // find value
26313 auto it = val.m_value.object->find(member);
26314
26315 // context-sensitive error message
26316 const auto error_msg = (op == "op") ? "operation" : "operation '" + op + "'";
26317
26318 // check if desired value is present
26319 if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
26320 {
26321 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
26322 JSON_THROW(parse_error::create(105, 0, error_msg + " must have member '" + member + "'", val));
26323 }
26324
26325 // check if result is of type string
26326 if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
26327 {
26328 // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
26329 JSON_THROW(parse_error::create(105, 0, error_msg + " must have string member '" + member + "'", val));
26330 }
26331
26332 // no error: return value
26333 return it->second;
26334 };
26335
26336 // type check: every element of the array must be an object
26337 if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
26338 {
26339 JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", val));
26340 }
26341
26342 // collect mandatory members
26343 const auto op = get_value("op", "op", true).template get<std::string>();
26344 const auto path = get_value(op, "path", true).template get<std::string>();
26345 json_pointer ptr(path);
26346
26347 switch (get_op(op))
26348 {
26349 case patch_operations::add:
26350 {
26351 operation_add(ptr, get_value("add", "value", false));
26352 break;
26353 }
26354
26355 case patch_operations::remove:
26356 {
26357 operation_remove(ptr);
26358 break;
26359 }
26360
26361 case patch_operations::replace:
26362 {
26363 // the "path" location must exist - use at()
26364 result.at(ptr) = get_value("replace", "value", false);
26365 break;
26366 }
26367
26368 case patch_operations::move:
26369 {
26370 const auto from_path = get_value("move", "from", true).template get<std::string>();
26371 json_pointer from_ptr(from_path);
26372 // the "from" location must exist - use at()
26373 basic_json v = result.at(from_ptr);
26374 // The move operation is functionally identical to a
26375 // "remove" operation on the "from" location, followed
26376 // immediately by an "add" operation at the target
26377 // location with the value that was just removed.
26378 operation_remove(from_ptr);
26379 operation_add(ptr, v);
26380 break;
26381 }
26382
26383 case patch_operations::copy:
26384 {
26385 const auto from_path = get_value("copy", "from", true).template get<std::string>();
26386 const json_pointer from_ptr(from_path);
26387 // the "from" location must exist - use at()
26388 basic_json v = result.at(from_ptr);
26389 // The copy is functionally identical to an "add"
26390 // operation at the target location using the value
26391 // specified in the "from" member.
26392 operation_add(ptr, v);
26393 break;
26394 }
26395
26396 case patch_operations::test:
26397 {
26398 bool success = false;
26399 JSON_TRY
26400 {
26401 // check if "value" matches the one at "path"
26402 // the "path" location must exist - use at()
26403 success = (result.at(ptr) == get_value("test", "value", false));
26404 }
26405 JSON_INTERNAL_CATCH (out_of_range &)
26406 {
26407 // ignore out of range errors: success remains false
26408 }
26409
26410 // throw an exception if test fails
26411 if (JSON_HEDLEY_UNLIKELY(!success))
26412 {
26413 JSON_THROW(other_error::create(501, "unsuccessful: " + val.dump(), val));
26414 }
26415
26416 break;
26417 }
26418
26419 case patch_operations::invalid:
26420 default:
26421 {
26422 // op must be "add", "remove", "replace", "move", "copy", or
26423 // "test"
26424 JSON_THROW(parse_error::create(105, 0, "operation value '" + op + "' is invalid", val));
26425 }
26426 }
26427 }
26428
26429 return result;
26430 }
26431
26465 JSON_HEDLEY_WARN_UNUSED_RESULT
26466 static basic_json diff(const basic_json &source, const basic_json &target,
26467 const std::string &path = "")
26468 {
26469 // the patch
26470 basic_json result(value_t::array);
26471
26472 // if the values are the same, return empty patch
26473 if (source == target)
26474 {
26475 return result;
26476 }
26477
26478 if (source.type() != target.type())
26479 {
26480 // different types: replace value
26481 result.push_back(
26482 {
26483 {"op", "replace"}, {"path", path}, {"value", target}
26484 });
26485 return result;
26486 }
26487
26488 switch (source.type())
26489 {
26490 case value_t::array:
26491 {
26492 // first pass: traverse common elements
26493 std::size_t i = 0;
26494
26495 while (i < source.size() && i < target.size())
26496 {
26497 // recursive call to compare array values at index i
26498 auto temp_diff = diff(source[i], target[i], path + "/" + std::to_string(i));
26499 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26500 ++i;
26501 }
26502
26503 // i now reached the end of at least one array
26504 // in a second pass, traverse the remaining elements
26505 // remove my remaining elements
26506 const auto end_index = static_cast<difference_type>(result.size());
26507
26508 while (i < source.size())
26509 {
26510 // add operations in reverse order to avoid invalid
26511 // indices
26512 result.insert(result.begin() + end_index, object(
26513 {
26514 {"op", "remove"},
26515 {"path", path + "/" + std::to_string(i)}
26516 }));
26517 ++i;
26518 }
26519
26520 // add other remaining elements
26521 while (i < target.size())
26522 {
26523 result.push_back(
26524 {
26525 {"op", "add"},
26526 {"path", path + "/-"},
26527 {"value", target[i]}
26528 });
26529 ++i;
26530 }
26531
26532 break;
26533 }
26534
26535 case value_t::object:
26536 {
26537 // first pass: traverse this object's elements
26538 for (auto it = source.cbegin(); it != source.cend(); ++it)
26539 {
26540 // escape the key name to be used in a JSON patch
26541 const auto path_key = path + "/" + detail::escape(it.key());
26542
26543 if (target.find(it.key()) != target.end())
26544 {
26545 // recursive call to compare object values at key it
26546 auto temp_diff = diff(it.value(), target[it.key()], path_key);
26547 result.insert(result.end(), temp_diff.begin(), temp_diff.end());
26548 }
26549
26550 else
26551 {
26552 // found a key that is not in o -> remove it
26553 result.push_back(object(
26554 {
26555 {"op", "remove"}, {"path", path_key}
26556 }));
26557 }
26558 }
26559
26560 // second pass: traverse other object's elements
26561 for (auto it = target.cbegin(); it != target.cend(); ++it)
26562 {
26563 if (source.find(it.key()) == source.end())
26564 {
26565 // found a key that is not in this -> add it
26566 const auto path_key = path + "/" + detail::escape(it.key());
26567 result.push_back(
26568 {
26569 {"op", "add"}, {"path", path_key},
26570 {"value", it.value()}
26571 });
26572 }
26573 }
26574
26575 break;
26576 }
26577
26578 case value_t::null:
26579 case value_t::string:
26580 case value_t::boolean:
26584 case value_t::binary:
26585 case value_t::discarded:
26586 default:
26587 {
26588 // both primitive type: replace value
26589 result.push_back(
26590 {
26591 {"op", "replace"}, {"path", path}, {"value", target}
26592 });
26593 break;
26594 }
26595 }
26596
26597 return result;
26598 }
26599
26601
26603 // JSON Merge Patch functions //
26605
26608
26651 void merge_patch(const basic_json &apply_patch)
26652 {
26653 if (apply_patch.is_object())
26654 {
26655 if (!is_object())
26656 {
26657 *this = object();
26658 }
26659
26660 for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
26661 {
26662 if (it.value().is_null())
26663 {
26664 erase(it.key());
26665 }
26666
26667 else
26668 {
26669 operator[](it.key()).merge_patch(it.value());
26670 }
26671 }
26672 }
26673
26674 else
26675 {
26676 *this = apply_patch;
26677 }
26678 }
26679
26681};
26682
26692NLOHMANN_BASIC_JSON_TPL_DECLARATION
26693std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
26694{
26695 return j.dump();
26696}
26697} // namespace nlohmann
26698
26700// nonmember support //
26702
26703// specialization of std::swap, and std::hash
26704namespace std
26705{
26706
26708template<>
26709struct hash<nlohmann::json>
26710{
26716 std::size_t operator()(const nlohmann::json &j) const
26717 {
26718 return nlohmann::detail::hash(j);
26719 }
26720};
26721
26725template<>
26727{
26733 nlohmann::detail::value_t rhs) const noexcept
26734 {
26735 return nlohmann::detail::operator<(lhs, rhs);
26736 }
26737};
26738
26739// C++20 prohibit function specialization in the std namespace.
26740#ifndef JSON_HAS_CPP_20
26741
26747template<>
26748inline void swap<nlohmann::json>(nlohmann::json &j1, nlohmann::json &j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
26749 is_nothrow_move_constructible<nlohmann::json>::value && // NOLINT(misc-redundant-expression)
26750 is_nothrow_move_assignable<nlohmann::json>::value
26751 )
26752{
26753 j1.swap(j2);
26754}
26755
26756#endif
26757
26758} // namespace std
26759
26773JSON_HEDLEY_NON_NULL(1)
26774inline nlohmann::json operator "" _json(const char *s, std::size_t n)
26775{
26776 return nlohmann::json::parse(s, s + n);
26777}
26778
26792JSON_HEDLEY_NON_NULL(1)
26793inline nlohmann::json::json_pointer operator "" _json_pointer(const char *s, std::size_t n)
26794{
26795 return nlohmann::json::json_pointer(std::string(s, n));
26796}
26797
26798// #include <nlohmann/detail/macro_unscope.hpp>
26799
26800
26801// restore clang diagnostic settings
26802#if defined(__clang__)
26803#pragma clang diagnostic pop
26804#endif
26805
26806// clean up
26807#undef JSON_ASSERT
26808#undef JSON_INTERNAL_CATCH
26809#undef JSON_CATCH
26810#undef JSON_THROW
26811#undef JSON_TRY
26812#undef JSON_PRIVATE_UNLESS_TESTED
26813#undef JSON_HAS_CPP_11
26814#undef JSON_HAS_CPP_14
26815#undef JSON_HAS_CPP_17
26816#undef JSON_HAS_CPP_20
26817#undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
26818#undef NLOHMANN_BASIC_JSON_TPL
26819#undef JSON_EXPLICIT
26820
26821// #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
26822
26823
26824#undef JSON_HEDLEY_ALWAYS_INLINE
26825#undef JSON_HEDLEY_ARM_VERSION
26826#undef JSON_HEDLEY_ARM_VERSION_CHECK
26827#undef JSON_HEDLEY_ARRAY_PARAM
26828#undef JSON_HEDLEY_ASSUME
26829#undef JSON_HEDLEY_BEGIN_C_DECLS
26830#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
26831#undef JSON_HEDLEY_CLANG_HAS_BUILTIN
26832#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
26833#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
26834#undef JSON_HEDLEY_CLANG_HAS_EXTENSION
26835#undef JSON_HEDLEY_CLANG_HAS_FEATURE
26836#undef JSON_HEDLEY_CLANG_HAS_WARNING
26837#undef JSON_HEDLEY_COMPCERT_VERSION
26838#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
26839#undef JSON_HEDLEY_CONCAT
26840#undef JSON_HEDLEY_CONCAT3
26841#undef JSON_HEDLEY_CONCAT3_EX
26842#undef JSON_HEDLEY_CONCAT_EX
26843#undef JSON_HEDLEY_CONST
26844#undef JSON_HEDLEY_CONSTEXPR
26845#undef JSON_HEDLEY_CONST_CAST
26846#undef JSON_HEDLEY_CPP_CAST
26847#undef JSON_HEDLEY_CRAY_VERSION
26848#undef JSON_HEDLEY_CRAY_VERSION_CHECK
26849#undef JSON_HEDLEY_C_DECL
26850#undef JSON_HEDLEY_DEPRECATED
26851#undef JSON_HEDLEY_DEPRECATED_FOR
26852#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
26853#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
26854#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
26855#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
26856#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
26857#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
26858#undef JSON_HEDLEY_DIAGNOSTIC_POP
26859#undef JSON_HEDLEY_DIAGNOSTIC_PUSH
26860#undef JSON_HEDLEY_DMC_VERSION
26861#undef JSON_HEDLEY_DMC_VERSION_CHECK
26862#undef JSON_HEDLEY_EMPTY_BASES
26863#undef JSON_HEDLEY_EMSCRIPTEN_VERSION
26864#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
26865#undef JSON_HEDLEY_END_C_DECLS
26866#undef JSON_HEDLEY_FLAGS
26867#undef JSON_HEDLEY_FLAGS_CAST
26868#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
26869#undef JSON_HEDLEY_GCC_HAS_BUILTIN
26870#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
26871#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
26872#undef JSON_HEDLEY_GCC_HAS_EXTENSION
26873#undef JSON_HEDLEY_GCC_HAS_FEATURE
26874#undef JSON_HEDLEY_GCC_HAS_WARNING
26875#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
26876#undef JSON_HEDLEY_GCC_VERSION
26877#undef JSON_HEDLEY_GCC_VERSION_CHECK
26878#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
26879#undef JSON_HEDLEY_GNUC_HAS_BUILTIN
26880#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
26881#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
26882#undef JSON_HEDLEY_GNUC_HAS_EXTENSION
26883#undef JSON_HEDLEY_GNUC_HAS_FEATURE
26884#undef JSON_HEDLEY_GNUC_HAS_WARNING
26885#undef JSON_HEDLEY_GNUC_VERSION
26886#undef JSON_HEDLEY_GNUC_VERSION_CHECK
26887#undef JSON_HEDLEY_HAS_ATTRIBUTE
26888#undef JSON_HEDLEY_HAS_BUILTIN
26889#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
26890#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
26891#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
26892#undef JSON_HEDLEY_HAS_EXTENSION
26893#undef JSON_HEDLEY_HAS_FEATURE
26894#undef JSON_HEDLEY_HAS_WARNING
26895#undef JSON_HEDLEY_IAR_VERSION
26896#undef JSON_HEDLEY_IAR_VERSION_CHECK
26897#undef JSON_HEDLEY_IBM_VERSION
26898#undef JSON_HEDLEY_IBM_VERSION_CHECK
26899#undef JSON_HEDLEY_IMPORT
26900#undef JSON_HEDLEY_INLINE
26901#undef JSON_HEDLEY_INTEL_CL_VERSION
26902#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
26903#undef JSON_HEDLEY_INTEL_VERSION
26904#undef JSON_HEDLEY_INTEL_VERSION_CHECK
26905#undef JSON_HEDLEY_IS_CONSTANT
26906#undef JSON_HEDLEY_IS_CONSTEXPR_
26907#undef JSON_HEDLEY_LIKELY
26908#undef JSON_HEDLEY_MALLOC
26909#undef JSON_HEDLEY_MCST_LCC_VERSION
26910#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
26911#undef JSON_HEDLEY_MESSAGE
26912#undef JSON_HEDLEY_MSVC_VERSION
26913#undef JSON_HEDLEY_MSVC_VERSION_CHECK
26914#undef JSON_HEDLEY_NEVER_INLINE
26915#undef JSON_HEDLEY_NON_NULL
26916#undef JSON_HEDLEY_NO_ESCAPE
26917#undef JSON_HEDLEY_NO_RETURN
26918#undef JSON_HEDLEY_NO_THROW
26919#undef JSON_HEDLEY_NULL
26920#undef JSON_HEDLEY_PELLES_VERSION
26921#undef JSON_HEDLEY_PELLES_VERSION_CHECK
26922#undef JSON_HEDLEY_PGI_VERSION
26923#undef JSON_HEDLEY_PGI_VERSION_CHECK
26924#undef JSON_HEDLEY_PREDICT
26925#undef JSON_HEDLEY_PRINTF_FORMAT
26926#undef JSON_HEDLEY_PRIVATE
26927#undef JSON_HEDLEY_PUBLIC
26928#undef JSON_HEDLEY_PURE
26929#undef JSON_HEDLEY_REINTERPRET_CAST
26930#undef JSON_HEDLEY_REQUIRE
26931#undef JSON_HEDLEY_REQUIRE_CONSTEXPR
26932#undef JSON_HEDLEY_REQUIRE_MSG
26933#undef JSON_HEDLEY_RESTRICT
26934#undef JSON_HEDLEY_RETURNS_NON_NULL
26935#undef JSON_HEDLEY_SENTINEL
26936#undef JSON_HEDLEY_STATIC_ASSERT
26937#undef JSON_HEDLEY_STATIC_CAST
26938#undef JSON_HEDLEY_STRINGIFY
26939#undef JSON_HEDLEY_STRINGIFY_EX
26940#undef JSON_HEDLEY_SUNPRO_VERSION
26941#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
26942#undef JSON_HEDLEY_TINYC_VERSION
26943#undef JSON_HEDLEY_TINYC_VERSION_CHECK
26944#undef JSON_HEDLEY_TI_ARMCL_VERSION
26945#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
26946#undef JSON_HEDLEY_TI_CL2000_VERSION
26947#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
26948#undef JSON_HEDLEY_TI_CL430_VERSION
26949#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
26950#undef JSON_HEDLEY_TI_CL6X_VERSION
26951#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
26952#undef JSON_HEDLEY_TI_CL7X_VERSION
26953#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
26954#undef JSON_HEDLEY_TI_CLPRU_VERSION
26955#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
26956#undef JSON_HEDLEY_TI_VERSION
26957#undef JSON_HEDLEY_TI_VERSION_CHECK
26958#undef JSON_HEDLEY_UNAVAILABLE
26959#undef JSON_HEDLEY_UNLIKELY
26960#undef JSON_HEDLEY_UNPREDICTABLE
26961#undef JSON_HEDLEY_UNREACHABLE
26962#undef JSON_HEDLEY_UNREACHABLE_RETURN
26963#undef JSON_HEDLEY_VERSION
26964#undef JSON_HEDLEY_VERSION_DECODE_MAJOR
26965#undef JSON_HEDLEY_VERSION_DECODE_MINOR
26966#undef JSON_HEDLEY_VERSION_DECODE_REVISION
26967#undef JSON_HEDLEY_VERSION_ENCODE
26968#undef JSON_HEDLEY_WARNING
26969#undef JSON_HEDLEY_WARN_UNUSED_RESULT
26970#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
26971#undef JSON_HEDLEY_FALL_THROUGH
26972
26973
26974
26975#endif // INCLUDE_NLOHMANN_JSON_HPP_
void insert(const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:23651
array_t * get_impl_ptr(array_t *) noexcept
get a pointer to the value (array)
Definition: json.hpp:20565
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.hpp:19123
bool contains(KeyT &&key) const
check the existence of an element in a JSON object
Definition: json.hpp:22307
iteration_proxy< iterator > items() noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:22767
const_reverse_iterator crbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:22592
constexpr const number_unsigned_t * get_impl_ptr(const number_unsigned_t *) const noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:20619
number_unsigned_t number_unsigned
number (unsigned integer)
Definition: json.hpp:18667
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:25945
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:25917
friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
comparison: equal
Definition: json.hpp:24148
ValueType value(const typename object_t::key_type &key, const ValueType &default_value) const
access specified object element with default value
Definition: json.hpp:21682
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.hpp:20388
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.hpp:18390
friend bool operator==(const_reference lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:24060
NLOHMANN_BASIC_JSON_TPL basic_json_t
workaround type for MSVC
Definition: json.hpp:17881
static bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
generate SAX events
Definition: json.hpp:24760
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.hpp:21052
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition: json.hpp:24605
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.hpp:23342
const_iterator find(KeyT &&key) const
find an element in a JSON object
Definition: json.hpp:22240
basic_json(const value_t v)
create an empty value with a given type
Definition: json.hpp:19164
object_t * get_impl_ptr(object_t *) noexcept
get a pointer to the value (object)
Definition: json.hpp:20553
size_type max_size() const noexcept
returns the maximum possible number of elements
Definition: json.hpp:22990
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:26466
static std::vector< std::uint8_t > to_bson(const basic_json &j)
Serializes the given JSON object j to BSON and returns a vector containing the corresponding BSON-rep...
Definition: json.hpp:25317
value_type & reference
the type of an element reference
Definition: json.hpp:17973
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.hpp:22169
const_reverse_iterator crend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:22621
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.hpp:21338
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.hpp:21286
iterator begin() noexcept
returns an iterator to the first element
Definition: json.hpp:22377
binary_t & get_binary()
Definition: json.hpp:21128
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.hpp:19755
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.hpp:25136
friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
comparison: equal
Definition: json.hpp:24159
json_value(object_t &&value)
constructor for rvalue objects
Definition: json.hpp:18774
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.hpp:25041
basic_json & operator=(basic_json other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
copy assignment
Definition: json.hpp:20021
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.hpp:19618
json_value(number_float_t v) noexcept
constructor for numbers (floating-point)
Definition: json.hpp:18680
const_reverse_iterator rend() const noexcept
returns a const reverse iterator to one before the first
Definition: json.hpp:22563
void assert_invariant(bool check_parents=true) const noexcept
checks the class invariants
Definition: json.hpp:18935
json_value(string_t &&value)
constructor for rvalue strings
Definition: json.hpp:18762
const_iterator cend() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:22488
json_value(number_integer_t v) noexcept
constructor for numbers (integer)
Definition: json.hpp:18676
number_unsigned_t * get_impl_ptr(number_unsigned_t *) noexcept
get a pointer to the value (unsigned number)
Definition: json.hpp:20613
reference back()
access the last element
Definition: json.hpp:21853
boolean_t * get_impl_ptr(boolean_t *) noexcept
get a pointer to the value (boolean)
Definition: json.hpp:20589
const binary_t & get_binary() const
Definition: json.hpp:21139
constexpr const boolean_t * get_impl_ptr(const boolean_t *) const noexcept
get a pointer to the value (boolean)
Definition: json.hpp:20595
static bool accept(InputType &&i, const bool ignore_comments=false)
check if the input is valid JSON
Definition: json.hpp:24697
StringType string_t
a type for a string
Definition: json.hpp:18292
size_type size() const noexcept
returns the number of elements
Definition: json.hpp:22912
void push_back(const basic_json &val)
add an object to an array
Definition: json.hpp:23185
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.hpp:18037
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.hpp:21755
void update(const_reference j)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:23693
std::size_t size_type
a type to represent container sizes
Definition: json.hpp:17980
ValueType & get_to(ValueType &v) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), v)))
get a value (explicit)
Definition: json.hpp:20992
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.hpp:17978
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init)
explicitly create a binary array (without subtype)
Definition: json.hpp:19515
reference operator[](const typename object_t::key_type &key)
access specified object element
Definition: json.hpp:21475
json_value(number_unsigned_t v) noexcept
constructor for numbers (unsigned)
Definition: json.hpp:18678
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.hpp:23175
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.hpp:19298
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.hpp:17988
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: json.hpp:25841
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.hpp:17986
constexpr const binary_t * get_impl_ptr(const binary_t *) const noexcept
get a pointer to the value (binary)
Definition: json.hpp:20643
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(InputType &&i, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:25450
BooleanType boolean_t
a type for a boolean
Definition: json.hpp:18318
void push_back(initializer_list_t init)
add an object to an object
Definition: json.hpp:23293
boolean_t get_impl(boolean_t *) const
get a boolean (explicit)
Definition: json.hpp:20542
string_t dump(const int indent=-1, const char indent_char=' ', const bool ensure_ascii=false, const error_handler_t error_handler=error_handler_t::strict) const
serialization
Definition: json.hpp:20117
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21920
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: json.hpp:25332
friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
comparison: not equal
Definition: json.hpp:24193
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
Create a JSON value from an input in BSON format.
Definition: json.hpp:25825
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.hpp:20229
friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:24378
const_iterator begin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:22387
friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
comparison: less than
Definition: json.hpp:24321
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.hpp:21186
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:19572
reference front()
access the first element
Definition: json.hpp:21809
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.hpp:20202
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.hpp:20360
detail::cbor_tag_handler_t cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:17928
void swap(object_t &other)
exchanges the values
Definition: json.hpp:23898
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.hpp:20410
const_reference front() const
access the first element
Definition: json.hpp:21817
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.hpp:20171
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.hpp:18529
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.hpp:17995
friend std::ostream & operator<<(std::ostream &o, const basic_json &j)
serialize to stream
Definition: json.hpp:24515
friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
comparison: less than or equal
Definition: json.hpp:24356
bool empty() const noexcept
checks whether the container is empty.
Definition: json.hpp:22832
json_value(value_t t)
constructor for empty values of a given type
Definition: json.hpp:18682
basic_json(const basic_json &other)
copy constructor
Definition: json.hpp:19893
~basic_json() noexcept
destructor
Definition: json.hpp:20053
static std::vector< std::uint8_t > to_ubjson(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.hpp:25239
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.hpp:19985
friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:24424
BasicJsonType get_impl(detail::priority_tag< 2 >) const
get special-case overload
Definition: json.hpp:20836
friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:24182
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts elements
Definition: json.hpp:23509
friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:24332
json_value m_value
the value of the current element
Definition: json.hpp:24928
boolean_t boolean
boolean
Definition: json.hpp:18663
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.hpp:23981
friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:24448
void swap(array_t &other)
exchanges the values
Definition: json.hpp:23864
ValueType get_impl(detail::priority_tag< 0 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >(), std::declval< ValueType & >())))
get a value (explicit)
Definition: json.hpp:20769
reverse_iterator rend() noexcept
returns an iterator to the reverse-end
Definition: json.hpp:22555
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(const typename binary_t::container_type &init, typename binary_t::subtype_type subtype)
explicitly create a binary array (with subtype)
Definition: json.hpp:19552
static iteration_proxy< iterator > iterator_wrapper(reference ref) noexcept
wrapper to access iterator member functions in range-based for
Definition: json.hpp:22685
json_value(const string_t &value)
constructor for strings
Definition: json.hpp:18756
json_value(const binary_t &value)
constructor for binary arrays (internal type)
Definition: json.hpp:18804
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.hpp:21065
json_value(const array_t &value)
constructor for arrays
Definition: json.hpp:18780
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts elements
Definition: json.hpp:23557
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:20948
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.hpp:26031
const_iterator end() const noexcept
returns a const iterator to one past the last element
Definition: json.hpp:22458
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.hpp:26651
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20706
iteration_proxy< const_iterator > items() const noexcept
helper to access iterator member functions in range-based for
Definition: json.hpp:22775
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements
Definition: json.hpp:23610
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.hpp:18239
friend bool operator>(const_reference lhs, const_reference rhs) noexcept
comparison: greater than
Definition: json.hpp:24402
constexpr const number_integer_t * get_impl_ptr(const number_integer_t *) const noexcept
get a pointer to the value (integer number)
Definition: json.hpp:20607
constexpr const string_t * get_impl_ptr(const string_t *) const noexcept
get a pointer to the value (string)
Definition: json.hpp:20583
json_value(const object_t &value)
constructor for objects
Definition: json.hpp:18768
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.hpp:22036
json_value(typename binary_t::container_type &&value)
constructor for rvalue binary arrays
Definition: json.hpp:18798
json_value(boolean_t v) noexcept
constructor for booleans
Definition: json.hpp:18674
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.hpp:20273
iterator end() noexcept
returns an iterator to one past the last element
Definition: json.hpp:22448
void swap(reference other) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:23802
void clear() noexcept
clears the contents
Definition: json.hpp:23069
friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:24470
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:25610
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.hpp:20476
static JSON_HEDLEY_RETURNS_NON_NULL T * create(Args &&... args)
helper for exception-safe object creation
Definition: json.hpp:18608
binary_t * binary
binary (stored with pointer to save storage)
Definition: json.hpp:18661
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.hpp:19662
iterator insert(const_iterator pos, basic_json &&val)
inserts element
Definition: json.hpp:23480
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:25727
reference operator[](size_type idx)
access specified array element
Definition: json.hpp:21385
friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than
Definition: json.hpp:24413
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: json.hpp:25340
void update(const_iterator first, const_iterator last)
updates a JSON object from another object, overwriting existing keys
Definition: json.hpp:23748
reference at(const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.hpp:25988
void swap(binary_t &other)
exchanges the values
Definition: json.hpp:23966
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.hpp:17991
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.hpp:17997
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_ubjson(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in UBJSON format
Definition: json.hpp:25711
::nlohmann::json_pointer< basic_json > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.hpp:17922
friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
comparison: not equal
Definition: json.hpp:24204
const_reverse_iterator rbegin() const noexcept
returns a const reverse iterator to the last element
Definition: json.hpp:22526
void swap(string_t &other)
exchanges the values
Definition: json.hpp:23932
const_reference back() const
access the last element
Definition: json.hpp:21863
friend bool operator<(const_reference lhs, const_reference rhs) noexcept
comparison: less than
Definition: json.hpp:24235
ValueType get_impl(detail::priority_tag< 1 >) const noexcept(noexcept(JSONSerializer< ValueType >::from_json(std::declval< const basic_json_t & >())))
get a value (explicit); special case
Definition: json.hpp:20811
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array (without subtype)
Definition: json.hpp:19562
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.hpp:20454
number_integer_t * get_impl_ptr(number_integer_t *) noexcept
get a pointer to the value (integer number)
Definition: json.hpp:20601
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.hpp:20432
iterator insert_iterator(const_iterator pos, Args &&... args)
Helper for insertion of an iterator.
Definition: json.hpp:23422
basic_json flatten() const
return flattened JSON value
Definition: json.hpp:26058
constexpr const number_float_t * get_impl_ptr(const number_float_t *) const noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:20631
constexpr const array_t * get_impl_ptr(const array_t *) const noexcept
get a pointer to the value (array)
Definition: json.hpp:20571
friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
comparison: greater than or equal
Definition: json.hpp:24459
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.hpp:24883
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:23148
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_cbor(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
create a JSON value from an input in CBOR format
Definition: json.hpp:25467
size_type count(KeyT &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.hpp:22274
json_value(const typename binary_t::container_type &value)
constructor for binary arrays
Definition: json.hpp:18792
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.hpp:20303
number_float_t number_float
number (floating-point)
Definition: json.hpp:18669
string_t * get_impl_ptr(string_t *) noexcept
get a pointer to the value (string)
Definition: json.hpp:20577
friend std::ostream & operator>>(const basic_json &j, std::ostream &o)
serialize to stream
Definition: json.hpp:24537
string_t * string
string (stored with pointer to save storage)
Definition: json.hpp:18659
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.hpp:23312
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.hpp:20332
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.hpp:17930
number_float_t * get_impl_ptr(number_float_t *) noexcept
get a pointer to the value (floating-point number)
Definition: json.hpp:20625
json_value(binary_t &&value)
constructor for rvalue binary arrays (internal type)
Definition: json.hpp:18810
const_reference operator[](const typename object_t::key_type &key) const
read-only access specified object element
Definition: json.hpp:21524
iterator find(KeyT &&key)
find an element in a JSON object
Definition: json.hpp:22223
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.hpp:19188
const_reference operator[](size_type idx) const
access specified array element
Definition: json.hpp:21437
array_t * array
array (stored with pointer to save storage)
Definition: json.hpp:18657
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.hpp:17983
basic_json get_impl(detail::priority_tag< 3 >) const
get special-case overload
Definition: json.hpp:20859
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.hpp:18600
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:23237
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json parse(IteratorType first, IteratorType last, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a pair of character iterators
Definition: json.hpp:24643
number_integer_t number_integer
number (integer)
Definition: json.hpp:18665
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.hpp:22338
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_msgpack(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in MessagePack format
Definition: json.hpp:25594
basic_json patch(const basic_json &json_patch) const
applies a JSON patch
Definition: json.hpp:26156
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: json.hpp:21705
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value
Definition: json.hpp:19260
basic_json unflatten() const
unflatten a previously flattened JSON value
Definition: json.hpp:26095
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.hpp:18461
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.hpp:23262
const_iterator cbegin() const noexcept
returns a const iterator to the first element
Definition: json.hpp:22417
friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
comparison: less than or equal
Definition: json.hpp:24367
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.hpp:24839
json_value(array_t &&value)
constructor for rvalue arrays
Definition: json.hpp:18786
basic_json(initializer_list_t init, bool type_deduction=true, value_t manual_type=value_t::array)
create a container (array or object) from an initializer list
Definition: json.hpp:19433
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.hpp:21234
iterator insert(const_iterator pos, const basic_json &val)
inserts element
Definition: json.hpp:23458
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.hpp:20503
constexpr auto get_impl(detail::priority_tag< 4 >) const noexcept -> decltype(std::declval< const basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.hpp:20872
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.hpp:20251
friend void swap(reference left, reference right) noexcept(std::is_nothrow_move_constructible< value_t >::value &&std::is_nothrow_move_assignable< value_t >::value &&std::is_nothrow_move_constructible< json_value >::value &&std::is_nothrow_move_assignable< json_value >::value)
exchanges the values
Definition: json.hpp:23834
binary_t * get_impl_ptr(binary_t *) noexcept
get a pointer to the value (binary)
Definition: json.hpp:20637
ObjectType< StringType, basic_json, object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > > > object_t
a type for an object
Definition: json.hpp:18193
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
Definition: json.hpp:20907
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.hpp:23392
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.hpp:23211
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.hpp:22134
static ReferenceType get_ref_impl(ThisType &obj)
helper function to implement get_ref()
Definition: json.hpp:20660
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.hpp:19689
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.hpp:18005
constexpr const object_t * get_impl_ptr(const object_t *) const noexcept
get a pointer to the value (object)
Definition: json.hpp:20559
constexpr auto get_ptr() const noexcept -> decltype(std::declval< const basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.hpp:20719
reverse_iterator rbegin() noexcept
returns an iterator to the reverse-beginning
Definition: json.hpp:22518
a class to store JSON values
Definition: json.hpp:17860
json_value()=default
default constructor (for null values)
BinaryType container_type
the type of the underlying container
Definition: json.hpp:5055
void clear_subtype() noexcept
clears the binary subtype
Definition: json.hpp:5185
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.hpp:5161
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.hpp:5112
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.hpp:5140
std::uint64_t subtype_type
the type of the subtype
Definition: json.hpp:5057
an internal type for a backed binary type
Definition: json.hpp:5052
bool get_msgpack_array(const std::size_t len)
Definition: json.hpp:10166
bool get_bson_string(const NumberType len, string_t &result)
Parses a zero-terminated string of length len from the BSON input.
Definition: json.hpp:8601
bool parse_bson_element_internal(const char_int_type element_type, const std::size_t element_type_parse_position)
Read a BSON document element of the given element_type.
Definition: json.hpp:8647
bool parse_bson_array()
Reads an array from the BSON input and passes it to the SAX-parser.
Definition: json.hpp:8764
char_int_type get_ignore_noop()
Definition: json.hpp:10778
binary_reader(InputAdapterType &&adapter) noexcept
create a binary reader
Definition: json.hpp:8458
bool get_bson_cstr(string_t &result)
Parses a C-style string from the BSON input.
Definition: json.hpp:8567
bool get_cbor_array(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:9493
bool get_msgpack_binary(binary_t &result)
reads a MessagePack byte array
Definition: json.hpp:10055
bool get_cbor_object(const std::size_t len, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:9532
bool get_ubjson_string(string_t &result, const bool get_char=true)
reads a UBJSON string
Definition: json.hpp:10247
bool parse_bson_element_list(const bool is_array)
Read a BSON element list (as specified in the BSON-spec)
Definition: json.hpp:8725
bool parse_cbor_internal(const bool get_char, const cbor_tag_handler_t tag_handler)
Definition: json.hpp:8794
bool get_string(const input_format_t format, const NumberType len, string_t &result)
create a string by reading characters from the input
Definition: json.hpp:10849
bool get_cbor_string(string_t &result)
reads a CBOR string
Definition: json.hpp:9298
InputAdapterType ia
input adapter
Definition: json.hpp:10975
bool get_binary(const input_format_t format, const NumberType len, binary_t &result)
create a byte array by reading bytes from the input
Definition: json.hpp:10886
bool parse_ubjson_internal(const bool get_char=true)
Definition: json.hpp:10228
bool unexpect_eof(const input_format_t format, const char *context) const
Definition: json.hpp:10914
bool get_ubjson_size_type(std::pair< std::size_t, char_int_type > &result)
determine the type and size for a container
Definition: json.hpp:10388
std::string get_token_string() const
Definition: json.hpp:10928
bool get_ubjson_value(const char_int_type prefix)
Definition: json.hpp:10431
bool get_msgpack_object(const std::size_t len)
Definition: json.hpp:10188
bool get_bson_binary(const NumberType len, binary_t &result)
Parses a byte array input of length len from the BSON input.
Definition: json.hpp:8622
std::string exception_message(const input_format_t format, const std::string &detail, const std::string &context) const
Definition: json.hpp:10941
std::size_t chars_read
the number of characters read
Definition: json.hpp:10981
char_int_type current
the current character
Definition: json.hpp:10978
bool sax_parse(const input_format_t format, json_sax_t *sax_, const bool strict=true, const cbor_tag_handler_t tag_handler=cbor_tag_handler_t::error)
Definition: json.hpp:8479
json_sax_t * sax
the SAX parser
Definition: json.hpp:10987
bool get_ubjson_size_value(std::size_t &result)
Definition: json.hpp:10301
bool parse_bson_internal()
Reads in a BSON-object and passes it to the SAX-parser.
Definition: json.hpp:8542
bool get_cbor_binary(binary_t &result)
reads a CBOR byte array
Definition: json.hpp:9396
char_int_type get()
get next character from the input
Definition: json.hpp:10769
const bool is_little_endian
whether we can assume little endianess
Definition: json.hpp:10984
bool get_msgpack_string(string_t &result)
reads a MessagePack string
Definition: json.hpp:9973
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.hpp:8442
void write_bson_array(const string_t &name, const typename BasicJsonType::array_t &value)
Writes a BSON element with key name and array value.
Definition: json.hpp:14958
const bool is_little_endian
whether we can assume little endianess
Definition: json.hpp:15516
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true)
Definition: json.hpp:14573
static std::size_t calc_bson_entry_header_size(const string_t &name, const BasicJsonType &j)
Definition: json.hpp:14787
void write_bson_entry_header(const string_t &name, const std::uint8_t element_type)
Writes the given element_type and name to the output adapter.
Definition: json.hpp:14803
static std::size_t calc_bson_element_size(const string_t &name, const BasicJsonType &j)
Calculates the size necessary to serialize the JSON value j with its name.
Definition: json.hpp:14989
void write_bson_double(const string_t &name, const double value)
Writes a BSON element with key name and double value value.
Definition: json.hpp:14825
void write_bson_object(const typename BasicJsonType::object_t &value)
Definition: json.hpp:15099
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.hpp:13808
CharType ubjson_prefix(const BasicJsonType &j) const noexcept
determine the type prefix of container values
Definition: json.hpp:15310
void write_bson_integer(const string_t &name, const std::int64_t value)
Writes a BSON element with key name and integer value.
Definition: json.hpp:14874
void write_bson_string(const string_t &name, const string_t &value)
Writes a BSON element with key name and string value value.
Definition: json.hpp:14843
void write_bson_object_entry(const string_t &name, const typename BasicJsonType::object_t &value)
Writes a BSON element with key name and object value.
Definition: json.hpp:14927
output_adapter_t< CharType > oa
the output
Definition: json.hpp:15519
void write_bson_element(const string_t &name, const BasicJsonType &j)
Serializes the JSON value j to BSON and associates it with the key name.
Definition: json.hpp:15038
void write_bson_binary(const string_t &name, const binary_t &value)
Writes a BSON element with key name and binary value value.
Definition: json.hpp:14976
void write_bson_null(const string_t &name)
Writes a BSON element with key name and null value.
Definition: json.hpp:14856
static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t &value)
Definition: json.hpp:14950
void write_bson(const BasicJsonType &j)
Definition: json.hpp:13817
void write_cbor(const BasicJsonType &j)
Definition: json.hpp:13846
static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
Definition: json.hpp:14893
void write_bson_unsigned(const string_t &name, const BasicJsonType &j)
Writes a BSON element with key name and unsigned value.
Definition: json.hpp:14903
static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t &value)
Calculates the size of the BSON serialization of the given JSON-object j.
Definition: json.hpp:15085
void write_bson_boolean(const string_t &name, const bool value)
Writes a BSON element with key name and boolean value value.
Definition: json.hpp:14815
void write_msgpack(const BasicJsonType &j)
Definition: json.hpp:14215
static std::size_t calc_bson_string_size(const string_t &value)
Definition: json.hpp:14835
static std::size_t calc_bson_integer_size(const std::int64_t value)
Definition: json.hpp:14864
static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t &value)
Definition: json.hpp:14937
serialization to CBOR and MessagePack values
Definition: json.hpp:13797
const int id
the id of the exception
Definition: json.hpp:2659
std::runtime_error m
an exception object as storage for error messages
Definition: json.hpp:2739
const char * what() const noexcept override
returns the explanatory string
Definition: json.hpp:2653
general exception of the basic_json class
Definition: json.hpp:2650
std::FILE * m_file
the file pointer to read from
Definition: json.hpp:5417
std::istream * is
the associated input stream
Definition: json.hpp:5479
exception indicating errors with iterators
Definition: json.hpp:2876
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.hpp:12177
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:12307
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition: json.hpp:12168
iter_impl const operator--(int)
post-decrement (it–)
Definition: json.hpp:12080
void set_end() noexcept
set the iterator past the last value
Definition: json.hpp:11904
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.hpp:11740
iter_impl & operator--()
pre-decrement (–it)
Definition: json.hpp:12091
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.hpp:12318
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.hpp:11822
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_reference, typename BasicJsonType::reference >::type reference
defines a reference to the type iterated over (value_type)
Definition: json.hpp:11749
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.hpp:11943
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.hpp:12230
typename std::conditional< std::is_const< BasicJsonType >::value, typename BasicJsonType::const_pointer, typename BasicJsonType::pointer >::type pointer
defines a pointer to the type iterated over (value_type)
Definition: json.hpp:11744
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.hpp:11848
pointer operator->() const
dereference the iterator
Definition: json.hpp:11987
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.hpp:11812
iter_impl const operator++(int)
post-increment (it++)
Definition: json.hpp:12029
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.hpp:11838
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.hpp:12410
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.hpp:12285
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.hpp:12296
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.hpp:12385
bool operator==(const IterImpl &other) const
comparison: equal
Definition: json.hpp:12132
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.hpp:12221
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.hpp:11738
reference value() const
return the value of an iterator
Definition: json.hpp:12401
friend other_iter_impl
allow basic_json to access private members
Definition: json.hpp:11717
iter_impl & operator++()
pre-increment (++it)
Definition: json.hpp:12040
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:12347
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.hpp:12212
std::bidirectional_iterator_tag iterator_category
The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
Definition: json.hpp:11735
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.hpp:12239
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.hpp:12276
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.hpp:11713
IteratorType anchor
the iterator
Definition: json.hpp:4401
const string_type empty_str
an empty string (to return a reference for primitive values)
Definition: json.hpp:4409
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.hpp:4437
std::size_t array_index_last
last stringified array index
Definition: json.hpp:4405
string_type array_index_str
a string representation of the array index
Definition: json.hpp:4407
IteratorType::reference value() const
return value of the iterator
Definition: json.hpp:4480
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.hpp:4423
std::size_t array_index
an index for arrays (used to create key names)
Definition: json.hpp:4403
iteration_proxy_value & operator*()
dereference operator (needed for range-based for)
Definition: json.hpp:4417
const string_type & key() const
return key of the iterator
Definition: json.hpp:4443
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.hpp:4431
iteration_proxy_value< IteratorType > begin() noexcept
return iterator begin (needed for range-based for)
Definition: json.hpp:4499
iteration_proxy_value< IteratorType > end() noexcept
return iterator end (needed for range-based for)
Definition: json.hpp:4505
IteratorType::reference container
the container to iterate
Definition: json.hpp:4491
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.hpp:4495
proxy class for the items() function
Definition: json.hpp:4488
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.hpp:12461
json_reverse_iterator const operator--(int)
post-decrement (it–)
Definition: json.hpp:12480
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.hpp:12458
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.hpp:12504
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.hpp:12492
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.hpp:12456
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.hpp:12465
reference operator[](difference_type n) const
access to successor
Definition: json.hpp:12516
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.hpp:12510
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.hpp:12498
json_reverse_iterator const operator++(int)
post-increment (it++)
Definition: json.hpp:12468
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.hpp:12522
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.hpp:12486
reference value() const
return the value of an iterator
Definition: json.hpp:12529
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.hpp:12474
a template for a reverse iterator class
Definition: json.hpp:12452
std::pair< bool, BasicJsonType * > handle_value(Value &&v, const bool skip_callback=false)
Definition: json.hpp:6409
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:6472
JSON_HEDLEY_RETURNS_NON_NULL BasicJsonType * handle_value(Value &&v)
Definition: json.hpp:6149
BasicJsonType & root
the parsed JSON value
Definition: json.hpp:6172
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.hpp:6022
SAX implementation to create a JSON value from SAX events.
Definition: json.hpp:6009
JSON_HEDLEY_RETURNS_NON_NULL static JSON_HEDLEY_CONST const char * token_type_name(const token_type t) noexcept
return name of values of type token_type (only used for errors)
Definition: json.hpp:6627
token_type
token types for the parser
Definition: json.hpp:6604
@ 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)
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.hpp:8035
const bool ignore_comments
whether comments should be ignored (true) or signaled as errors (false)
Definition: json.hpp:8216
void add(char_int_type c)
add a character to token_buffer
Definition: json.hpp:8006
void reset() noexcept
reset token_buffer; current character is beginning of token
Definition: json.hpp:7924
bool next_unget
whether the next get() call should just return current
Definition: json.hpp:8222
char_int_type current
the current character
Definition: json.hpp:8219
static JSON_HEDLEY_PURE char get_decimal_point() noexcept
return the locale-dependent decimal point
Definition: json.hpp:6723
InputAdapterType ia
input adapter
Definition: json.hpp:8213
const char_int_type decimal_point_char
the decimal point
Definition: json.hpp:8242
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.hpp:8093
const char * error_message
a description of occurred lexer errors
Definition: json.hpp:8234
position_t position
the start position of the current token
Definition: json.hpp:8225
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.hpp:8045
std::vector< char_type > token_string
raw input token string (for error messages)
Definition: json.hpp:8228
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.hpp:8017
token_type scan_number()
scan a number literal
Definition: json.hpp:7566
void unget()
unget current character (read it again on next get)
Definition: json.hpp:7979
token_type scan_string()
scan a string literal
Definition: json.hpp:6839
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.hpp:8023
string_t token_buffer
buffer for variable-length tokens (numbers, strings)
Definition: json.hpp:8231
token_type scan_literal(const char_type *literal_text, const std::size_t length, token_type return_type)
Definition: json.hpp:7902
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.hpp:8029
int get_codepoint()
get codepoint from 4 hex characters following \u
Definition: json.hpp:6749
std::string get_token_string() const
return the last read token (for errors only).
Definition: json.hpp:8053
bool next_byte_in_range(std::initializer_list< char_int_type > ranges)
check if the next byte(s) are inside a given range
Definition: json.hpp:6800
bool scan_comment()
scan a comment
Definition: json.hpp:7441
JSON_HEDLEY_RETURNS_NON_NULL constexpr const char * get_error_message() const noexcept
return syntax error message
Definition: json.hpp:8080
lexical analysis
Definition: json.hpp:6692
exception indicating other library errors
Definition: json.hpp:3018
exception indicating access out of the defined range
Definition: json.hpp:2979
output adapter for output streams
Definition: json.hpp:13710
output adapter for basic_string
Definition: json.hpp:13735
output adapter for byte vectors
Definition: json.hpp:13685
const std::size_t byte
byte index of the parse error
Definition: json.hpp:2825
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, const BasicJsonType &context)
create a parse error exception
Definition: json.hpp:2800
exception indicating a parse error
Definition: json.hpp:2788
lexer_t m_lexer
the lexer
Definition: json.hpp:11506
token_type get_token()
get next token from lexer
Definition: json.hpp:11465
token_type last_token
the type of the last read token
Definition: json.hpp:11504
parser(InputAdapterType &&adapter, const parser_callback_t< BasicJsonType > cb=nullptr, const bool allow_exceptions_=true, const bool skip_comments=false)
a parser reading from an input adapter
Definition: json.hpp:11066
bool accept(const bool strict=true)
public accept interface
Definition: json.hpp:11149
const parser_callback_t< BasicJsonType > callback
callback function
Definition: json.hpp:11502
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.hpp:11088
const bool allow_exceptions
whether to throw exceptions in case of errors
Definition: json.hpp:11508
syntax analysis
Definition: json.hpp:11056
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.hpp:11575
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.hpp:11569
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.hpp:11557
void set_end() noexcept
set iterator to a defined past the end
Definition: json.hpp:11563
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.hpp:17551
const std::lconv * loc
the locale
Definition: json.hpp:17536
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition: json.hpp:17533
const char decimal_point
the locale's decimal point character
Definition: json.hpp:17540
const char thousands_sep
the locale's thousand separator character
Definition: json.hpp:17538
void dump(const BasicJsonType &val, const bool pretty_print, const bool ensure_ascii, const unsigned int indent_step, const unsigned int current_indent=0)
internal implementation of the serialization function
Definition: json.hpp:16683
const char indent_char
the indentation character
Definition: json.hpp:17546
std::array< char, 512 > string_buffer
string buffer
Definition: json.hpp:17543
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.hpp:16643
string_t indent_string
the indentation string
Definition: json.hpp:17548
exception indicating executing a member function with a wrong type
Definition: json.hpp:2931
std::size_t utf8_bytes_index
index to the utf8_codes array for the next valid byte
Definition: json.hpp:5694
std::size_t utf8_bytes_filled
number of valid bytes in the utf8_codes array
Definition: json.hpp:5696
std::array< std::char_traits< char >::int_type, 4 > utf8_bytes
a buffer for UTF-8 bytes
Definition: json.hpp:5691
std::vector< std::string > reference_tokens
the reference tokens
Definition: json.hpp:13542
json_pointer & operator/=(std::string token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.hpp:12665
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.hpp:12641
std::string to_string() const
return a string representation of the JSON pointer
Definition: json.hpp:12609
const BasicJsonType & get_unchecked(const BasicJsonType *ptr) const
return a const reference to the pointed to value
Definition: json.hpp:13149
friend bool operator==(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for equality
Definition: json.hpp:13518
void pop_back()
remove last reference token
Definition: json.hpp:12791
const std::string & back() const
return last reference token
Definition: json.hpp:12815
const BasicJsonType & get_checked(const BasicJsonType *ptr) const
Definition: json.hpp:13197
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.hpp:12862
friend bool operator!=(json_pointer const &lhs, json_pointer const &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.hpp:13535
void push_back(const std::string &token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:12837
json_pointer(const std::string &s="")
create JSON pointer
Definition: json.hpp:12591
friend json_pointer operator/(const json_pointer &lhs, const json_pointer &rhs)
create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer
Definition: json.hpp:12707
bool contains(const BasicJsonType *ptr) const
Definition: json.hpp:13245
static BasicJsonType unflatten(const BasicJsonType &value)
Definition: json.hpp:13480
friend json_pointer operator/(const json_pointer &ptr, std::string token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.hpp:12728
BasicJsonType & get_and_create(BasicJsonType &j) const
create and return a reference to the pointed to value
Definition: json.hpp:12943
static void flatten(const std::string &reference_string, const BasicJsonType &value, BasicJsonType &result)
Definition: json.hpp:13405
void push_back(std::string &&token)
append an unescaped token at the end of the reference pointer
Definition: json.hpp:12843
BasicJsonType & get_checked(BasicJsonType *ptr) const
Definition: json.hpp:13092
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.hpp:12687
static BasicJsonType::size_type array_index(const std::string &s)
Definition: json.hpp:12878
BasicJsonType & get_unchecked(BasicJsonType *ptr) const
return a reference to the pointed to value
Definition: json.hpp:13024
friend json_pointer operator/(const json_pointer &ptr, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.hpp:12748
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.hpp:12766
static std::vector< std::string > split(const std::string &reference_string)
split the string input to reference tokens
Definition: json.hpp:13337
JSON Pointer.
Definition: json.hpp:12564
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.hpp:16321
JSON_HEDLEY_RETURNS_NON_NULL char * format_buffer(char *buf, int len, int decimal_exponent, int min_exp, int max_exp)
prettify v = buf * 10^decimal_exponent
Definition: json.hpp:16467
boundaries compute_boundaries(FloatType value)
Definition: json.hpp:15709
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.hpp:15994
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.hpp:16411
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.hpp:16097
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.hpp:15837
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.hpp:147
static void unescape(std::string &s)
string unescaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2572
value_t
the JSON type enumeration
Definition: json.hpp: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)
JSON_HEDLEY_RETURNS_NON_NULL char * to_chars(char *first, const char *last, FloatType value)
generates a decimal representation of the floating-point number value in [first, last).
Definition: json.hpp:16546
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.hpp:8414
@ store
store tags as binary type
@ error
throw a parse_error exception in case of a tag
@ value
the parser finished reading a JSON value
@ key
the parser read a key of a value in an object
@ array_end
the parser read ] and finished processing a JSON array
@ array_start
the parser read [ and started to process a JSON array
@ object_start
the parser read { and started to process a JSON object
@ object_end
the parser read } and finished processing a JSON object
error_handler_t
how to treat decoding errors
Definition: json.hpp:16620
@ 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
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:5240
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.hpp:13680
std::string escape(std::string s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.hpp:2558
input_format_t
the supported input formats
Definition: json.hpp:5382
void replace_substring(std::string &s, const std::string &f, const std::string &t)
replace all occurrences of a substring by another string
Definition: json.hpp:2539
static bool little_endianess(int num=1) noexcept
determine system byte order
Definition: json.hpp:8427
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.hpp:11661
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.hpp:11659
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.hpp:11657
basic_json<> json
default JSON class
Definition: json.hpp:3411
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:26693
namespace for Niels Lohmann
Definition: json.hpp:89
STL namespace.
Definition: Utils.h:15
static auto from_json(BasicJsonType &&j, TargetType &val) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), val))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), val), void())
convert a JSON value to any value type
Definition: json.hpp:4981
static auto from_json(BasicJsonType &&j) noexcept(noexcept(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))) -> decltype(::nlohmann::from_json(std::forward< BasicJsonType >(j), detail::identity_tag< TargetType > {}))
convert a JSON value to any value type
Definition: json.hpp:5001
static auto to_json(BasicJsonType &j, TargetType &&val) noexcept(noexcept(::nlohmann::to_json(j, std::forward< TargetType >(val)))) -> decltype(::nlohmann::to_json(j, std::forward< TargetType >(val)), void())
convert any value type to a JSON value
Definition: json.hpp:5018
default JSONSerializer template argument
Definition: json.hpp:4968
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.hpp:15669
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: json.hpp:15686
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.hpp:15614
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.hpp:15603
abstract output adapter interface
Definition: json.hpp:13666
std::size_t lines_read
the number of lines read
Definition: json.hpp:2598
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.hpp:2596
std::size_t chars_read_total
the total number of characters read
Definition: json.hpp:2594
struct to capture the start position of the current token
Definition: json.hpp:2592
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
virtual bool end_array()=0
the end of an array was read
virtual bool key(string_t &val)=0
an object key was read
virtual bool binary(binary_t &val)=0
a binary string was read
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
virtual bool boolean(bool val)=0
a boolean value was read
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
virtual bool number_float(number_float_t val, const string_t &s)=0
an floating-point number was read
virtual bool number_integer(number_integer_t val)=0
an integer number was read
SAX interface.
Definition: json.hpp:5878
ordered_map: a minimal map-like container that preserves insertion order for use within nlohmann::bas...
Definition: json.hpp:17583
std::size_t operator()(const nlohmann::json &j) const
return a hash value for a JSON object
Definition: json.hpp:26716
bool operator()(nlohmann::detail::value_t lhs, nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.hpp:26732