Instrument Neutral Distributed Interface INDI  2.0.2
json.h
Go to the documentation of this file.
1 /*
2  __ _____ _____ _____
3  __| | __| | | | JSON for Modern C++
4 | | |__ | | | | | | version 3.10.5
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6 
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2022 Niels Lohmann <http://nlohmann.me>.
10 
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17 
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20 
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29 
30 /****************************************************************************\
31  * Note on documentation: The source files contain links to the online *
32  * documentation of the public API at https://json.nlohmann.me. This URL *
33  * contains the most recent documentation and should also be applicable to *
34  * previous versions; documentation for deprecated functions is not *
35  * removed, but marked deprecated. See "Generate documentation" section in *
36  * file docs/README.md. *
37 \****************************************************************************/
38 
39 #ifndef INCLUDE_NLOHMANN_JSON_HPP_
40 #define INCLUDE_NLOHMANN_JSON_HPP_
41 
42 #ifndef JSON_SKIP_LIBRARY_VERSION_CHECK
43  #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH)
44  #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 10 || NLOHMANN_JSON_VERSION_PATCH != 5
45  #warning "Already included a different version of the library!"
46  #endif
47  #endif
48 #endif
49 
50 #define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum)
51 #define NLOHMANN_JSON_VERSION_MINOR 10 // NOLINT(modernize-macro-to-enum)
52 #define NLOHMANN_JSON_VERSION_PATCH 5 // NOLINT(modernize-macro-to-enum)
53 
54 #include <algorithm> // all_of, find, for_each
55 #include <cstddef> // nullptr_t, ptrdiff_t, size_t
56 #include <functional> // hash, less
57 #include <initializer_list> // initializer_list
58 #ifndef JSON_NO_IO
59  #include <iosfwd> // istream, ostream
60 #endif // JSON_NO_IO
61 #include <iterator> // random_access_iterator_tag
62 #include <memory> // unique_ptr
63 #include <numeric> // accumulate
64 #include <string> // string, stoi, to_string
65 #include <utility> // declval, forward, move, pair, swap
66 #include <vector> // vector
67 
68 // #include <nlohmann/adl_serializer.hpp>
69 
70 
71 #include <type_traits>
72 #include <utility>
73 
74 // #include <nlohmann/detail/conversions/from_json.hpp>
75 
76 
77 #include <algorithm> // transform
78 #include <array> // array
79 #include <forward_list> // forward_list
80 #include <iterator> // inserter, front_inserter, end
81 #include <map> // map
82 #include <string> // string
83 #include <tuple> // tuple, make_tuple
84 #include <type_traits> // is_arithmetic, is_same, is_enum, underlying_type, is_convertible
85 #include <unordered_map> // unordered_map
86 #include <utility> // pair, declval
87 #include <valarray> // valarray
88 
89 // #include <nlohmann/detail/exceptions.hpp>
90 
91 
92 #include <cstddef> // nullptr_t
93 #include <exception> // exception
94 #include <stdexcept> // runtime_error
95 #include <string> // to_string
96 #include <vector> // vector
97 
98 // #include <nlohmann/detail/value_t.hpp>
99 
100 
101 #include <array> // array
102 #include <cstddef> // size_t
103 #include <cstdint> // uint8_t
104 #include <string> // string
105 
106 // #include <nlohmann/detail/macro_scope.hpp>
107 
108 
109 #include <utility> // declval, pair
110 // #include <nlohmann/thirdparty/hedley/hedley.hpp>
111 
112 
113 /* Hedley - https://nemequ.github.io/hedley
114  * Created by Evan Nemerson <evan@nemerson.com>
115  *
116  * To the extent possible under law, the author(s) have dedicated all
117  * copyright and related and neighboring rights to this software to
118  * the public domain worldwide. This software is distributed without
119  * any warranty.
120  *
121  * For details, see <http://creativecommons.org/publicdomain/zero/1.0/>.
122  * SPDX-License-Identifier: CC0-1.0
123  */
124 
125 #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15)
126 #if defined(JSON_HEDLEY_VERSION)
127  #undef JSON_HEDLEY_VERSION
128 #endif
129 #define JSON_HEDLEY_VERSION 15
130 
131 #if defined(JSON_HEDLEY_STRINGIFY_EX)
132  #undef JSON_HEDLEY_STRINGIFY_EX
133 #endif
134 #define JSON_HEDLEY_STRINGIFY_EX(x) #x
135 
136 #if defined(JSON_HEDLEY_STRINGIFY)
137  #undef JSON_HEDLEY_STRINGIFY
138 #endif
139 #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x)
140 
141 #if defined(JSON_HEDLEY_CONCAT_EX)
142  #undef JSON_HEDLEY_CONCAT_EX
143 #endif
144 #define JSON_HEDLEY_CONCAT_EX(a,b) a##b
145 
146 #if defined(JSON_HEDLEY_CONCAT)
147  #undef JSON_HEDLEY_CONCAT
148 #endif
149 #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b)
150 
151 #if defined(JSON_HEDLEY_CONCAT3_EX)
152  #undef JSON_HEDLEY_CONCAT3_EX
153 #endif
154 #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c
155 
156 #if defined(JSON_HEDLEY_CONCAT3)
157  #undef JSON_HEDLEY_CONCAT3
158 #endif
159 #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c)
160 
161 #if defined(JSON_HEDLEY_VERSION_ENCODE)
162  #undef JSON_HEDLEY_VERSION_ENCODE
163 #endif
164 #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision))
165 
166 #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR)
167  #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
168 #endif
169 #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000)
170 
171 #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR)
172  #undef JSON_HEDLEY_VERSION_DECODE_MINOR
173 #endif
174 #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000)
175 
176 #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION)
177  #undef JSON_HEDLEY_VERSION_DECODE_REVISION
178 #endif
179 #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000)
180 
181 #if defined(JSON_HEDLEY_GNUC_VERSION)
182  #undef JSON_HEDLEY_GNUC_VERSION
183 #endif
184 #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__)
185  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
186 #elif defined(__GNUC__)
187  #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0)
188 #endif
189 
190 #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK)
191  #undef JSON_HEDLEY_GNUC_VERSION_CHECK
192 #endif
193 #if defined(JSON_HEDLEY_GNUC_VERSION)
194  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
195 #else
196  #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0)
197 #endif
198 
199 #if defined(JSON_HEDLEY_MSVC_VERSION)
200  #undef JSON_HEDLEY_MSVC_VERSION
201 #endif
202 #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL)
203  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100)
204 #elif defined(_MSC_FULL_VER) && !defined(__ICL)
205  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10)
206 #elif defined(_MSC_VER) && !defined(__ICL)
207  #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0)
208 #endif
209 
210 #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK)
211  #undef JSON_HEDLEY_MSVC_VERSION_CHECK
212 #endif
213 #if !defined(JSON_HEDLEY_MSVC_VERSION)
214  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0)
215 #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
216  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch)))
217 #elif defined(_MSC_VER) && (_MSC_VER >= 1200)
218  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch)))
219 #else
220  #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor)))
221 #endif
222 
223 #if defined(JSON_HEDLEY_INTEL_VERSION)
224  #undef JSON_HEDLEY_INTEL_VERSION
225 #endif
226 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL)
227  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE)
228 #elif defined(__INTEL_COMPILER) && !defined(__ICL)
229  #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0)
230 #endif
231 
232 #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK)
233  #undef JSON_HEDLEY_INTEL_VERSION_CHECK
234 #endif
235 #if defined(JSON_HEDLEY_INTEL_VERSION)
236  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
237 #else
238  #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0)
239 #endif
240 
241 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
242  #undef JSON_HEDLEY_INTEL_CL_VERSION
243 #endif
244 #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL)
245  #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0)
246 #endif
247 
248 #if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK)
249  #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
250 #endif
251 #if defined(JSON_HEDLEY_INTEL_CL_VERSION)
252  #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
253 #else
254  #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0)
255 #endif
256 
257 #if defined(JSON_HEDLEY_PGI_VERSION)
258  #undef JSON_HEDLEY_PGI_VERSION
259 #endif
260 #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__)
261  #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__)
262 #endif
263 
264 #if defined(JSON_HEDLEY_PGI_VERSION_CHECK)
265  #undef JSON_HEDLEY_PGI_VERSION_CHECK
266 #endif
267 #if defined(JSON_HEDLEY_PGI_VERSION)
268  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
269 #else
270  #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0)
271 #endif
272 
273 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
274  #undef JSON_HEDLEY_SUNPRO_VERSION
275 #endif
276 #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000)
277  #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)
278 #elif defined(__SUNPRO_C)
279  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf)
280 #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000)
281  #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)
282 #elif defined(__SUNPRO_CC)
283  #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf)
284 #endif
285 
286 #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK)
287  #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
288 #endif
289 #if defined(JSON_HEDLEY_SUNPRO_VERSION)
290  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
291 #else
292  #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0)
293 #endif
294 
295 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
296  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
297 #endif
298 #if defined(__EMSCRIPTEN__)
299  #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__)
300 #endif
301 
302 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK)
303  #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
304 #endif
305 #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION)
306  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
307 #else
308  #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0)
309 #endif
310 
311 #if defined(JSON_HEDLEY_ARM_VERSION)
312  #undef JSON_HEDLEY_ARM_VERSION
313 #endif
314 #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION)
315  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100)
316 #elif defined(__CC_ARM) && defined(__ARMCC_VERSION)
317  #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100)
318 #endif
319 
320 #if defined(JSON_HEDLEY_ARM_VERSION_CHECK)
321  #undef JSON_HEDLEY_ARM_VERSION_CHECK
322 #endif
323 #if defined(JSON_HEDLEY_ARM_VERSION)
324  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
325 #else
326  #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0)
327 #endif
328 
329 #if defined(JSON_HEDLEY_IBM_VERSION)
330  #undef JSON_HEDLEY_IBM_VERSION
331 #endif
332 #if defined(__ibmxl__)
333  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__)
334 #elif defined(__xlC__) && defined(__xlC_ver__)
335  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff)
336 #elif defined(__xlC__)
337  #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0)
338 #endif
339 
340 #if defined(JSON_HEDLEY_IBM_VERSION_CHECK)
341  #undef JSON_HEDLEY_IBM_VERSION_CHECK
342 #endif
343 #if defined(JSON_HEDLEY_IBM_VERSION)
344  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
345 #else
346  #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0)
347 #endif
348 
349 #if defined(JSON_HEDLEY_TI_VERSION)
350  #undef JSON_HEDLEY_TI_VERSION
351 #endif
352 #if \
353  defined(__TI_COMPILER_VERSION__) && \
354  ( \
355  defined(__TMS470__) || defined(__TI_ARM__) || \
356  defined(__MSP430__) || \
357  defined(__TMS320C2000__) \
358  )
359 #if (__TI_COMPILER_VERSION__ >= 16000000)
360  #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
361 #endif
362 #endif
363 
364 #if defined(JSON_HEDLEY_TI_VERSION_CHECK)
365  #undef JSON_HEDLEY_TI_VERSION_CHECK
366 #endif
367 #if defined(JSON_HEDLEY_TI_VERSION)
368  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
369 #else
370  #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0)
371 #endif
372 
373 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
374  #undef JSON_HEDLEY_TI_CL2000_VERSION
375 #endif
376 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__)
377  #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
378 #endif
379 
380 #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK)
381  #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
382 #endif
383 #if defined(JSON_HEDLEY_TI_CL2000_VERSION)
384  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
385 #else
386  #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0)
387 #endif
388 
389 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
390  #undef JSON_HEDLEY_TI_CL430_VERSION
391 #endif
392 #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__)
393  #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
394 #endif
395 
396 #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK)
397  #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
398 #endif
399 #if defined(JSON_HEDLEY_TI_CL430_VERSION)
400  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
401 #else
402  #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0)
403 #endif
404 
405 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
406  #undef JSON_HEDLEY_TI_ARMCL_VERSION
407 #endif
408 #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__))
409  #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
410 #endif
411 
412 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK)
413  #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
414 #endif
415 #if defined(JSON_HEDLEY_TI_ARMCL_VERSION)
416  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
417 #else
418  #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0)
419 #endif
420 
421 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
422  #undef JSON_HEDLEY_TI_CL6X_VERSION
423 #endif
424 #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__)
425  #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
426 #endif
427 
428 #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK)
429  #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
430 #endif
431 #if defined(JSON_HEDLEY_TI_CL6X_VERSION)
432  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
433 #else
434  #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0)
435 #endif
436 
437 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
438  #undef JSON_HEDLEY_TI_CL7X_VERSION
439 #endif
440 #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__)
441  #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
442 #endif
443 
444 #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK)
445  #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
446 #endif
447 #if defined(JSON_HEDLEY_TI_CL7X_VERSION)
448  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
449 #else
450  #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0)
451 #endif
452 
453 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
454  #undef JSON_HEDLEY_TI_CLPRU_VERSION
455 #endif
456 #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__)
457  #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000))
458 #endif
459 
460 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK)
461  #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
462 #endif
463 #if defined(JSON_HEDLEY_TI_CLPRU_VERSION)
464  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
465 #else
466  #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0)
467 #endif
468 
469 #if defined(JSON_HEDLEY_CRAY_VERSION)
470  #undef JSON_HEDLEY_CRAY_VERSION
471 #endif
472 #if defined(_CRAYC)
473  #if defined(_RELEASE_PATCHLEVEL)
474  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL)
475  #else
476  #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0)
477  #endif
478 #endif
479 
480 #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK)
481  #undef JSON_HEDLEY_CRAY_VERSION_CHECK
482 #endif
483 #if defined(JSON_HEDLEY_CRAY_VERSION)
484  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
485 #else
486  #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0)
487 #endif
488 
489 #if defined(JSON_HEDLEY_IAR_VERSION)
490  #undef JSON_HEDLEY_IAR_VERSION
491 #endif
492 #if defined(__IAR_SYSTEMS_ICC__)
493  #if __VER__ > 1000
494  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000))
495  #else
496  #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0)
497  #endif
498 #endif
499 
500 #if defined(JSON_HEDLEY_IAR_VERSION_CHECK)
501  #undef JSON_HEDLEY_IAR_VERSION_CHECK
502 #endif
503 #if defined(JSON_HEDLEY_IAR_VERSION)
504  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
505 #else
506  #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0)
507 #endif
508 
509 #if defined(JSON_HEDLEY_TINYC_VERSION)
510  #undef JSON_HEDLEY_TINYC_VERSION
511 #endif
512 #if defined(__TINYC__)
513  #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100)
514 #endif
515 
516 #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK)
517  #undef JSON_HEDLEY_TINYC_VERSION_CHECK
518 #endif
519 #if defined(JSON_HEDLEY_TINYC_VERSION)
520  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
521 #else
522  #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0)
523 #endif
524 
525 #if defined(JSON_HEDLEY_DMC_VERSION)
526  #undef JSON_HEDLEY_DMC_VERSION
527 #endif
528 #if defined(__DMC__)
529  #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf)
530 #endif
531 
532 #if defined(JSON_HEDLEY_DMC_VERSION_CHECK)
533  #undef JSON_HEDLEY_DMC_VERSION_CHECK
534 #endif
535 #if defined(JSON_HEDLEY_DMC_VERSION)
536  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
537 #else
538  #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0)
539 #endif
540 
541 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
542  #undef JSON_HEDLEY_COMPCERT_VERSION
543 #endif
544 #if defined(__COMPCERT_VERSION__)
545  #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100)
546 #endif
547 
548 #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK)
549  #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
550 #endif
551 #if defined(JSON_HEDLEY_COMPCERT_VERSION)
552  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
553 #else
554  #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0)
555 #endif
556 
557 #if defined(JSON_HEDLEY_PELLES_VERSION)
558  #undef JSON_HEDLEY_PELLES_VERSION
559 #endif
560 #if defined(__POCC__)
561  #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0)
562 #endif
563 
564 #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK)
565  #undef JSON_HEDLEY_PELLES_VERSION_CHECK
566 #endif
567 #if defined(JSON_HEDLEY_PELLES_VERSION)
568  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
569 #else
570  #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0)
571 #endif
572 
573 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
574  #undef JSON_HEDLEY_MCST_LCC_VERSION
575 #endif
576 #if defined(__LCC__) && defined(__LCC_MINOR__)
577  #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__)
578 #endif
579 
580 #if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK)
581  #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
582 #endif
583 #if defined(JSON_HEDLEY_MCST_LCC_VERSION)
584  #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
585 #else
586  #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0)
587 #endif
588 
589 #if defined(JSON_HEDLEY_GCC_VERSION)
590  #undef JSON_HEDLEY_GCC_VERSION
591 #endif
592 #if \
593  defined(JSON_HEDLEY_GNUC_VERSION) && \
594  !defined(__clang__) && \
595  !defined(JSON_HEDLEY_INTEL_VERSION) && \
596  !defined(JSON_HEDLEY_PGI_VERSION) && \
597  !defined(JSON_HEDLEY_ARM_VERSION) && \
598  !defined(JSON_HEDLEY_CRAY_VERSION) && \
599  !defined(JSON_HEDLEY_TI_VERSION) && \
600  !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \
601  !defined(JSON_HEDLEY_TI_CL430_VERSION) && \
602  !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \
603  !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \
604  !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \
605  !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \
606  !defined(__COMPCERT__) && \
607  !defined(JSON_HEDLEY_MCST_LCC_VERSION)
608  #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION
609 #endif
610 
611 #if defined(JSON_HEDLEY_GCC_VERSION_CHECK)
612  #undef JSON_HEDLEY_GCC_VERSION_CHECK
613 #endif
614 #if defined(JSON_HEDLEY_GCC_VERSION)
615  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch))
616 #else
617  #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0)
618 #endif
619 
620 #if defined(JSON_HEDLEY_HAS_ATTRIBUTE)
621  #undef JSON_HEDLEY_HAS_ATTRIBUTE
622 #endif
623 #if \
624  defined(__has_attribute) && \
625  ( \
626  (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \
627  )
628 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute)
629 #else
630 # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0)
631 #endif
632 
633 #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE)
634  #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
635 #endif
636 #if defined(__has_attribute)
637  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
638 #else
639  #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
640 #endif
641 
642 #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE)
643  #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
644 #endif
645 #if defined(__has_attribute)
646  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
647 #else
648  #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
649 #endif
650 
651 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE)
652  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
653 #endif
654 #if \
655  defined(__has_cpp_attribute) && \
656  defined(__cplusplus) && \
657  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0))
658  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute)
659 #else
660  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0)
661 #endif
662 
663 #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS)
664  #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
665 #endif
666 #if !defined(__cplusplus) || !defined(__has_cpp_attribute)
667  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
668 #elif \
669  !defined(JSON_HEDLEY_PGI_VERSION) && \
670  !defined(JSON_HEDLEY_IAR_VERSION) && \
671  (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \
672  (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0))
673  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute)
674 #else
675  #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0)
676 #endif
677 
678 #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE)
679  #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
680 #endif
681 #if defined(__has_cpp_attribute) && defined(__cplusplus)
682  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
683 #else
684  #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
685 #endif
686 
687 #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE)
688  #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
689 #endif
690 #if defined(__has_cpp_attribute) && defined(__cplusplus)
691  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute)
692 #else
693  #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
694 #endif
695 
696 #if defined(JSON_HEDLEY_HAS_BUILTIN)
697  #undef JSON_HEDLEY_HAS_BUILTIN
698 #endif
699 #if defined(__has_builtin)
700  #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin)
701 #else
702  #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0)
703 #endif
704 
705 #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN)
706  #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
707 #endif
708 #if defined(__has_builtin)
709  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
710 #else
711  #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
712 #endif
713 
714 #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN)
715  #undef JSON_HEDLEY_GCC_HAS_BUILTIN
716 #endif
717 #if defined(__has_builtin)
718  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin)
719 #else
720  #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
721 #endif
722 
723 #if defined(JSON_HEDLEY_HAS_FEATURE)
724  #undef JSON_HEDLEY_HAS_FEATURE
725 #endif
726 #if defined(__has_feature)
727  #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature)
728 #else
729  #define JSON_HEDLEY_HAS_FEATURE(feature) (0)
730 #endif
731 
732 #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE)
733  #undef JSON_HEDLEY_GNUC_HAS_FEATURE
734 #endif
735 #if defined(__has_feature)
736  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
737 #else
738  #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
739 #endif
740 
741 #if defined(JSON_HEDLEY_GCC_HAS_FEATURE)
742  #undef JSON_HEDLEY_GCC_HAS_FEATURE
743 #endif
744 #if defined(__has_feature)
745  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature)
746 #else
747  #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
748 #endif
749 
750 #if defined(JSON_HEDLEY_HAS_EXTENSION)
751  #undef JSON_HEDLEY_HAS_EXTENSION
752 #endif
753 #if defined(__has_extension)
754  #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension)
755 #else
756  #define JSON_HEDLEY_HAS_EXTENSION(extension) (0)
757 #endif
758 
759 #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION)
760  #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
761 #endif
762 #if defined(__has_extension)
763  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
764 #else
765  #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
766 #endif
767 
768 #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION)
769  #undef JSON_HEDLEY_GCC_HAS_EXTENSION
770 #endif
771 #if defined(__has_extension)
772  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension)
773 #else
774  #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
775 #endif
776 
777 #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE)
778  #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
779 #endif
780 #if defined(__has_declspec_attribute)
781  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute)
782 #else
783  #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0)
784 #endif
785 
786 #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE)
787  #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
788 #endif
789 #if defined(__has_declspec_attribute)
790  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
791 #else
792  #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
793 #endif
794 
795 #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE)
796  #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
797 #endif
798 #if defined(__has_declspec_attribute)
799  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute)
800 #else
801  #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
802 #endif
803 
804 #if defined(JSON_HEDLEY_HAS_WARNING)
805  #undef JSON_HEDLEY_HAS_WARNING
806 #endif
807 #if defined(__has_warning)
808  #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning)
809 #else
810  #define JSON_HEDLEY_HAS_WARNING(warning) (0)
811 #endif
812 
813 #if defined(JSON_HEDLEY_GNUC_HAS_WARNING)
814  #undef JSON_HEDLEY_GNUC_HAS_WARNING
815 #endif
816 #if defined(__has_warning)
817  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
818 #else
819  #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch)
820 #endif
821 
822 #if defined(JSON_HEDLEY_GCC_HAS_WARNING)
823  #undef JSON_HEDLEY_GCC_HAS_WARNING
824 #endif
825 #if defined(__has_warning)
826  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning)
827 #else
828  #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
829 #endif
830 
831 #if \
832  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
833  defined(__clang__) || \
834  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
835  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
836  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
837  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
838  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
839  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
840  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
841  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
842  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
843  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \
844  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
845  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
846  JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \
847  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \
848  JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \
849  (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR))
850  #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value)
851 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
852  #define JSON_HEDLEY_PRAGMA(value) __pragma(value)
853 #else
854  #define JSON_HEDLEY_PRAGMA(value)
855 #endif
856 
857 #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH)
858  #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
859 #endif
860 #if defined(JSON_HEDLEY_DIAGNOSTIC_POP)
861  #undef JSON_HEDLEY_DIAGNOSTIC_POP
862 #endif
863 #if defined(__clang__)
864  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
865  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
866 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
867  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
868  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
869 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
870  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
871  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
872 #elif \
873  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
874  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
875  #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push))
876  #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop))
877 #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0)
878  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push")
879  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop")
880 #elif \
881  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
882  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
883  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \
884  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
885  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
886  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
887  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push")
888  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop")
889 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
890  #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)")
891  #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)")
892 #else
893  #define JSON_HEDLEY_DIAGNOSTIC_PUSH
894  #define JSON_HEDLEY_DIAGNOSTIC_POP
895 #endif
896 
897 /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for
898  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
899 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
900  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
901 #endif
902 #if defined(__cplusplus)
903 # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat")
904 # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions")
905 # if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions")
906 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
907  JSON_HEDLEY_DIAGNOSTIC_PUSH \
908  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
909  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
910  _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \
911  xpr \
912  JSON_HEDLEY_DIAGNOSTIC_POP
913 # else
914 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
915  JSON_HEDLEY_DIAGNOSTIC_PUSH \
916  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
917  _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \
918  xpr \
919  JSON_HEDLEY_DIAGNOSTIC_POP
920 # endif
921 # else
922 # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \
923  JSON_HEDLEY_DIAGNOSTIC_PUSH \
924  _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \
925  xpr \
926  JSON_HEDLEY_DIAGNOSTIC_POP
927 # endif
928 # endif
929 #endif
930 #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_)
931  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x
932 #endif
933 
934 #if defined(JSON_HEDLEY_CONST_CAST)
935  #undef JSON_HEDLEY_CONST_CAST
936 #endif
937 #if defined(__cplusplus)
938 # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast<T>(expr))
939 #elif \
940  JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \
941  JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \
942  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
943 # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \
944  JSON_HEDLEY_DIAGNOSTIC_PUSH \
945  JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \
946  ((T) (expr)); \
947  JSON_HEDLEY_DIAGNOSTIC_POP \
948  }))
949 #else
950 # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr))
951 #endif
952 
953 #if defined(JSON_HEDLEY_REINTERPRET_CAST)
954  #undef JSON_HEDLEY_REINTERPRET_CAST
955 #endif
956 #if defined(__cplusplus)
957  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast<T>(expr))
958 #else
959  #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr))
960 #endif
961 
962 #if defined(JSON_HEDLEY_STATIC_CAST)
963  #undef JSON_HEDLEY_STATIC_CAST
964 #endif
965 #if defined(__cplusplus)
966  #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast<T>(expr))
967 #else
968  #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr))
969 #endif
970 
971 #if defined(JSON_HEDLEY_CPP_CAST)
972  #undef JSON_HEDLEY_CPP_CAST
973 #endif
974 #if defined(__cplusplus)
975 # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast")
976 # define JSON_HEDLEY_CPP_CAST(T, expr) \
977  JSON_HEDLEY_DIAGNOSTIC_PUSH \
978  _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \
979  ((T) (expr)) \
980  JSON_HEDLEY_DIAGNOSTIC_POP
981 # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0)
982 # define JSON_HEDLEY_CPP_CAST(T, expr) \
983  JSON_HEDLEY_DIAGNOSTIC_PUSH \
984  _Pragma("diag_suppress=Pe137") \
985  JSON_HEDLEY_DIAGNOSTIC_POP
986 # else
987 # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr))
988 # endif
989 #else
990 # define JSON_HEDLEY_CPP_CAST(T, expr) (expr)
991 #endif
992 
993 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED)
994  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
995 #endif
996 #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations")
997  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
998 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
999  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)")
1000 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1001  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786))
1002 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1003  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445")
1004 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1005  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1006 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1007  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1008 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1009  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996))
1010 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1011  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444")
1012 #elif \
1013  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1014  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1015  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1016  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1017  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1018  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1019  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1020  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1021  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1022  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1023  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0)
1024  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718")
1025 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus)
1026  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)")
1027 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus)
1028  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)")
1029 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1030  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215")
1031 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0)
1032  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)")
1033 #else
1034  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
1035 #endif
1036 
1037 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS)
1038  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1039 #endif
1040 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
1041  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"")
1042 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1043  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)")
1044 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1045  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161))
1046 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1047  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675")
1048 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0)
1049  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"")
1050 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0)
1051  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068))
1052 #elif \
1053  JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \
1054  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1055  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1056  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0)
1057  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1058 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0)
1059  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163")
1060 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1061  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161")
1062 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1063  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161")
1064 #else
1065  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
1066 #endif
1067 
1068 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES)
1069  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1070 #endif
1071 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes")
1072  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"")
1073 #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0)
1074  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
1075 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0)
1076  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)")
1077 #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1078  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292))
1079 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0)
1080  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030))
1081 #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0)
1082  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098")
1083 #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0)
1084  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1085 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)
1086  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)")
1087 #elif \
1088  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1089  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1090  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0)
1091  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173")
1092 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1093  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097")
1094 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1095  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097")
1096 #else
1097  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
1098 #endif
1099 
1100 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL)
1101  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1102 #endif
1103 #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual")
1104  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"")
1105 #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
1106  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)")
1107 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0)
1108  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
1109 #else
1110  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
1111 #endif
1112 
1113 #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION)
1114  #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1115 #endif
1116 #if JSON_HEDLEY_HAS_WARNING("-Wunused-function")
1117  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"")
1118 #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0)
1119  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"")
1120 #elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0)
1121  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505))
1122 #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1123  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142")
1124 #else
1125  #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
1126 #endif
1127 
1128 #if defined(JSON_HEDLEY_DEPRECATED)
1129  #undef JSON_HEDLEY_DEPRECATED
1130 #endif
1131 #if defined(JSON_HEDLEY_DEPRECATED_FOR)
1132  #undef JSON_HEDLEY_DEPRECATED_FOR
1133 #endif
1134 #if \
1135  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1136  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1137  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
1138  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
1139 #elif \
1140  (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1141  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1142  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1143  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1144  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \
1145  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1146  JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \
1147  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \
1148  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \
1149  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1150  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \
1151  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1152  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
1153  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
1154 #elif defined(__cplusplus) && (__cplusplus >= 201402L)
1155  #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]])
1156  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]])
1157 #elif \
1158  JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \
1159  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1160  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1161  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1162  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1163  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1164  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1165  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1166  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1167  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1168  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1169  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1170  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1171  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1172  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1173  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1174  #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
1175  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
1176 #elif \
1177  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1178  JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \
1179  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1180  #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated)
1181  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
1182 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1183  #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated")
1184  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated")
1185 #else
1186  #define JSON_HEDLEY_DEPRECATED(since)
1187  #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement)
1188 #endif
1189 
1190 #if defined(JSON_HEDLEY_UNAVAILABLE)
1191  #undef JSON_HEDLEY_UNAVAILABLE
1192 #endif
1193 #if \
1194  JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \
1195  JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \
1196  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1197  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1198  #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since)))
1199 #else
1200  #define JSON_HEDLEY_UNAVAILABLE(available_since)
1201 #endif
1202 
1203 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT)
1204  #undef JSON_HEDLEY_WARN_UNUSED_RESULT
1205 #endif
1206 #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG)
1207  #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
1208 #endif
1209 #if \
1210  JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \
1211  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1212  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1213  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1214  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1215  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1216  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1217  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1218  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1219  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1220  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1221  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1222  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1223  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1224  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1225  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1226  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1227  #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
1228  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__))
1229 #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L)
1230  #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1231  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]])
1232 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard)
1233  #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1234  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]])
1235 #elif defined(_Check_return_) /* SAL */
1236  #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_
1237  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_
1238 #else
1239  #define JSON_HEDLEY_WARN_UNUSED_RESULT
1240  #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg)
1241 #endif
1242 
1243 #if defined(JSON_HEDLEY_SENTINEL)
1244  #undef JSON_HEDLEY_SENTINEL
1245 #endif
1246 #if \
1247  JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \
1248  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1249  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1250  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1251  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1252  #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position)))
1253 #else
1254  #define JSON_HEDLEY_SENTINEL(position)
1255 #endif
1256 
1257 #if defined(JSON_HEDLEY_NO_RETURN)
1258  #undef JSON_HEDLEY_NO_RETURN
1259 #endif
1260 #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1261  #define JSON_HEDLEY_NO_RETURN __noreturn
1262 #elif \
1263  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1264  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1265  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1266 #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
1267  #define JSON_HEDLEY_NO_RETURN _Noreturn
1268 #elif defined(__cplusplus) && (__cplusplus >= 201103L)
1269  #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]])
1270 #elif \
1271  JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \
1272  JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \
1273  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1274  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1275  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1276  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1277  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1278  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1279  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1280  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1281  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1282  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1283  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1284  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1285  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1286  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1287  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1288  #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__))
1289 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1290  #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return")
1291 #elif \
1292  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1293  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1294  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1295 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1296  #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;")
1297 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1298  #define JSON_HEDLEY_NO_RETURN __attribute((noreturn))
1299 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1300  #define JSON_HEDLEY_NO_RETURN __declspec(noreturn)
1301 #else
1302  #define JSON_HEDLEY_NO_RETURN
1303 #endif
1304 
1305 #if defined(JSON_HEDLEY_NO_ESCAPE)
1306  #undef JSON_HEDLEY_NO_ESCAPE
1307 #endif
1308 #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape)
1309  #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__))
1310 #else
1311  #define JSON_HEDLEY_NO_ESCAPE
1312 #endif
1313 
1314 #if defined(JSON_HEDLEY_UNREACHABLE)
1315  #undef JSON_HEDLEY_UNREACHABLE
1316 #endif
1317 #if defined(JSON_HEDLEY_UNREACHABLE_RETURN)
1318  #undef JSON_HEDLEY_UNREACHABLE_RETURN
1319 #endif
1320 #if defined(JSON_HEDLEY_ASSUME)
1321  #undef JSON_HEDLEY_ASSUME
1322 #endif
1323 #if \
1324  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1325  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1326  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1327  #define JSON_HEDLEY_ASSUME(expr) __assume(expr)
1328 #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume)
1329  #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr)
1330 #elif \
1331  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1332  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1333  #if defined(__cplusplus)
1334  #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr)
1335  #else
1336  #define JSON_HEDLEY_ASSUME(expr) _nassert(expr)
1337  #endif
1338 #endif
1339 #if \
1340  (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \
1341  JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \
1342  JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \
1343  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1344  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \
1345  JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \
1346  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1347  #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable()
1348 #elif defined(JSON_HEDLEY_ASSUME)
1349  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1350 #endif
1351 #if !defined(JSON_HEDLEY_ASSUME)
1352  #if defined(JSON_HEDLEY_UNREACHABLE)
1353  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1)))
1354  #else
1355  #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr)
1356  #endif
1357 #endif
1358 #if defined(JSON_HEDLEY_UNREACHABLE)
1359  #if \
1360  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1361  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0)
1362  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value))
1363  #else
1364  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE()
1365  #endif
1366 #else
1367  #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value)
1368 #endif
1369 #if !defined(JSON_HEDLEY_UNREACHABLE)
1370  #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0)
1371 #endif
1372 
1374 #if JSON_HEDLEY_HAS_WARNING("-Wpedantic")
1375  #pragma clang diagnostic ignored "-Wpedantic"
1376 #endif
1377 #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus)
1378  #pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
1379 #endif
1380 #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0)
1381  #if defined(__clang__)
1382  #pragma clang diagnostic ignored "-Wvariadic-macros"
1383  #elif defined(JSON_HEDLEY_GCC_VERSION)
1384  #pragma GCC diagnostic ignored "-Wvariadic-macros"
1385  #endif
1386 #endif
1387 #if defined(JSON_HEDLEY_NON_NULL)
1388  #undef JSON_HEDLEY_NON_NULL
1389 #endif
1390 #if \
1391  JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \
1392  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1393  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1394  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1395  #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
1396 #else
1397  #define JSON_HEDLEY_NON_NULL(...)
1398 #endif
1400 
1401 #if defined(JSON_HEDLEY_PRINTF_FORMAT)
1402  #undef JSON_HEDLEY_PRINTF_FORMAT
1403 #endif
1404 #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO)
1405  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check)))
1406 #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO)
1407  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check)))
1408 #elif \
1409  JSON_HEDLEY_HAS_ATTRIBUTE(format) || \
1410  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1411  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1412  JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \
1413  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1414  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1415  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1416  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1417  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1418  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1419  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1420  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1421  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1422  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1423  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1424  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1425  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1426  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check)))
1427 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0)
1428  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check))
1429 #else
1430  #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check)
1431 #endif
1432 
1433 #if defined(JSON_HEDLEY_CONSTEXPR)
1434  #undef JSON_HEDLEY_CONSTEXPR
1435 #endif
1436 #if defined(__cplusplus)
1437  #if __cplusplus >= 201103L
1438  #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr)
1439  #endif
1440 #endif
1441 #if !defined(JSON_HEDLEY_CONSTEXPR)
1442  #define JSON_HEDLEY_CONSTEXPR
1443 #endif
1444 
1445 #if defined(JSON_HEDLEY_PREDICT)
1446  #undef JSON_HEDLEY_PREDICT
1447 #endif
1448 #if defined(JSON_HEDLEY_LIKELY)
1449  #undef JSON_HEDLEY_LIKELY
1450 #endif
1451 #if defined(JSON_HEDLEY_UNLIKELY)
1452  #undef JSON_HEDLEY_UNLIKELY
1453 #endif
1454 #if defined(JSON_HEDLEY_UNPREDICTABLE)
1455  #undef JSON_HEDLEY_UNPREDICTABLE
1456 #endif
1457 #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable)
1458  #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr))
1459 #endif
1460 #if \
1461  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \
1462  JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \
1463  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1464 # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability))
1465 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability))
1466 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability))
1467 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 )
1468 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 )
1469 #elif \
1470  (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1471  JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \
1472  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1473  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
1474  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1475  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1476  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1477  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \
1478  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1479  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \
1480  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1481  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1482  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1483  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \
1484  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1485  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1486 # define JSON_HEDLEY_PREDICT(expr, expected, probability) \
1487  (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)))
1488 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \
1489  (__extension__ ({ \
1490  double hedley_probability_ = (probability); \
1491  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \
1492  }))
1493 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \
1494  (__extension__ ({ \
1495  double hedley_probability_ = (probability); \
1496  ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \
1497  }))
1498 # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1)
1499 # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
1500 #else
1501 # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))
1502 # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr))
1503 # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr))
1504 # define JSON_HEDLEY_LIKELY(expr) (!!(expr))
1505 # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr))
1506 #endif
1507 #if !defined(JSON_HEDLEY_UNPREDICTABLE)
1508  #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5)
1509 #endif
1510 
1511 #if defined(JSON_HEDLEY_MALLOC)
1512  #undef JSON_HEDLEY_MALLOC
1513 #endif
1514 #if \
1515  JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \
1516  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1517  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1518  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1519  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1520  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1521  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1522  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1523  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1524  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1525  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1526  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1527  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1528  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1529  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1530  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1531  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1532  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1533  #define JSON_HEDLEY_MALLOC __attribute__((__malloc__))
1534 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1535  #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory")
1536 #elif \
1537  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1538  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1539  #define JSON_HEDLEY_MALLOC __declspec(restrict)
1540 #else
1541  #define JSON_HEDLEY_MALLOC
1542 #endif
1543 
1544 #if defined(JSON_HEDLEY_PURE)
1545  #undef JSON_HEDLEY_PURE
1546 #endif
1547 #if \
1548  JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \
1549  JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \
1550  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1551  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1552  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1553  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1554  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1555  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1556  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1557  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1558  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1559  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1560  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1561  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1562  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1563  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1564  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1565  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1566  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1567 # define JSON_HEDLEY_PURE __attribute__((__pure__))
1568 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1569 # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data")
1570 #elif defined(__cplusplus) && \
1571  ( \
1572  JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \
1573  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \
1574  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \
1575  )
1576 # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;")
1577 #else
1578 # define JSON_HEDLEY_PURE
1579 #endif
1580 
1581 #if defined(JSON_HEDLEY_CONST)
1582  #undef JSON_HEDLEY_CONST
1583 #endif
1584 #if \
1585  JSON_HEDLEY_HAS_ATTRIBUTE(const) || \
1586  JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \
1587  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1588  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1589  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1590  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1591  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1592  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1593  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1594  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1595  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1596  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1597  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1598  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1599  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1600  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1601  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1602  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1603  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1604  #define JSON_HEDLEY_CONST __attribute__((__const__))
1605 #elif \
1606  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0)
1607  #define JSON_HEDLEY_CONST _Pragma("no_side_effect")
1608 #else
1609  #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE
1610 #endif
1611 
1612 #if defined(JSON_HEDLEY_RESTRICT)
1613  #undef JSON_HEDLEY_RESTRICT
1614 #endif
1615 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus)
1616  #define JSON_HEDLEY_RESTRICT restrict
1617 #elif \
1618  JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \
1619  JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \
1620  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1621  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1622  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1623  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1624  JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \
1625  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1626  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \
1627  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \
1628  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1629  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \
1630  JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \
1631  defined(__clang__) || \
1632  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1633  #define JSON_HEDLEY_RESTRICT __restrict
1634 #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus)
1635  #define JSON_HEDLEY_RESTRICT _Restrict
1636 #else
1637  #define JSON_HEDLEY_RESTRICT
1638 #endif
1639 
1640 #if defined(JSON_HEDLEY_INLINE)
1641  #undef JSON_HEDLEY_INLINE
1642 #endif
1643 #if \
1644  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \
1645  (defined(__cplusplus) && (__cplusplus >= 199711L))
1646  #define JSON_HEDLEY_INLINE inline
1647 #elif \
1648  defined(JSON_HEDLEY_GCC_VERSION) || \
1649  JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0)
1650  #define JSON_HEDLEY_INLINE __inline__
1651 #elif \
1652  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1653  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1654  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1655  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \
1656  JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \
1657  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \
1658  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \
1659  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1660  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1661  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1662  #define JSON_HEDLEY_INLINE __inline
1663 #else
1664  #define JSON_HEDLEY_INLINE
1665 #endif
1666 
1667 #if defined(JSON_HEDLEY_ALWAYS_INLINE)
1668  #undef JSON_HEDLEY_ALWAYS_INLINE
1669 #endif
1670 #if \
1671  JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \
1672  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1673  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1674  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1675  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1676  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1677  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1678  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1679  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1680  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1681  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1682  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1683  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1684  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1685  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1686  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1687  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1688  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1689  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1690 # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE
1691 #elif \
1692  JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \
1693  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1694 # define JSON_HEDLEY_ALWAYS_INLINE __forceinline
1695 #elif defined(__cplusplus) && \
1696  ( \
1697  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1698  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1699  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1700  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1701  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1702  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \
1703  )
1704 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;")
1705 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1706 # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced")
1707 #else
1708 # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE
1709 #endif
1710 
1711 #if defined(JSON_HEDLEY_NEVER_INLINE)
1712  #undef JSON_HEDLEY_NEVER_INLINE
1713 #endif
1714 #if \
1715  JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \
1716  JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \
1717  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1718  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1719  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1720  JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
1721  JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \
1722  (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1723  JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \
1724  (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1725  JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \
1726  (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1727  JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \
1728  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1729  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \
1730  JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \
1731  JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \
1732  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \
1733  JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0)
1734  #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__))
1735 #elif \
1736  JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \
1737  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1738  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1739 #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0)
1740  #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline")
1741 #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus)
1742  #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
1743 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
1744  #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never")
1745 #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0)
1746  #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline))
1747 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0)
1748  #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline)
1749 #else
1750  #define JSON_HEDLEY_NEVER_INLINE
1751 #endif
1752 
1753 #if defined(JSON_HEDLEY_PRIVATE)
1754  #undef JSON_HEDLEY_PRIVATE
1755 #endif
1756 #if defined(JSON_HEDLEY_PUBLIC)
1757  #undef JSON_HEDLEY_PUBLIC
1758 #endif
1759 #if defined(JSON_HEDLEY_IMPORT)
1760  #undef JSON_HEDLEY_IMPORT
1761 #endif
1762 #if defined(_WIN32) || defined(__CYGWIN__)
1763 # define JSON_HEDLEY_PRIVATE
1764 # define JSON_HEDLEY_PUBLIC __declspec(dllexport)
1765 # define JSON_HEDLEY_IMPORT __declspec(dllimport)
1766 #else
1767 # if \
1768  JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \
1769  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1770  JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
1771  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1772  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1773  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1774  ( \
1775  defined(__TI_EABI__) && \
1776  ( \
1777  (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
1778  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \
1779  ) \
1780  ) || \
1781  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1782 # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden")))
1783 # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default")))
1784 # else
1785 # define JSON_HEDLEY_PRIVATE
1786 # define JSON_HEDLEY_PUBLIC
1787 # endif
1788 # define JSON_HEDLEY_IMPORT extern
1789 #endif
1790 
1791 #if defined(JSON_HEDLEY_NO_THROW)
1792  #undef JSON_HEDLEY_NO_THROW
1793 #endif
1794 #if \
1795  JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \
1796  JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \
1797  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1798  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1799  #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__))
1800 #elif \
1801  JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \
1802  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \
1803  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0)
1804  #define JSON_HEDLEY_NO_THROW __declspec(nothrow)
1805 #else
1806  #define JSON_HEDLEY_NO_THROW
1807 #endif
1808 
1809 #if defined(JSON_HEDLEY_FALL_THROUGH)
1810  #undef JSON_HEDLEY_FALL_THROUGH
1811 #endif
1812 #if \
1813  JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \
1814  JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \
1815  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1816  #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__))
1817 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough)
1818  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]])
1819 #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)
1820  #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]])
1821 #elif defined(__fallthrough) /* SAL */
1822  #define JSON_HEDLEY_FALL_THROUGH __fallthrough
1823 #else
1824  #define JSON_HEDLEY_FALL_THROUGH
1825 #endif
1826 
1827 #if defined(JSON_HEDLEY_RETURNS_NON_NULL)
1828  #undef JSON_HEDLEY_RETURNS_NON_NULL
1829 #endif
1830 #if \
1831  JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \
1832  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1833  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1834  #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__))
1835 #elif defined(_Ret_notnull_) /* SAL */
1836  #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_
1837 #else
1838  #define JSON_HEDLEY_RETURNS_NON_NULL
1839 #endif
1840 
1841 #if defined(JSON_HEDLEY_ARRAY_PARAM)
1842  #undef JSON_HEDLEY_ARRAY_PARAM
1843 #endif
1844 #if \
1845  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
1846  !defined(__STDC_NO_VLA__) && \
1847  !defined(__cplusplus) && \
1848  !defined(JSON_HEDLEY_PGI_VERSION) && \
1849  !defined(JSON_HEDLEY_TINYC_VERSION)
1850  #define JSON_HEDLEY_ARRAY_PARAM(name) (name)
1851 #else
1852  #define JSON_HEDLEY_ARRAY_PARAM(name)
1853 #endif
1854 
1855 #if defined(JSON_HEDLEY_IS_CONSTANT)
1856  #undef JSON_HEDLEY_IS_CONSTANT
1857 #endif
1858 #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR)
1859  #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
1860 #endif
1861 /* JSON_HEDLEY_IS_CONSTEXPR_ is for
1862  HEDLEY INTERNAL USE ONLY. API subject to change without notice. */
1863 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1864  #undef JSON_HEDLEY_IS_CONSTEXPR_
1865 #endif
1866 #if \
1867  JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \
1868  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1869  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1870  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \
1871  JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
1872  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1873  JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \
1874  (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \
1875  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1876  JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10)
1877  #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr)
1878 #endif
1879 #if !defined(__cplusplus)
1880 # if \
1881  JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \
1882  JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \
1883  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1884  JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \
1885  JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \
1886  JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \
1887  JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24)
1888 #if defined(__INTPTR_TYPE__)
1889  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*)
1890 #else
1891  #include <stdint.h>
1892  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*)
1893 #endif
1894 # elif \
1895  ( \
1896  defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \
1897  !defined(JSON_HEDLEY_SUNPRO_VERSION) && \
1898  !defined(JSON_HEDLEY_PGI_VERSION) && \
1899  !defined(JSON_HEDLEY_IAR_VERSION)) || \
1900  (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \
1901  JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \
1902  JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \
1903  JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \
1904  JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0)
1905 #if defined(__INTPTR_TYPE__)
1906  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0)
1907 #else
1908  #include <stdint.h>
1909  #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0)
1910 #endif
1911 # elif \
1912  defined(JSON_HEDLEY_GCC_VERSION) || \
1913  defined(JSON_HEDLEY_INTEL_VERSION) || \
1914  defined(JSON_HEDLEY_TINYC_VERSION) || \
1915  defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \
1916  JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \
1917  defined(JSON_HEDLEY_TI_CL2000_VERSION) || \
1918  defined(JSON_HEDLEY_TI_CL6X_VERSION) || \
1919  defined(JSON_HEDLEY_TI_CL7X_VERSION) || \
1920  defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \
1921  defined(__clang__)
1922 # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \
1923  sizeof(void) != \
1924  sizeof(*( \
1925  1 ? \
1926  ((void*) ((expr) * 0L) ) : \
1927 ((struct { char v[sizeof(void) * 2]; } *) 1) \
1928  ) \
1929  ) \
1930  )
1931 # endif
1932 #endif
1933 #if defined(JSON_HEDLEY_IS_CONSTEXPR_)
1934  #if !defined(JSON_HEDLEY_IS_CONSTANT)
1935  #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr)
1936  #endif
1937  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1))
1938 #else
1939  #if !defined(JSON_HEDLEY_IS_CONSTANT)
1940  #define JSON_HEDLEY_IS_CONSTANT(expr) (0)
1941  #endif
1942  #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr)
1943 #endif
1944 
1945 #if defined(JSON_HEDLEY_BEGIN_C_DECLS)
1946  #undef JSON_HEDLEY_BEGIN_C_DECLS
1947 #endif
1948 #if defined(JSON_HEDLEY_END_C_DECLS)
1949  #undef JSON_HEDLEY_END_C_DECLS
1950 #endif
1951 #if defined(JSON_HEDLEY_C_DECL)
1952  #undef JSON_HEDLEY_C_DECL
1953 #endif
1954 #if defined(__cplusplus)
1955  #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" {
1956  #define JSON_HEDLEY_END_C_DECLS }
1957  #define JSON_HEDLEY_C_DECL extern "C"
1958 #else
1959  #define JSON_HEDLEY_BEGIN_C_DECLS
1960  #define JSON_HEDLEY_END_C_DECLS
1961  #define JSON_HEDLEY_C_DECL
1962 #endif
1963 
1964 #if defined(JSON_HEDLEY_STATIC_ASSERT)
1965  #undef JSON_HEDLEY_STATIC_ASSERT
1966 #endif
1967 #if \
1968  !defined(__cplusplus) && ( \
1969  (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \
1970  (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \
1971  JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \
1972  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \
1973  defined(_Static_assert) \
1974  )
1975 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message)
1976 #elif \
1977  (defined(__cplusplus) && (__cplusplus >= 201103L)) || \
1978  JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \
1979  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
1980 # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message))
1981 #else
1982 # define JSON_HEDLEY_STATIC_ASSERT(expr, message)
1983 #endif
1984 
1985 #if defined(JSON_HEDLEY_NULL)
1986  #undef JSON_HEDLEY_NULL
1987 #endif
1988 #if defined(__cplusplus)
1989  #if __cplusplus >= 201103L
1990  #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr)
1991  #elif defined(NULL)
1992  #define JSON_HEDLEY_NULL NULL
1993  #else
1994  #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0)
1995  #endif
1996 #elif defined(NULL)
1997  #define JSON_HEDLEY_NULL NULL
1998 #else
1999  #define JSON_HEDLEY_NULL ((void*) 0)
2000 #endif
2001 
2002 #if defined(JSON_HEDLEY_MESSAGE)
2003  #undef JSON_HEDLEY_MESSAGE
2004 #endif
2005 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2006 # define JSON_HEDLEY_MESSAGE(msg) \
2007  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2008  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2009  JSON_HEDLEY_PRAGMA(message msg) \
2010  JSON_HEDLEY_DIAGNOSTIC_POP
2011 #elif \
2012  JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \
2013  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2014 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg)
2015 #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0)
2016 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg)
2017 #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0)
2018 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2019 #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0)
2020 # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg))
2021 #else
2022 # define JSON_HEDLEY_MESSAGE(msg)
2023 #endif
2024 
2025 #if defined(JSON_HEDLEY_WARNING)
2026  #undef JSON_HEDLEY_WARNING
2027 #endif
2028 #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas")
2029 # define JSON_HEDLEY_WARNING(msg) \
2030  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2031  JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \
2032  JSON_HEDLEY_PRAGMA(clang warning msg) \
2033  JSON_HEDLEY_DIAGNOSTIC_POP
2034 #elif \
2035  JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \
2036  JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \
2037  JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0)
2038 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg)
2039 #elif \
2040  JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \
2041  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2042 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg))
2043 #else
2044 # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg)
2045 #endif
2046 
2047 #if defined(JSON_HEDLEY_REQUIRE)
2048  #undef JSON_HEDLEY_REQUIRE
2049 #endif
2050 #if defined(JSON_HEDLEY_REQUIRE_MSG)
2051  #undef JSON_HEDLEY_REQUIRE_MSG
2052 #endif
2053 #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if)
2054 # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat")
2055 # define JSON_HEDLEY_REQUIRE(expr) \
2056  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2057  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2058  __attribute__((diagnose_if(!(expr), #expr, "error"))) \
2059  JSON_HEDLEY_DIAGNOSTIC_POP
2060 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \
2061  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2062  _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
2063  __attribute__((diagnose_if(!(expr), msg, "error"))) \
2064  JSON_HEDLEY_DIAGNOSTIC_POP
2065 # else
2066 # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error")))
2067 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error")))
2068 # endif
2069 #else
2070 # define JSON_HEDLEY_REQUIRE(expr)
2071 # define JSON_HEDLEY_REQUIRE_MSG(expr,msg)
2072 #endif
2073 
2074 #if defined(JSON_HEDLEY_FLAGS)
2075  #undef JSON_HEDLEY_FLAGS
2076 #endif
2077 #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion"))
2078  #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__))
2079 #else
2080  #define JSON_HEDLEY_FLAGS
2081 #endif
2082 
2083 #if defined(JSON_HEDLEY_FLAGS_CAST)
2084  #undef JSON_HEDLEY_FLAGS_CAST
2085 #endif
2086 #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0)
2087 # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \
2088  JSON_HEDLEY_DIAGNOSTIC_PUSH \
2089  _Pragma("warning(disable:188)") \
2090  ((T) (expr)); \
2091  JSON_HEDLEY_DIAGNOSTIC_POP \
2092  }))
2093 #else
2094 # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr)
2095 #endif
2096 
2097 #if defined(JSON_HEDLEY_EMPTY_BASES)
2098  #undef JSON_HEDLEY_EMPTY_BASES
2099 #endif
2100 #if \
2101  (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \
2102  JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0)
2103  #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases)
2104 #else
2105  #define JSON_HEDLEY_EMPTY_BASES
2106 #endif
2107 
2108 /* Remaining macros are deprecated. */
2109 
2110 #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK)
2111  #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
2112 #endif
2113 #if defined(__clang__)
2114  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0)
2115 #else
2116  #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch)
2117 #endif
2118 
2119 #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE)
2120  #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
2121 #endif
2122 #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute)
2123 
2124 #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE)
2125  #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
2126 #endif
2127 #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute)
2128 
2129 #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN)
2130  #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
2131 #endif
2132 #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin)
2133 
2134 #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE)
2135  #undef JSON_HEDLEY_CLANG_HAS_FEATURE
2136 #endif
2137 #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature)
2138 
2139 #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION)
2140  #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
2141 #endif
2142 #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension)
2143 
2144 #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE)
2145  #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
2146 #endif
2147 #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute)
2148 
2149 #if defined(JSON_HEDLEY_CLANG_HAS_WARNING)
2150  #undef JSON_HEDLEY_CLANG_HAS_WARNING
2151 #endif
2152 #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning)
2153 
2154 #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */
2155 
2156 // #include <nlohmann/detail/meta/detected.hpp>
2157 
2158 
2159 #include <type_traits>
2160 
2161 // #include <nlohmann/detail/meta/void_t.hpp>
2162 
2163 
2164 namespace nlohmann
2165 {
2166 namespace detail
2167 {
2168 template<typename ...Ts> struct make_void
2169 {
2170  using type = void;
2171 };
2172 template<typename ...Ts> using void_t = typename make_void<Ts...>::type;
2173 } // namespace detail
2174 } // namespace nlohmann
2175 
2176 
2177 // https://en.cppreference.com/w/cpp/experimental/is_detected
2178 namespace nlohmann
2179 {
2180 namespace detail
2181 {
2182 struct nonesuch
2183 {
2184  nonesuch() = delete;
2185  ~nonesuch() = delete;
2186  nonesuch(nonesuch const&) = delete;
2187  nonesuch(nonesuch const&&) = delete;
2188  void operator=(nonesuch const&) = delete;
2189  void operator=(nonesuch&&) = delete;
2190 };
2191 
2192 template<class Default,
2193  class AlwaysVoid,
2194  template<class...> class Op,
2195  class... Args>
2196 struct detector
2197 {
2198  using value_t = std::false_type;
2199  using type = Default;
2200 };
2201 
2202 template<class Default, template<class...> class Op, class... Args>
2203 struct detector<Default, void_t<Op<Args...>>, Op, Args...>
2204 {
2205  using value_t = std::true_type;
2206  using type = Op<Args...>;
2207 };
2208 
2209 template<template<class...> class Op, class... Args>
2210 using is_detected = typename detector<nonesuch, void, Op, Args...>::value_t;
2211 
2212 template<template<class...> class Op, class... Args>
2213 struct is_detected_lazy : is_detected<Op, Args...> { };
2214 
2215 template<template<class...> class Op, class... Args>
2216 using detected_t = typename detector<nonesuch, void, Op, Args...>::type;
2217 
2218 template<class Default, template<class...> class Op, class... Args>
2219 using detected_or = detector<Default, void, Op, Args...>;
2220 
2221 template<class Default, template<class...> class Op, class... Args>
2222 using detected_or_t = typename detected_or<Default, Op, Args...>::type;
2223 
2224 template<class Expected, template<class...> class Op, class... Args>
2225 using is_detected_exact = std::is_same<Expected, detected_t<Op, Args...>>;
2226 
2227 template<class To, template<class...> class Op, class... Args>
2229  std::is_convertible<detected_t<Op, Args...>, To>;
2230 } // namespace detail
2231 } // namespace nlohmann
2232 
2233 
2234 // This file contains all internal macro definitions
2235 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
2236 
2237 // exclude unsupported compilers
2238 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
2239  #if defined(__clang__)
2240  #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
2241  #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
2242  #endif
2243  #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
2244  #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
2245  #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
2246  #endif
2247  #endif
2248 #endif
2249 
2250 // C++ language standard detection
2251 // if the user manually specified the used c++ version this is skipped
2252 #if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11)
2253  #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
2254  #define JSON_HAS_CPP_20
2255  #define JSON_HAS_CPP_17
2256  #define JSON_HAS_CPP_14
2257  #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
2258  #define JSON_HAS_CPP_17
2259  #define JSON_HAS_CPP_14
2260  #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
2261  #define JSON_HAS_CPP_14
2262  #endif
2263  // the cpp 11 flag is always specified because it is the minimal required version
2264  #define JSON_HAS_CPP_11
2265 #endif
2266 
2267 #ifdef __has_include
2268  #if __has_include(<version>)
2269  #include <version>
2270  #endif
2271 #endif
2272 
2273 #if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
2274  #ifdef JSON_HAS_CPP_17
2275  #if defined(__cpp_lib_filesystem)
2276  #define JSON_HAS_FILESYSTEM 1
2277  #elif defined(__cpp_lib_experimental_filesystem)
2278  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2279  #elif !defined(__has_include)
2280  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2281  #elif __has_include(<filesystem>)
2282  #define JSON_HAS_FILESYSTEM 1
2283  #elif __has_include(<experimental/filesystem>)
2284  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
2285  #endif
2286 
2287  // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
2288  #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
2289  #undef JSON_HAS_FILESYSTEM
2290  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2291  #endif
2292 
2293  // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
2294  #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
2295  #undef JSON_HAS_FILESYSTEM
2296  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2297  #endif
2298 
2299  // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
2300  #if defined(__clang_major__) && __clang_major__ < 7
2301  #undef JSON_HAS_FILESYSTEM
2302  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2303  #endif
2304 
2305  // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
2306  #if defined(_MSC_VER) && _MSC_VER < 1914
2307  #undef JSON_HAS_FILESYSTEM
2308  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2309  #endif
2310 
2311  // no filesystem support before iOS 13
2312  #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
2313  #undef JSON_HAS_FILESYSTEM
2314  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2315  #endif
2316 
2317  // no filesystem support before macOS Catalina
2318  #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
2319  #undef JSON_HAS_FILESYSTEM
2320  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2321  #endif
2322  #endif
2323 #endif
2324 
2325 #ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM
2326  #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0
2327 #endif
2328 
2329 #ifndef JSON_HAS_FILESYSTEM
2330  #define JSON_HAS_FILESYSTEM 0
2331 #endif
2332 
2333 #ifndef JSON_HAS_THREE_WAY_COMPARISON
2334  #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \
2335  && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
2336  #define JSON_HAS_THREE_WAY_COMPARISON 1
2337  #else
2338  #define JSON_HAS_THREE_WAY_COMPARISON 0
2339  #endif
2340 #endif
2341 
2342 #ifndef JSON_HAS_RANGES
2343  // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error
2344  #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427
2345  #define JSON_HAS_RANGES 0
2346  #elif defined(__cpp_lib_ranges)
2347  #define JSON_HAS_RANGES 1
2348  #else
2349  #define JSON_HAS_RANGES 0
2350  #endif
2351 #endif
2352 
2353 #ifdef JSON_HAS_CPP_17
2354  #define JSON_INLINE_VARIABLE inline
2355 #else
2356  #define JSON_INLINE_VARIABLE
2357 #endif
2358 
2359 #if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address)
2360  #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]]
2361 #else
2362  #define JSON_NO_UNIQUE_ADDRESS
2363 #endif
2364 
2365 // disable documentation warnings on clang
2366 #if defined(__clang__)
2367  #pragma clang diagnostic push
2368  #pragma clang diagnostic ignored "-Wdocumentation"
2369  #pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
2370 #endif
2371 
2372 // allow disabling exceptions
2373 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
2374  #define JSON_THROW(exception) throw exception
2375  #define JSON_TRY try
2376  #define JSON_CATCH(exception) catch(exception)
2377  #define JSON_INTERNAL_CATCH(exception) catch(exception)
2378 #else
2379  #include <cstdlib>
2380  #define JSON_THROW(exception) std::abort()
2381  #define JSON_TRY if(true)
2382  #define JSON_CATCH(exception) if(false)
2383  #define JSON_INTERNAL_CATCH(exception) if(false)
2384 #endif
2385 
2386 // override exception macros
2387 #if defined(JSON_THROW_USER)
2388  #undef JSON_THROW
2389  #define JSON_THROW JSON_THROW_USER
2390 #endif
2391 #if defined(JSON_TRY_USER)
2392  #undef JSON_TRY
2393  #define JSON_TRY JSON_TRY_USER
2394 #endif
2395 #if defined(JSON_CATCH_USER)
2396  #undef JSON_CATCH
2397  #define JSON_CATCH JSON_CATCH_USER
2398  #undef JSON_INTERNAL_CATCH
2399  #define JSON_INTERNAL_CATCH JSON_CATCH_USER
2400 #endif
2401 #if defined(JSON_INTERNAL_CATCH_USER)
2402  #undef JSON_INTERNAL_CATCH
2403  #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
2404 #endif
2405 
2406 // allow overriding assert
2407 #if !defined(JSON_ASSERT)
2408  #include <cassert> // assert
2409  #define JSON_ASSERT(x) assert(x)
2410 #endif
2411 
2412 // allow to access some private functions (needed by the test suite)
2413 #if defined(JSON_TESTS_PRIVATE)
2414  #define JSON_PRIVATE_UNLESS_TESTED public
2415 #else
2416  #define JSON_PRIVATE_UNLESS_TESTED private
2417 #endif
2418 
2424 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \
2425  template<typename BasicJsonType> \
2426  inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
2427  { \
2428  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2429  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2430  auto it = std::find_if(std::begin(m), std::end(m), \
2431  [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2432  { \
2433  return ej_pair.first == e; \
2434  }); \
2435  j = ((it != std::end(m)) ? it : std::begin(m))->second; \
2436  } \
2437  template<typename BasicJsonType> \
2438  inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
2439  { \
2440  static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
2441  static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__; \
2442  auto it = std::find_if(std::begin(m), std::end(m), \
2443  [&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
2444  { \
2445  return ej_pair.second == j; \
2446  }); \
2447  e = ((it != std::end(m)) ? it : std::begin(m))->first; \
2448  }
2449 
2450 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
2451 // may be removed in the future once the class is split.
2452 
2453 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \
2454  template<template<typename, typename, typename...> class ObjectType, \
2455  template<typename, typename...> class ArrayType, \
2456  class StringType, class BooleanType, class NumberIntegerType, \
2457  class NumberUnsignedType, class NumberFloatType, \
2458  template<typename> class AllocatorType, \
2459  template<typename, typename = void> class JSONSerializer, \
2460  class BinaryType>
2461 
2462 #define NLOHMANN_BASIC_JSON_TPL \
2463  basic_json<ObjectType, ArrayType, StringType, BooleanType, \
2464  NumberIntegerType, NumberUnsignedType, NumberFloatType, \
2465  AllocatorType, JSONSerializer, BinaryType>
2466 
2467 // Macros to simplify conversion from/to types
2468 
2469 #define NLOHMANN_JSON_EXPAND( x ) x
2470 #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
2471 #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \
2472  NLOHMANN_JSON_PASTE64, \
2473  NLOHMANN_JSON_PASTE63, \
2474  NLOHMANN_JSON_PASTE62, \
2475  NLOHMANN_JSON_PASTE61, \
2476  NLOHMANN_JSON_PASTE60, \
2477  NLOHMANN_JSON_PASTE59, \
2478  NLOHMANN_JSON_PASTE58, \
2479  NLOHMANN_JSON_PASTE57, \
2480  NLOHMANN_JSON_PASTE56, \
2481  NLOHMANN_JSON_PASTE55, \
2482  NLOHMANN_JSON_PASTE54, \
2483  NLOHMANN_JSON_PASTE53, \
2484  NLOHMANN_JSON_PASTE52, \
2485  NLOHMANN_JSON_PASTE51, \
2486  NLOHMANN_JSON_PASTE50, \
2487  NLOHMANN_JSON_PASTE49, \
2488  NLOHMANN_JSON_PASTE48, \
2489  NLOHMANN_JSON_PASTE47, \
2490  NLOHMANN_JSON_PASTE46, \
2491  NLOHMANN_JSON_PASTE45, \
2492  NLOHMANN_JSON_PASTE44, \
2493  NLOHMANN_JSON_PASTE43, \
2494  NLOHMANN_JSON_PASTE42, \
2495  NLOHMANN_JSON_PASTE41, \
2496  NLOHMANN_JSON_PASTE40, \
2497  NLOHMANN_JSON_PASTE39, \
2498  NLOHMANN_JSON_PASTE38, \
2499  NLOHMANN_JSON_PASTE37, \
2500  NLOHMANN_JSON_PASTE36, \
2501  NLOHMANN_JSON_PASTE35, \
2502  NLOHMANN_JSON_PASTE34, \
2503  NLOHMANN_JSON_PASTE33, \
2504  NLOHMANN_JSON_PASTE32, \
2505  NLOHMANN_JSON_PASTE31, \
2506  NLOHMANN_JSON_PASTE30, \
2507  NLOHMANN_JSON_PASTE29, \
2508  NLOHMANN_JSON_PASTE28, \
2509  NLOHMANN_JSON_PASTE27, \
2510  NLOHMANN_JSON_PASTE26, \
2511  NLOHMANN_JSON_PASTE25, \
2512  NLOHMANN_JSON_PASTE24, \
2513  NLOHMANN_JSON_PASTE23, \
2514  NLOHMANN_JSON_PASTE22, \
2515  NLOHMANN_JSON_PASTE21, \
2516  NLOHMANN_JSON_PASTE20, \
2517  NLOHMANN_JSON_PASTE19, \
2518  NLOHMANN_JSON_PASTE18, \
2519  NLOHMANN_JSON_PASTE17, \
2520  NLOHMANN_JSON_PASTE16, \
2521  NLOHMANN_JSON_PASTE15, \
2522  NLOHMANN_JSON_PASTE14, \
2523  NLOHMANN_JSON_PASTE13, \
2524  NLOHMANN_JSON_PASTE12, \
2525  NLOHMANN_JSON_PASTE11, \
2526  NLOHMANN_JSON_PASTE10, \
2527  NLOHMANN_JSON_PASTE9, \
2528  NLOHMANN_JSON_PASTE8, \
2529  NLOHMANN_JSON_PASTE7, \
2530  NLOHMANN_JSON_PASTE6, \
2531  NLOHMANN_JSON_PASTE5, \
2532  NLOHMANN_JSON_PASTE4, \
2533  NLOHMANN_JSON_PASTE3, \
2534  NLOHMANN_JSON_PASTE2, \
2535  NLOHMANN_JSON_PASTE1)(__VA_ARGS__))
2536 #define NLOHMANN_JSON_PASTE2(func, v1) func(v1)
2537 #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2)
2538 #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3)
2539 #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4)
2540 #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5)
2541 #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)
2542 #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)
2543 #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)
2544 #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)
2545 #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)
2546 #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)
2547 #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)
2548 #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)
2549 #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)
2550 #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)
2551 #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)
2552 #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)
2553 #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)
2554 #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)
2555 #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)
2556 #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)
2557 #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)
2558 #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)
2559 #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)
2560 #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)
2561 #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)
2562 #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)
2563 #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)
2564 #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)
2565 #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)
2566 #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)
2567 #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)
2568 #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)
2569 #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)
2570 #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)
2571 #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)
2572 #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)
2573 #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)
2574 #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)
2575 #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)
2576 #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)
2577 #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)
2578 #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)
2579 #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)
2580 #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)
2581 #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)
2582 #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)
2583 #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)
2584 #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)
2585 #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)
2586 #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)
2587 #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)
2588 #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)
2589 #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)
2590 #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)
2591 #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)
2592 #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)
2593 #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)
2594 #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)
2595 #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)
2596 #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)
2597 #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)
2598 #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)
2599 
2600 #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1;
2601 #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1);
2602 #define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1);
2603 
2609 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \
2610  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__)) } \
2611  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__)) }
2612 
2613 #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2614  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__)) } \
2615  friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2616 
2622 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
2623  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__)) } \
2624  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__)) }
2625 
2626 #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \
2627  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__)) } \
2628  inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { Type nlohmann_json_default_obj; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) }
2629 
2630 
2631 // inspired from https://stackoverflow.com/a/26745591
2632 // allows to call any std function as if (e.g. with begin):
2633 // using std::begin; begin(x);
2634 //
2635 // it allows using the detected idiom to retrieve the return type
2636 // of such an expression
2637 #define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \
2638  namespace detail { \
2639  using std::std_name; \
2640  \
2641  template<typename... T> \
2642  using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2643  } \
2644  \
2645  namespace detail2 { \
2646  struct std_name##_tag \
2647  { \
2648  }; \
2649  \
2650  template<typename... T> \
2651  std_name##_tag std_name(T&&...); \
2652  \
2653  template<typename... T> \
2654  using result_of_##std_name = decltype(std_name(std::declval<T>()...)); \
2655  \
2656  template<typename... T> \
2657  struct would_call_std_##std_name \
2658  { \
2659  static constexpr auto const value = ::nlohmann::detail:: \
2660  is_detected_exact<std_name##_tag, result_of_##std_name, T...>::value; \
2661  }; \
2662  } /* namespace detail2 */ \
2663  \
2664  template<typename... T> \
2665  struct would_call_std_##std_name : detail2::would_call_std_##std_name<T...> \
2666  { \
2667  }
2668 
2669 #ifndef JSON_USE_IMPLICIT_CONVERSIONS
2670  #define JSON_USE_IMPLICIT_CONVERSIONS 1
2671 #endif
2672 
2673 #if JSON_USE_IMPLICIT_CONVERSIONS
2674  #define JSON_EXPLICIT
2675 #else
2676  #define JSON_EXPLICIT explicit
2677 #endif
2678 
2679 #ifndef JSON_DIAGNOSTICS
2680  #define JSON_DIAGNOSTICS 0
2681 #endif
2682 
2683 #ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
2684  #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0
2685 #endif
2686 
2687 #ifndef JSON_DISABLE_ENUM_SERIALIZATION
2688  #define JSON_DISABLE_ENUM_SERIALIZATION 0
2689 #endif
2690 
2691 #if JSON_HAS_THREE_WAY_COMPARISON
2692  #include <compare> // partial_ordering
2693 #endif
2694 
2695 namespace nlohmann
2696 {
2697 namespace detail
2698 {
2700 // JSON type enumeration //
2702 
2727 enum class value_t : std::uint8_t
2728 {
2729  null,
2730  object,
2731  array,
2732  string,
2733  boolean,
2734  number_integer,
2735  number_unsigned,
2736  number_float,
2737  binary,
2738  discarded
2739 };
2740 
2754 #if JSON_HAS_THREE_WAY_COMPARISON
2755  inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD*
2756 #else
2757  inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2758 #endif
2759 {
2760  static constexpr std::array<std::uint8_t, 9> order = {{
2761  0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */,
2762  1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */,
2763  6 /* binary */
2764  }
2765  };
2766 
2767  const auto l_index = static_cast<std::size_t>(lhs);
2768  const auto r_index = static_cast<std::size_t>(rhs);
2769 #if JSON_HAS_THREE_WAY_COMPARISON
2770  if (l_index < order.size() && r_index < order.size())
2771  {
2772  return order[l_index] <=> order[r_index]; // *NOPAD*
2773  }
2774  return std::partial_ordering::unordered;
2775 #else
2776  return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index];
2777 #endif
2778 }
2779 
2780 // GCC selects the built-in operator< over an operator rewritten from
2781 // a user-defined spaceship operator
2782 // Clang, MSVC, and ICC select the rewritten candidate
2783 // (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200)
2784 #if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__)
2785 inline bool operator<(const value_t lhs, const value_t rhs) noexcept
2786 {
2787  return std::is_lt(lhs <=> rhs); // *NOPAD*
2788 }
2789 #endif
2790 } // namespace detail
2791 } // namespace nlohmann
2792 
2793 // #include <nlohmann/detail/string_escape.hpp>
2794 
2795 
2796 // #include <nlohmann/detail/macro_scope.hpp>
2797 
2798 
2799 namespace nlohmann
2800 {
2801 namespace detail
2802 {
2803 
2817 template<typename StringType>
2818 inline void replace_substring(StringType& s, const StringType& f,
2819  const StringType& t)
2820 {
2821  JSON_ASSERT(!f.empty());
2822  for (auto pos = s.find(f); // find first occurrence of f
2823  pos != StringType::npos; // make sure f was found
2824  s.replace(pos, f.size(), t), // replace with t, and
2825  pos = s.find(f, pos + t.size())) // find next occurrence of f
2826  {}
2827 }
2828 
2836 template<typename StringType>
2837 inline StringType escape(StringType s)
2838 {
2839  replace_substring(s, StringType{"~"}, StringType{"~0"});
2840  replace_substring(s, StringType{"/"}, StringType{"~1"});
2841  return s;
2842 }
2843 
2851 template<typename StringType>
2852 static void unescape(StringType& s)
2853 {
2854  replace_substring(s, StringType{"~1"}, StringType{"/"});
2855  replace_substring(s, StringType{"~0"}, StringType{"~"});
2856 }
2857 
2858 } // namespace detail
2859 } // namespace nlohmann
2860 
2861 // #include <nlohmann/detail/input/position_t.hpp>
2862 
2863 
2864 #include <cstddef> // size_t
2865 
2866 namespace nlohmann
2867 {
2868 namespace detail
2869 {
2872 {
2874  std::size_t chars_read_total = 0;
2876  std::size_t chars_read_current_line = 0;
2878  std::size_t lines_read = 0;
2879 
2881  constexpr operator size_t() const
2882  {
2883  return chars_read_total;
2884  }
2885 };
2886 
2887 } // namespace detail
2888 } // namespace nlohmann
2889 
2890 // #include <nlohmann/detail/macro_scope.hpp>
2891 
2892 // #include <nlohmann/detail/meta/cpp_future.hpp>
2893 
2894 
2895 #include <cstddef> // size_t
2896 #include <type_traits> // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type
2897 #include <utility> // index_sequence, make_index_sequence, index_sequence_for
2898 
2899 // #include <nlohmann/detail/macro_scope.hpp>
2900 
2901 
2902 namespace nlohmann
2903 {
2904 namespace detail
2905 {
2906 
2907 template<typename T>
2909 
2910 #ifdef JSON_HAS_CPP_14
2911 
2912 // the following utilities are natively available in C++14
2913 using std::enable_if_t;
2914 using std::index_sequence;
2917 
2918 #else
2919 
2920 // alias templates to reduce boilerplate
2921 template<bool B, typename T = void>
2923 
2924 // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h
2925 // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0.
2926 
2928 
2929 // integer_sequence
2930 //
2931 // Class template representing a compile-time integer sequence. An instantiation
2932 // of `integer_sequence<T, Ints...>` has a sequence of integers encoded in its
2933 // type through its template arguments (which is a common need when
2934 // working with C++11 variadic templates). `absl::integer_sequence` is designed
2935 // to be a drop-in replacement for C++14's `std::integer_sequence`.
2936 //
2937 // Example:
2938 //
2939 // template< class T, T... Ints >
2940 // void user_function(integer_sequence<T, Ints...>);
2941 //
2942 // int main()
2943 // {
2944 // // user_function's `T` will be deduced to `int` and `Ints...`
2945 // // will be deduced to `0, 1, 2, 3, 4`.
2946 // user_function(make_integer_sequence<int, 5>());
2947 // }
2948 template <typename T, T... Ints>
2950 {
2951  using value_type = T;
2952  static constexpr std::size_t size() noexcept
2953  {
2954  return sizeof...(Ints);
2955  }
2956 };
2957 
2958 // index_sequence
2959 //
2960 // A helper template for an `integer_sequence` of `size_t`,
2961 // `absl::index_sequence` is designed to be a drop-in replacement for C++14's
2962 // `std::index_sequence`.
2963 template <size_t... Ints>
2964 using index_sequence = integer_sequence<size_t, Ints...>;
2965 
2966 namespace utility_internal
2967 {
2968 
2969 template <typename Seq, size_t SeqSize, size_t Rem>
2970 struct Extend;
2971 
2972 // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency.
2973 template <typename T, T... Ints, size_t SeqSize>
2974 struct Extend<integer_sequence<T, Ints...>, SeqSize, 0>
2975 {
2976  using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >;
2977 };
2978 
2979 template <typename T, T... Ints, size_t SeqSize>
2980 struct Extend<integer_sequence<T, Ints...>, SeqSize, 1>
2981 {
2982  using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >;
2983 };
2984 
2985 // Recursion helper for 'make_integer_sequence<T, N>'.
2986 // 'Gen<T, N>::type' is an alias for 'integer_sequence<T, 0, 1, ... N-1>'.
2987 template <typename T, size_t N>
2988 struct Gen
2989 {
2990  using type =
2991  typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type;
2992 };
2993 
2994 template <typename T>
2995 struct Gen<T, 0>
2996 {
2998 };
2999 
3000 } // namespace utility_internal
3001 
3002 // Compile-time sequences of integers
3003 
3004 // make_integer_sequence
3005 //
3006 // This template alias is equivalent to
3007 // `integer_sequence<int, 0, 1, ..., N-1>`, and is designed to be a drop-in
3008 // replacement for C++14's `std::make_integer_sequence`.
3009 template <typename T, T N>
3011 
3012 // make_index_sequence
3013 //
3014 // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`,
3015 // and is designed to be a drop-in replacement for C++14's
3016 // `std::make_index_sequence`.
3017 template <size_t N>
3019 
3020 // index_sequence_for
3021 //
3022 // Converts a typename pack into an index sequence of the same length, and
3023 // is designed to be a drop-in replacement for C++14's
3024 // `std::index_sequence_for()`
3025 template <typename... Ts>
3027 
3029 
3030 #endif
3031 
3032 // dispatch utility (taken from ranges-v3)
3033 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
3034 template<> struct priority_tag<0> {};
3035 
3036 // taken from ranges-v3
3037 template<typename T>
3039 {
3040  static constexpr T value{};
3041 };
3042 
3043 #ifndef JSON_HAS_CPP_17
3044 
3045  template<typename T>
3046  constexpr T static_const<T>::value; // NOLINT(readability-redundant-declaration)
3047 
3048 #endif
3049 
3050 } // namespace detail
3051 } // namespace nlohmann
3052 
3053 // #include <nlohmann/detail/meta/type_traits.hpp>
3054 
3055 
3056 #include <limits> // numeric_limits
3057 #include <type_traits> // false_type, is_constructible, is_integral, is_same, true_type
3058 #include <utility> // declval
3059 #include <tuple> // tuple
3060 
3061 // #include <nlohmann/detail/macro_scope.hpp>
3062 
3063 
3064 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
3065 
3066 
3067 #include <iterator> // random_access_iterator_tag
3068 
3069 // #include <nlohmann/detail/meta/void_t.hpp>
3070 
3071 // #include <nlohmann/detail/meta/cpp_future.hpp>
3072 
3073 
3074 namespace nlohmann
3075 {
3076 namespace detail
3077 {
3078 template<typename It, typename = void>
3079 struct iterator_types {};
3080 
3081 template<typename It>
3083  It,
3084  void_t<typename It::difference_type, typename It::value_type, typename It::pointer,
3085  typename It::reference, typename It::iterator_category >>
3086 {
3087  using difference_type = typename It::difference_type;
3088  using value_type = typename It::value_type;
3089  using pointer = typename It::pointer;
3090  using reference = typename It::reference;
3091  using iterator_category = typename It::iterator_category;
3092 };
3093 
3094 // This is required as some compilers implement std::iterator_traits in a way that
3095 // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341.
3096 template<typename T, typename = void>
3098 {
3099 };
3100 
3101 template<typename T>
3102 struct iterator_traits < T, enable_if_t < !std::is_pointer<T>::value >>
3103  : iterator_types<T>
3104 {
3105 };
3106 
3107 template<typename T>
3109 {
3110  using iterator_category = std::random_access_iterator_tag;
3111  using value_type = T;
3112  using difference_type = ptrdiff_t;
3113  using pointer = T*;
3114  using reference = T&;
3115 };
3116 } // namespace detail
3117 } // namespace nlohmann
3118 
3119 // #include <nlohmann/detail/meta/call_std/begin.hpp>
3120 
3121 
3122 // #include <nlohmann/detail/macro_scope.hpp>
3123 
3124 
3125 namespace nlohmann
3126 {
3128 } // namespace nlohmann
3129 
3130 // #include <nlohmann/detail/meta/call_std/end.hpp>
3131 
3132 
3133 // #include <nlohmann/detail/macro_scope.hpp>
3134 
3135 
3136 namespace nlohmann
3137 {
3139 } // namespace nlohmann
3140 
3141 // #include <nlohmann/detail/meta/cpp_future.hpp>
3142 
3143 // #include <nlohmann/detail/meta/detected.hpp>
3144 
3145 // #include <nlohmann/json_fwd.hpp>
3146 #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_
3147 #define INCLUDE_NLOHMANN_JSON_FWD_HPP_
3148 
3149 #include <cstdint> // int64_t, uint64_t
3150 #include <map> // map
3151 #include <memory> // allocator
3152 #include <string> // string
3153 #include <vector> // vector
3154 
3160 namespace nlohmann
3161 {
3169 template<typename T = void, typename SFINAE = void>
3170 struct adl_serializer;
3171 
3174 template<template<typename U, typename V, typename... Args> class ObjectType =
3175  std::map,
3176  template<typename U, typename... Args> class ArrayType = std::vector,
3177  class StringType = std::string, class BooleanType = bool,
3178  class NumberIntegerType = std::int64_t,
3179  class NumberUnsignedType = std::uint64_t,
3180  class NumberFloatType = double,
3181  template<typename U> class AllocatorType = std::allocator,
3182  template<typename T, typename SFINAE = void> class JSONSerializer =
3183  adl_serializer,
3184  class BinaryType = std::vector<std::uint8_t>>
3185 class basic_json;
3186 
3189 template<typename BasicJsonType>
3190 class json_pointer;
3191 
3197 
3200 template<class Key, class T, class IgnoredLess, class Allocator>
3201 struct ordered_map;
3202 
3206 
3207 } // namespace nlohmann
3208 
3209 #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_
3210 
3211 
3212 namespace nlohmann
3213 {
3222 namespace detail
3223 {
3225 // helpers //
3227 
3228 // Note to maintainers:
3229 //
3230 // Every trait in this file expects a non CV-qualified type.
3231 // The only exceptions are in the 'aliases for detected' section
3232 // (i.e. those of the form: decltype(T::member_function(std::declval<T>())))
3233 //
3234 // In this case, T has to be properly CV-qualified to constraint the function arguments
3235 // (e.g. to_json(BasicJsonType&, const T&))
3236 
3237 template<typename> struct is_basic_json : std::false_type {};
3238 
3240 struct is_basic_json<NLOHMANN_BASIC_JSON_TPL> : std::true_type {};
3241 
3242 // used by exceptions create() member functions
3243 // true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t
3244 // false_type otherwise
3245 template<typename BasicJsonContext>
3247  std::integral_constant < bool,
3248  is_basic_json<typename std::remove_cv<typename std::remove_pointer<BasicJsonContext>::type>::type>::value
3249  || std::is_same<BasicJsonContext, std::nullptr_t>::value >
3250 {};
3251 
3253 // json_ref helpers //
3255 
3256 template<typename>
3257 class json_ref;
3258 
3259 template<typename>
3260 struct is_json_ref : std::false_type {};
3261 
3262 template<typename T>
3263 struct is_json_ref<json_ref<T>> : std::true_type {};
3264 
3266 // aliases for detected //
3268 
3269 template<typename T>
3270 using mapped_type_t = typename T::mapped_type;
3271 
3272 template<typename T>
3273 using key_type_t = typename T::key_type;
3274 
3275 template<typename T>
3276 using value_type_t = typename T::value_type;
3277 
3278 template<typename T>
3279 using difference_type_t = typename T::difference_type;
3280 
3281 template<typename T>
3282 using pointer_t = typename T::pointer;
3283 
3284 template<typename T>
3285 using reference_t = typename T::reference;
3286 
3287 template<typename T>
3288 using iterator_category_t = typename T::iterator_category;
3289 
3290 template<typename T, typename... Args>
3291 using to_json_function = decltype(T::to_json(std::declval<Args>()...));
3292 
3293 template<typename T, typename... Args>
3294 using from_json_function = decltype(T::from_json(std::declval<Args>()...));
3295 
3296 template<typename T, typename U>
3297 using get_template_function = decltype(std::declval<T>().template get<U>());
3298 
3299 // trait checking if JSONSerializer<T>::from_json(json const&, udt&) exists
3300 template<typename BasicJsonType, typename T, typename = void>
3301 struct has_from_json : std::false_type {};
3302 
3303 // trait checking if j.get<T> is valid
3304 // use this trait instead of std::is_constructible or std::is_convertible,
3305 // both rely on, or make use of implicit conversions, and thus fail when T
3306 // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958)
3307 template <typename BasicJsonType, typename T>
3309 {
3311 };
3312 
3313 template<typename BasicJsonType, typename T>
3314 struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3315 {
3316  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3317 
3318  static constexpr bool value =
3320  const BasicJsonType&, T&>::value;
3321 };
3322 
3323 // This trait checks if JSONSerializer<T>::from_json(json const&) exists
3324 // this overload is used for non-default-constructible user-defined-types
3325 template<typename BasicJsonType, typename T, typename = void>
3326 struct has_non_default_from_json : std::false_type {};
3327 
3328 template<typename BasicJsonType, typename T>
3329 struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3330 {
3331  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3332 
3333  static constexpr bool value =
3335  const BasicJsonType&>::value;
3336 };
3337 
3338 // This trait checks if BasicJsonType::json_serializer<T>::to_json exists
3339 // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion.
3340 template<typename BasicJsonType, typename T, typename = void>
3341 struct has_to_json : std::false_type {};
3342 
3343 template<typename BasicJsonType, typename T>
3344 struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json<T>::value >>
3345 {
3346  using serializer = typename BasicJsonType::template json_serializer<T, void>;
3347 
3348  static constexpr bool value =
3349  is_detected_exact<void, to_json_function, serializer, BasicJsonType&,
3350  T>::value;
3351 };
3352 
3353 template<typename T>
3354 using detect_key_compare = typename T::key_compare;
3355 
3356 template<typename T>
3357 struct has_key_compare : std::integral_constant<bool, is_detected<detect_key_compare, T>::value> {};
3358 
3359 // obtains the actual object key comparator
3360 template<typename BasicJsonType>
3362 {
3363  using object_t = typename BasicJsonType::object_t;
3364  using object_comparator_t = typename BasicJsonType::default_object_comparator_t;
3365  using type = typename std::conditional < has_key_compare<object_t>::value,
3366  typename object_t::key_compare, object_comparator_t>::type;
3367 };
3368 
3369 template<typename BasicJsonType>
3371 
3373 // is_ functions //
3375 
3376 // https://en.cppreference.com/w/cpp/types/conjunction
3377 template<class...> struct conjunction : std::true_type { };
3378 template<class B> struct conjunction<B> : B { };
3379 template<class B, class... Bn>
3380 struct conjunction<B, Bn...>
3381 : std::conditional<static_cast<bool>(B::value), conjunction<Bn...>, B>::type {};
3382 
3383 // https://en.cppreference.com/w/cpp/types/negation
3384 template<class B> struct negation : std::integral_constant < bool, !B::value > { };
3385 
3386 // Reimplementation of is_constructible and is_default_constructible, due to them being broken for
3387 // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367).
3388 // This causes compile errors in e.g. clang 3.5 or gcc 4.9.
3389 template <typename T>
3390 struct is_default_constructible : std::is_default_constructible<T> {};
3391 
3392 template <typename T1, typename T2>
3393 struct is_default_constructible<std::pair<T1, T2>>
3394  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3395 
3396 template <typename T1, typename T2>
3397 struct is_default_constructible<const std::pair<T1, T2>>
3398  : conjunction<is_default_constructible<T1>, is_default_constructible<T2>> {};
3399 
3400 template <typename... Ts>
3401 struct is_default_constructible<std::tuple<Ts...>>
3402  : conjunction<is_default_constructible<Ts>...> {};
3403 
3404 template <typename... Ts>
3405 struct is_default_constructible<const std::tuple<Ts...>>
3406  : conjunction<is_default_constructible<Ts>...> {};
3407 
3408 
3409 template <typename T, typename... Args>
3410 struct is_constructible : std::is_constructible<T, Args...> {};
3411 
3412 template <typename T1, typename T2>
3413 struct is_constructible<std::pair<T1, T2>> : is_default_constructible<std::pair<T1, T2>> {};
3414 
3415 template <typename T1, typename T2>
3416 struct is_constructible<const std::pair<T1, T2>> : is_default_constructible<const std::pair<T1, T2>> {};
3417 
3418 template <typename... Ts>
3419 struct is_constructible<std::tuple<Ts...>> : is_default_constructible<std::tuple<Ts...>> {};
3420 
3421 template <typename... Ts>
3422 struct is_constructible<const std::tuple<Ts...>> : is_default_constructible<const std::tuple<Ts...>> {};
3423 
3424 
3425 template<typename T, typename = void>
3426 struct is_iterator_traits : std::false_type {};
3427 
3428 template<typename T>
3430 {
3431  private:
3432  using traits = iterator_traits<T>;
3433 
3434  public:
3435  static constexpr auto value =
3441 };
3442 
3443 template<typename T>
3444 struct is_range
3445 {
3446  private:
3447  using t_ref = typename std::add_lvalue_reference<T>::type;
3448 
3449  using iterator = detected_t<result_of_begin, t_ref>;
3450  using sentinel = detected_t<result_of_end, t_ref>;
3451 
3452  // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator
3453  // and https://en.cppreference.com/w/cpp/iterator/sentinel_for
3454  // but reimplementing these would be too much work, as a lot of other concepts are used underneath
3455  static constexpr auto is_iterator_begin =
3457 
3458  public:
3459  static constexpr bool value = !std::is_same<iterator, nonesuch>::value && !std::is_same<sentinel, nonesuch>::value && is_iterator_begin;
3460 };
3461 
3462 template<typename R>
3463 using iterator_t = enable_if_t<is_range<R>::value, result_of_begin<decltype(std::declval<R&>())>>;
3464 
3465 template<typename T>
3467 
3468 // The following implementation of is_complete_type is taken from
3469 // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/
3470 // and is written by Xiang Fan who agreed to using it in this library.
3471 
3472 template<typename T, typename = void>
3473 struct is_complete_type : std::false_type {};
3474 
3475 template<typename T>
3476 struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {};
3477 
3478 template<typename BasicJsonType, typename CompatibleObjectType,
3479  typename = void>
3480 struct is_compatible_object_type_impl : std::false_type {};
3481 
3482 template<typename BasicJsonType, typename CompatibleObjectType>
3484  BasicJsonType, CompatibleObjectType,
3485  enable_if_t < is_detected<mapped_type_t, CompatibleObjectType>::value&&
3486  is_detected<key_type_t, CompatibleObjectType>::value >>
3487 {
3488  using object_t = typename BasicJsonType::object_t;
3489 
3490  // macOS's is_constructible does not play well with nonesuch...
3491  static constexpr bool value =
3492  is_constructible<typename object_t::key_type,
3493  typename CompatibleObjectType::key_type>::value &&
3494  is_constructible<typename object_t::mapped_type,
3495  typename CompatibleObjectType::mapped_type>::value;
3496 };
3497 
3498 template<typename BasicJsonType, typename CompatibleObjectType>
3500  : is_compatible_object_type_impl<BasicJsonType, CompatibleObjectType> {};
3501 
3502 template<typename BasicJsonType, typename ConstructibleObjectType,
3503  typename = void>
3504 struct is_constructible_object_type_impl : std::false_type {};
3505 
3506 template<typename BasicJsonType, typename ConstructibleObjectType>
3508  BasicJsonType, ConstructibleObjectType,
3509  enable_if_t < is_detected<mapped_type_t, ConstructibleObjectType>::value&&
3510  is_detected<key_type_t, ConstructibleObjectType>::value >>
3511 {
3512  using object_t = typename BasicJsonType::object_t;
3513 
3514  static constexpr bool value =
3516  (std::is_move_assignable<ConstructibleObjectType>::value ||
3517  std::is_copy_assignable<ConstructibleObjectType>::value) &&
3518  (is_constructible<typename ConstructibleObjectType::key_type,
3519  typename object_t::key_type>::value &&
3520  std::is_same <
3521  typename object_t::mapped_type,
3522  typename ConstructibleObjectType::mapped_type >::value)) ||
3523  (has_from_json<BasicJsonType,
3524  typename ConstructibleObjectType::mapped_type>::value ||
3526  BasicJsonType,
3527  typename ConstructibleObjectType::mapped_type >::value);
3528 };
3529 
3530 template<typename BasicJsonType, typename ConstructibleObjectType>
3532  : is_constructible_object_type_impl<BasicJsonType,
3533  ConstructibleObjectType> {};
3534 
3535 template<typename BasicJsonType, typename CompatibleStringType>
3537 {
3538  static constexpr auto value =
3540 };
3541 
3542 template<typename BasicJsonType, typename ConstructibleStringType>
3544 {
3545  // launder type through decltype() to fix compilation failure on ICPC
3546 #ifdef __INTEL_COMPILER
3547  using laundered_type = decltype(std::declval<ConstructibleStringType>());
3548 #else
3549  using laundered_type = ConstructibleStringType;
3550 #endif
3551 
3552  static constexpr auto value =
3554  typename BasicJsonType::string_t>::value;
3555 };
3556 
3557 template<typename BasicJsonType, typename CompatibleArrayType, typename = void>
3558 struct is_compatible_array_type_impl : std::false_type {};
3559 
3560 template<typename BasicJsonType, typename CompatibleArrayType>
3562  BasicJsonType, CompatibleArrayType,
3563  enable_if_t <
3564  is_detected<iterator_t, CompatibleArrayType>::value&&
3565  is_iterator_traits<iterator_traits<detected_t<iterator_t, CompatibleArrayType>>>::value&&
3566 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3567 // c.f. https://github.com/nlohmann/json/pull/3073
3568  !std::is_same<CompatibleArrayType, detected_t<range_value_t, CompatibleArrayType>>::value >>
3569 {
3570  static constexpr bool value =
3571  is_constructible<BasicJsonType,
3573 };
3574 
3575 template<typename BasicJsonType, typename CompatibleArrayType>
3577  : is_compatible_array_type_impl<BasicJsonType, CompatibleArrayType> {};
3578 
3579 template<typename BasicJsonType, typename ConstructibleArrayType, typename = void>
3580 struct is_constructible_array_type_impl : std::false_type {};
3581 
3582 template<typename BasicJsonType, typename ConstructibleArrayType>
3584  BasicJsonType, ConstructibleArrayType,
3585  enable_if_t<std::is_same<ConstructibleArrayType,
3586  typename BasicJsonType::value_type>::value >>
3587  : std::true_type {};
3588 
3589 template<typename BasicJsonType, typename ConstructibleArrayType>
3591  BasicJsonType, ConstructibleArrayType,
3592  enable_if_t < !std::is_same<ConstructibleArrayType,
3593  typename BasicJsonType::value_type>::value&&
3594  !is_compatible_string_type<BasicJsonType, ConstructibleArrayType>::value&&
3595  is_default_constructible<ConstructibleArrayType>::value&&
3596 (std::is_move_assignable<ConstructibleArrayType>::value ||
3597  std::is_copy_assignable<ConstructibleArrayType>::value)&&
3598 is_detected<iterator_t, ConstructibleArrayType>::value&&
3599 is_iterator_traits<iterator_traits<detected_t<iterator_t, ConstructibleArrayType>>>::value&&
3600 is_detected<range_value_t, ConstructibleArrayType>::value&&
3601 // special case for types like std::filesystem::path whose iterator's value_type are themselves
3602 // c.f. https://github.com/nlohmann/json/pull/3073
3603 !std::is_same<ConstructibleArrayType, detected_t<range_value_t, ConstructibleArrayType>>::value&&
3605  detected_t<range_value_t, ConstructibleArrayType >>::value >>
3606 {
3608 
3609  static constexpr bool value =
3610  std::is_same<value_type,
3611  typename BasicJsonType::array_t::value_type>::value ||
3612  has_from_json<BasicJsonType,
3613  value_type>::value ||
3615  BasicJsonType,
3616  value_type >::value;
3617 };
3618 
3619 template<typename BasicJsonType, typename ConstructibleArrayType>
3621  : is_constructible_array_type_impl<BasicJsonType, ConstructibleArrayType> {};
3622 
3623 template<typename RealIntegerType, typename CompatibleNumberIntegerType,
3624  typename = void>
3625 struct is_compatible_integer_type_impl : std::false_type {};
3626 
3627 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3629  RealIntegerType, CompatibleNumberIntegerType,
3630  enable_if_t < std::is_integral<RealIntegerType>::value&&
3631  std::is_integral<CompatibleNumberIntegerType>::value&&
3632  !std::is_same<bool, CompatibleNumberIntegerType>::value >>
3633 {
3634  // is there an assert somewhere on overflows?
3635  using RealLimits = std::numeric_limits<RealIntegerType>;
3636  using CompatibleLimits = std::numeric_limits<CompatibleNumberIntegerType>;
3637 
3638  static constexpr auto value =
3639  is_constructible<RealIntegerType,
3640  CompatibleNumberIntegerType>::value &&
3641  CompatibleLimits::is_integer &&
3642  RealLimits::is_signed == CompatibleLimits::is_signed;
3643 };
3644 
3645 template<typename RealIntegerType, typename CompatibleNumberIntegerType>
3647  : is_compatible_integer_type_impl<RealIntegerType,
3648  CompatibleNumberIntegerType> {};
3649 
3650 template<typename BasicJsonType, typename CompatibleType, typename = void>
3651 struct is_compatible_type_impl: std::false_type {};
3652 
3653 template<typename BasicJsonType, typename CompatibleType>
3655  BasicJsonType, CompatibleType,
3656  enable_if_t<is_complete_type<CompatibleType>::value >>
3657 {
3658  static constexpr bool value =
3660 };
3661 
3662 template<typename BasicJsonType, typename CompatibleType>
3664  : is_compatible_type_impl<BasicJsonType, CompatibleType> {};
3665 
3666 template<typename T1, typename T2>
3667 struct is_constructible_tuple : std::false_type {};
3668 
3669 template<typename T1, typename... Args>
3670 struct is_constructible_tuple<T1, std::tuple<Args...>> : conjunction<is_constructible<T1, Args>...> {};
3671 
3672 template<typename BasicJsonType, typename T>
3673 struct is_json_iterator_of : std::false_type {};
3674 
3675 template<typename BasicJsonType>
3676 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::iterator> : std::true_type {};
3677 
3678 template<typename BasicJsonType>
3679 struct is_json_iterator_of<BasicJsonType, typename BasicJsonType::const_iterator> : std::true_type
3680 {};
3681 
3682 // checks if a given type T is a template specialization of Primary
3683 template<template <typename...> class Primary, typename T>
3684 struct is_specialization_of : std::false_type {};
3685 
3686 template<template <typename...> class Primary, typename... Args>
3687 struct is_specialization_of<Primary, Primary<Args...>> : std::true_type {};
3688 
3689 template<typename T>
3691 
3692 // checks if A and B are comparable using Compare functor
3693 template<typename Compare, typename A, typename B, typename = void>
3694 struct is_comparable : std::false_type {};
3695 
3696 template<typename Compare, typename A, typename B>
3697 struct is_comparable<Compare, A, B, void_t<
3698 decltype(std::declval<Compare>()(std::declval<A>(), std::declval<B>())),
3699 decltype(std::declval<Compare>()(std::declval<B>(), std::declval<A>()))
3700 >> : std::true_type {};
3701 
3702 template<typename T>
3703 using detect_is_transparent = typename T::is_transparent;
3704 
3705 // type trait to check if KeyType can be used as object key (without a BasicJsonType)
3706 // see is_usable_as_basic_json_key_type below
3707 template<typename Comparator, typename ObjectKeyType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3708  bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3709 using is_usable_as_key_type = typename std::conditional <
3711  && !(ExcludeObjectKeyType && std::is_same<KeyType,
3712  ObjectKeyType>::value)
3713  && (!RequireTransparentComparator
3716  std::true_type,
3717  std::false_type >::type;
3718 
3719 // type trait to check if KeyType can be used as object key
3720 // true if:
3721 // - KeyType is comparable with BasicJsonType::object_t::key_type
3722 // - if ExcludeObjectKeyType is true, KeyType is not BasicJsonType::object_t::key_type
3723 // - the comparator is transparent or RequireTransparentComparator is false
3724 // - KeyType is not a JSON iterator or json_pointer
3725 template<typename BasicJsonType, typename KeyTypeCVRef, bool RequireTransparentComparator = true,
3726  bool ExcludeObjectKeyType = RequireTransparentComparator, typename KeyType = uncvref_t<KeyTypeCVRef>>
3727 using is_usable_as_basic_json_key_type = typename std::conditional <
3728  is_usable_as_key_type<typename BasicJsonType::object_comparator_t,
3729  typename BasicJsonType::object_t::key_type, KeyTypeCVRef,
3730  RequireTransparentComparator, ExcludeObjectKeyType>::value
3732  std::true_type,
3733  std::false_type >::type;
3734 
3735 template<typename ObjectType, typename KeyType>
3736 using detect_erase_with_key_type = decltype(std::declval<ObjectType&>().erase(std::declval<KeyType>()));
3737 
3738 // type trait to check if object_t has an erase() member functions accepting KeyType
3739 template<typename BasicJsonType, typename KeyType>
3740 using has_erase_with_key_type = typename std::conditional <
3741  is_detected <
3743  typename BasicJsonType::object_t, KeyType >::value,
3744  std::true_type,
3745  std::false_type >::type;
3746 
3747 // a naive helper to check if a type is an ordered_map (exploits the fact that
3748 // ordered_map inherits capacity() from std::vector)
3749 template <typename T>
3751 {
3752  using one = char;
3753 
3754  struct two
3755  {
3756  char x[2]; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
3757  };
3758 
3759  template <typename C> static one test( decltype(&C::capacity) ) ;
3760  template <typename C> static two test(...);
3761 
3762  enum { value = sizeof(test<T>(nullptr)) == sizeof(char) }; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
3763 };
3764 
3765 // to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
3766 template < typename T, typename U, enable_if_t < !std::is_same<T, U>::value, int > = 0 >
3768 {
3769  return static_cast<T>(value);
3770 }
3771 
3772 template<typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
3773 T conditional_static_cast(U value)
3774 {
3775  return value;
3776 }
3777 
3778 template<typename... Types>
3780 
3781 template<typename... Types>
3783 
3784 template<typename... Types>
3786 
3787 // there's a disjunction trait in another PR; replace when merged
3788 template<typename... Types>
3789 using same_sign = std::integral_constant < bool,
3790  all_signed<Types...>::value || all_unsigned<Types...>::value >;
3791 
3792 template<typename OfType, typename T>
3793 using never_out_of_range = std::integral_constant < bool,
3794  (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
3795  || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
3796 
3797 template<typename OfType, typename T,
3798  bool OfTypeSigned = std::is_signed<OfType>::value,
3799  bool TSigned = std::is_signed<T>::value>
3801 
3802 template<typename OfType, typename T>
3803 struct value_in_range_of_impl2<OfType, T, false, false>
3804 {
3805  static constexpr bool test(T val)
3806  {
3807  using CommonType = typename std::common_type<OfType, T>::type;
3808  return static_cast<CommonType>(val) <= static_cast<CommonType>(std::numeric_limits<OfType>::max());
3809  }
3810 };
3811 
3812 template<typename OfType, typename T>
3813 struct value_in_range_of_impl2<OfType, T, true, false>
3814 {
3815  static constexpr bool test(T val)
3816  {
3817  using CommonType = typename std::common_type<OfType, T>::type;
3818  return static_cast<CommonType>(val) <= static_cast<CommonType>(std::numeric_limits<OfType>::max());
3819  }
3820 };
3821 
3822 template<typename OfType, typename T>
3823 struct value_in_range_of_impl2<OfType, T, false, true>
3824 {
3825  static constexpr bool test(T val)
3826  {
3827  using CommonType = typename std::common_type<OfType, T>::type;
3828  return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>(std::numeric_limits<OfType>::max());
3829  }
3830 };
3831 
3832 
3833 template<typename OfType, typename T>
3834 struct value_in_range_of_impl2<OfType, T, true, true>
3835 {
3836  static constexpr bool test(T val)
3837  {
3838  using CommonType = typename std::common_type<OfType, T>::type;
3839  return static_cast<CommonType>(val) >= static_cast<CommonType>(std::numeric_limits<OfType>::min())
3840  && static_cast<CommonType>(val) <= static_cast<CommonType>(std::numeric_limits<OfType>::max());
3841  }
3842 };
3843 
3844 template<typename OfType, typename T,
3845  bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
3848 
3849 template<typename OfType, typename T>
3850 struct value_in_range_of_impl1<OfType, T, false>
3851 {
3852  static constexpr bool test(T val)
3853  {
3855  }
3856 };
3857 
3858 template<typename OfType, typename T>
3859 struct value_in_range_of_impl1<OfType, T, true>
3860 {
3861  static constexpr bool test(T /*val*/)
3862  {
3863  return true;
3864  }
3865 };
3866 
3867 template<typename OfType, typename T>
3868 inline constexpr bool value_in_range_of(T val)
3869 {
3871 }
3872 
3873 } // namespace detail
3874 } // namespace nlohmann
3875 
3876 // #include <nlohmann/detail/string_concat.hpp>
3877 
3878 
3879 #include <cstring> // strlen
3880 #include <string> // string
3881 #include <utility> // forward
3882 
3883 // #include <nlohmann/detail/meta/cpp_future.hpp>
3884 
3885 // #include <nlohmann/detail/meta/detected.hpp>
3886 
3887 
3888 namespace nlohmann
3889 {
3890 namespace detail
3891 {
3892 
3893 inline std::size_t concat_length()
3894 {
3895  return 0;
3896 }
3897 
3898 template<typename... Args>
3899 inline std::size_t concat_length(const char* cstr, Args&& ... rest);
3900 
3901 template<typename StringType, typename... Args>
3902 inline std::size_t concat_length(const StringType& str, Args&& ... rest);
3903 
3904 template<typename... Args>
3905 inline std::size_t concat_length(const char /*c*/, Args&& ... rest)
3906 {
3907  return 1 + concat_length(std::forward<Args>(rest)...);
3908 }
3909 
3910 template<typename... Args>
3911 inline std::size_t concat_length(const char* cstr, Args&& ... rest)
3912 {
3913  // cppcheck-suppress ignoredReturnValue
3914  return ::strlen(cstr) + concat_length(std::forward<Args>(rest)...);
3915 }
3916 
3917 template<typename StringType, typename... Args>
3918 inline std::size_t concat_length(const StringType& str, Args&& ... rest)
3919 {
3920  return str.size() + concat_length(std::forward<Args>(rest)...);
3921 }
3922 
3923 template<typename OutStringType>
3924 inline void concat_into(OutStringType& /*out*/)
3925 {}
3926 
3927 template<typename StringType, typename Arg>
3928 using string_can_append = decltype(std::declval<StringType&>().append(std::declval < Arg && > ()));
3929 
3930 template<typename StringType, typename Arg>
3932 
3933 template<typename StringType, typename Arg>
3934 using string_can_append_op = decltype(std::declval<StringType&>() += std::declval < Arg && > ());
3935 
3936 template<typename StringType, typename Arg>
3938 
3939 template<typename StringType, typename Arg>
3940 using string_can_append_iter = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().begin(), std::declval<const Arg&>().end()));
3941 
3942 template<typename StringType, typename Arg>
3944 
3945 template<typename StringType, typename Arg>
3946 using string_can_append_data = decltype(std::declval<StringType&>().append(std::declval<const Arg&>().data(), std::declval<const Arg&>().size()));
3947 
3948 template<typename StringType, typename Arg>
3950 
3951 template < typename OutStringType, typename Arg, typename... Args,
3954 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest);
3955 
3956 template < typename OutStringType, typename Arg, typename... Args,
3960 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
3961 
3962 template < typename OutStringType, typename Arg, typename... Args,
3967 inline void concat_into(OutStringType& out, const Arg& arg, Args && ... rest);
3968 
3969 template<typename OutStringType, typename Arg, typename... Args,
3971 inline void concat_into(OutStringType& out, Arg && arg, Args && ... rest)
3972 {
3973  out.append(std::forward<Arg>(arg));
3974  concat_into(out, std::forward<Args>(rest)...);
3975 }
3976 
3977 template < typename OutStringType, typename Arg, typename... Args,
3978  enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3979  && detect_string_can_append_op<OutStringType, Arg>::value, int > >
3980 inline void concat_into(OutStringType& out, Arg&& arg, Args&& ... rest)
3981 {
3982  out += std::forward<Arg>(arg);
3983  concat_into(out, std::forward<Args>(rest)...);
3984 }
3985 
3986 template < typename OutStringType, typename Arg, typename... Args,
3987  enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3988  && !detect_string_can_append_op<OutStringType, Arg>::value
3989  && detect_string_can_append_iter<OutStringType, Arg>::value, int > >
3990 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
3991 {
3992  out.append(arg.begin(), arg.end());
3993  concat_into(out, std::forward<Args>(rest)...);
3994 }
3995 
3996 template < typename OutStringType, typename Arg, typename... Args,
3997  enable_if_t < !detect_string_can_append<OutStringType, Arg>::value
3998  && !detect_string_can_append_op<OutStringType, Arg>::value
3999  && !detect_string_can_append_iter<OutStringType, Arg>::value
4000  && detect_string_can_append_data<OutStringType, Arg>::value, int > >
4001 inline void concat_into(OutStringType& out, const Arg& arg, Args&& ... rest)
4002 {
4003  out.append(arg.data(), arg.size());
4004  concat_into(out, std::forward<Args>(rest)...);
4005 }
4006 
4007 template<typename OutStringType = std::string, typename... Args>
4008 inline OutStringType concat(Args && ... args)
4009 {
4010  OutStringType str;
4011  str.reserve(concat_length(std::forward<Args>(args)...));
4012  concat_into(str, std::forward<Args>(args)...);
4013  return str;
4014 }
4015 
4016 } // namespace detail
4017 } // namespace nlohmann
4018 
4019 
4020 
4021 namespace nlohmann
4022 {
4023 namespace detail
4024 {
4026 // exceptions //
4028 
4031 class exception : public std::exception
4032 {
4033  public:
4035  const char* what() const noexcept override
4036  {
4037  return m.what();
4038  }
4039 
4041  const int id; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
4042 
4043  protected:
4045  exception(int id_, const char* what_arg) : id(id_), m(what_arg) {} // NOLINT(bugprone-throw-keyword-missing)
4046 
4047  static std::string name(const std::string& ename, int id_)
4048  {
4049  return concat("[json.exception.", ename, '.', std::to_string(id_), "] ");
4050  }
4051 
4052  static std::string diagnostics(std::nullptr_t /*leaf_element*/)
4053  {
4054  return "";
4055  }
4056 
4057  template<typename BasicJsonType>
4058  static std::string diagnostics(const BasicJsonType* leaf_element)
4059  {
4060 #if JSON_DIAGNOSTICS
4061  std::vector<std::string> tokens;
4062  for (const auto* current = leaf_element; current != nullptr && current->m_parent != nullptr; current = current->m_parent)
4063  {
4064  switch (current->m_parent->type())
4065  {
4066  case value_t::array:
4067  {
4068  for (std::size_t i = 0; i < current->m_parent->m_value.array->size(); ++i)
4069  {
4070  if (&current->m_parent->m_value.array->operator[](i) == current)
4071  {
4072  tokens.emplace_back(std::to_string(i));
4073  break;
4074  }
4075  }
4076  break;
4077  }
4078 
4079  case value_t::object:
4080  {
4081  for (const auto& element : *current->m_parent->m_value.object)
4082  {
4083  if (&element.second == current)
4084  {
4085  tokens.emplace_back(element.first.c_str());
4086  break;
4087  }
4088  }
4089  break;
4090  }
4091 
4092  case value_t::null: // LCOV_EXCL_LINE
4093  case value_t::string: // LCOV_EXCL_LINE
4094  case value_t::boolean: // LCOV_EXCL_LINE
4095  case value_t::number_integer: // LCOV_EXCL_LINE
4096  case value_t::number_unsigned: // LCOV_EXCL_LINE
4097  case value_t::number_float: // LCOV_EXCL_LINE
4098  case value_t::binary: // LCOV_EXCL_LINE
4099  case value_t::discarded: // LCOV_EXCL_LINE
4100  default: // LCOV_EXCL_LINE
4101  break; // LCOV_EXCL_LINE
4102  }
4103  }
4104 
4105  if (tokens.empty())
4106  {
4107  return "";
4108  }
4109 
4110  auto str = std::accumulate(tokens.rbegin(), tokens.rend(), std::string{},
4111  [](const std::string & a, const std::string & b)
4112  {
4113  return concat(a, '/', detail::escape(b));
4114  });
4115  return concat('(', str, ") ");
4116 #else
4117  static_cast<void>(leaf_element);
4118  return "";
4119 #endif
4120  }
4121 
4122  private:
4124  std::runtime_error m;
4125 };
4126 
4129 class parse_error : public exception
4130 {
4131  public:
4141  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4142  static parse_error create(int id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
4143  {
4144  std::string w = concat(exception::name("parse_error", id_), "parse error",
4145  position_string(pos), ": ", exception::diagnostics(context), what_arg);
4146  return {id_, pos.chars_read_total, w.c_str()};
4147  }
4148 
4149  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4150  static parse_error create(int id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
4151  {
4152  std::string w = concat(exception::name("parse_error", id_), "parse error",
4153  (byte_ != 0 ? (concat(" at byte ", std::to_string(byte_))) : ""),
4154  ": ", exception::diagnostics(context), what_arg);
4155  return {id_, byte_, w.c_str()};
4156  }
4157 
4167  const std::size_t byte;
4168 
4169  private:
4170  parse_error(int id_, std::size_t byte_, const char* what_arg)
4171  : exception(id_, what_arg), byte(byte_) {}
4172 
4173  static std::string position_string(const position_t& pos)
4174  {
4175  return concat(" at line ", std::to_string(pos.lines_read + 1),
4176  ", column ", std::to_string(pos.chars_read_current_line));
4177  }
4178 };
4179 
4183 {
4184  public:
4185  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4186  static invalid_iterator create(int id_, const std::string& what_arg, BasicJsonContext context)
4187  {
4188  std::string w = concat(exception::name("invalid_iterator", id_), exception::diagnostics(context), what_arg);
4189  return {id_, w.c_str()};
4190  }
4191 
4192  private:
4194  invalid_iterator(int id_, const char* what_arg)
4195  : exception(id_, what_arg) {}
4196 };
4197 
4200 class type_error : public exception
4201 {
4202  public:
4203  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4204  static type_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4205  {
4206  std::string w = concat(exception::name("type_error", id_), exception::diagnostics(context), what_arg);
4207  return {id_, w.c_str()};
4208  }
4209 
4210  private:
4212  type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4213 };
4214 
4217 class out_of_range : public exception
4218 {
4219  public:
4220  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4221  static out_of_range create(int id_, const std::string& what_arg, BasicJsonContext context)
4222  {
4223  std::string w = concat(exception::name("out_of_range", id_), exception::diagnostics(context), what_arg);
4224  return {id_, w.c_str()};
4225  }
4226 
4227  private:
4229  out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
4230 };
4231 
4234 class other_error : public exception
4235 {
4236  public:
4237  template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
4238  static other_error create(int id_, const std::string& what_arg, BasicJsonContext context)
4239  {
4240  std::string w = concat(exception::name("other_error", id_), exception::diagnostics(context), what_arg);
4241  return {id_, w.c_str()};
4242  }
4243 
4244  private:
4246  other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
4247 };
4248 
4249 } // namespace detail
4250 } // namespace nlohmann
4251 
4252 // #include <nlohmann/detail/macro_scope.hpp>
4253 
4254 // #include <nlohmann/detail/meta/cpp_future.hpp>
4255 
4256 // #include <nlohmann/detail/meta/identity_tag.hpp>
4257 
4258 
4259 namespace nlohmann
4260 {
4261 namespace detail
4262 {
4263 // dispatching helper struct
4264 template <class T> struct identity_tag {};
4265 } // namespace detail
4266 } // namespace nlohmann
4267 
4268 // #include <nlohmann/detail/meta/type_traits.hpp>
4269 
4270 // #include <nlohmann/detail/string_concat.hpp>
4271 
4272 // #include <nlohmann/detail/value_t.hpp>
4273 
4274 
4275 #if JSON_HAS_EXPERIMENTAL_FILESYSTEM
4276 #include <experimental/filesystem>
4277 namespace nlohmann::detail
4278 {
4279 namespace std_fs = std::experimental::filesystem;
4280 } // namespace nlohmann::detail
4281 #elif JSON_HAS_FILESYSTEM
4282 #include <filesystem>
4283 namespace nlohmann::detail
4284 {
4285 namespace std_fs = std::filesystem;
4286 } // namespace nlohmann::detail
4287 #endif
4288 
4289 namespace nlohmann
4290 {
4291 namespace detail
4292 {
4293 template<typename BasicJsonType>
4294 inline void from_json(const BasicJsonType& j, typename std::nullptr_t& n)
4295 {
4296  if (JSON_HEDLEY_UNLIKELY(!j.is_null()))
4297  {
4298  JSON_THROW(type_error::create(302, concat("type must be null, but is ", j.type_name()), &j));
4299  }
4300  n = nullptr;
4301 }
4302 
4303 // overloads for basic_json template parameters
4304 template < typename BasicJsonType, typename ArithmeticType,
4305  enable_if_t < std::is_arithmetic<ArithmeticType>::value&&
4306  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4307  int > = 0 >
4308 void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val)
4309 {
4310  switch (static_cast<value_t>(j))
4311  {
4313  {
4314  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4315  break;
4316  }
4318  {
4319  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4320  break;
4321  }
4322  case value_t::number_float:
4323  {
4324  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4325  break;
4326  }
4327 
4328  case value_t::null:
4329  case value_t::object:
4330  case value_t::array:
4331  case value_t::string:
4332  case value_t::boolean:
4333  case value_t::binary:
4334  case value_t::discarded:
4335  default:
4336  JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4337  }
4338 }
4339 
4340 template<typename BasicJsonType>
4341 inline void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b)
4342 {
4343  if (JSON_HEDLEY_UNLIKELY(!j.is_boolean()))
4344  {
4345  JSON_THROW(type_error::create(302, concat("type must be boolean, but is ", j.type_name()), &j));
4346  }
4347  b = *j.template get_ptr<const typename BasicJsonType::boolean_t*>();
4348 }
4349 
4350 template<typename BasicJsonType>
4351 inline void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s)
4352 {
4353  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4354  {
4355  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4356  }
4357  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4358 }
4359 
4360 template <
4361  typename BasicJsonType, typename StringType,
4362  enable_if_t <
4363  std::is_assignable<StringType&, const typename BasicJsonType::string_t>::value
4364  && !std::is_same<typename BasicJsonType::string_t, StringType>::value
4365  && !is_json_ref<StringType>::value, int > = 0 >
4366 inline void from_json(const BasicJsonType& j, StringType& s)
4367 {
4368  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4369  {
4370  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4371  }
4372 
4373  s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4374 }
4375 
4376 template<typename BasicJsonType>
4377 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val)
4378 {
4379  get_arithmetic_value(j, val);
4380 }
4381 
4382 template<typename BasicJsonType>
4383 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val)
4384 {
4385  get_arithmetic_value(j, val);
4386 }
4387 
4388 template<typename BasicJsonType>
4389 inline void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val)
4390 {
4391  get_arithmetic_value(j, val);
4392 }
4393 
4394 #if !JSON_DISABLE_ENUM_SERIALIZATION
4395 template<typename BasicJsonType, typename EnumType,
4396  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
4397 inline void from_json(const BasicJsonType& j, EnumType& e)
4398 {
4400  get_arithmetic_value(j, val);
4401  e = static_cast<EnumType>(val);
4402 }
4403 #endif // JSON_DISABLE_ENUM_SERIALIZATION
4404 
4405 // forward_list doesn't have an insert method
4406 template<typename BasicJsonType, typename T, typename Allocator,
4407  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4408 inline void from_json(const BasicJsonType& j, std::forward_list<T, Allocator>& l)
4409 {
4410  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4411  {
4412  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4413  }
4414  l.clear();
4415  std::transform(j.rbegin(), j.rend(),
4416  std::front_inserter(l), [](const BasicJsonType & i)
4417  {
4418  return i.template get<T>();
4419  });
4420 }
4421 
4422 // valarray doesn't have an insert method
4423 template<typename BasicJsonType, typename T,
4424  enable_if_t<is_getable<BasicJsonType, T>::value, int> = 0>
4425 inline void from_json(const BasicJsonType& j, std::valarray<T>& l)
4426 {
4427  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4428  {
4429  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4430  }
4431  l.resize(j.size());
4432  std::transform(j.begin(), j.end(), std::begin(l),
4433  [](const BasicJsonType & elem)
4434  {
4435  return elem.template get<T>();
4436  });
4437 }
4438 
4439 template<typename BasicJsonType, typename T, std::size_t N>
4440 auto from_json(const BasicJsonType& j, T (&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
4441 -> decltype(j.template get<T>(), void())
4442 {
4443  for (std::size_t i = 0; i < N; ++i)
4444  {
4445  arr[i] = j.at(i).template get<T>();
4446  }
4447 }
4448 
4449 template<typename BasicJsonType>
4450 inline void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
4451 {
4452  arr = *j.template get_ptr<const typename BasicJsonType::array_t*>();
4453 }
4454 
4455 template<typename BasicJsonType, typename T, std::size_t N>
4456 auto from_json_array_impl(const BasicJsonType& j, std::array<T, N>& arr,
4457  priority_tag<2> /*unused*/)
4458 -> decltype(j.template get<T>(), void())
4459 {
4460  for (std::size_t i = 0; i < N; ++i)
4461  {
4462  arr[i] = j.at(i).template get<T>();
4463  }
4464 }
4465 
4466 template<typename BasicJsonType, typename ConstructibleArrayType,
4467  enable_if_t<
4468  std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4469  int> = 0>
4470 auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, priority_tag<1> /*unused*/)
4471 -> decltype(
4472  arr.reserve(std::declval<typename ConstructibleArrayType::size_type>()),
4473  j.template get<typename ConstructibleArrayType::value_type>(),
4474  void())
4475 {
4476  using std::end;
4477 
4478  ConstructibleArrayType ret;
4479  ret.reserve(j.size());
4480  std::transform(j.begin(), j.end(),
4481  std::inserter(ret, end(ret)), [](const BasicJsonType & i)
4482  {
4483  // get<BasicJsonType>() returns *this, this won't call a from_json
4484  // method when value_type is BasicJsonType
4485  return i.template get<typename ConstructibleArrayType::value_type>();
4486  });
4487  arr = std::move(ret);
4488 }
4489 
4490 template<typename BasicJsonType, typename ConstructibleArrayType,
4491  enable_if_t<
4492  std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
4493  int> = 0>
4494 inline void from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr,
4495  priority_tag<0> /*unused*/)
4496 {
4497  using std::end;
4498 
4499  ConstructibleArrayType ret;
4500  std::transform(
4501  j.begin(), j.end(), std::inserter(ret, end(ret)),
4502  [](const BasicJsonType & i)
4503  {
4504  // get<BasicJsonType>() returns *this, this won't call a from_json
4505  // method when value_type is BasicJsonType
4506  return i.template get<typename ConstructibleArrayType::value_type>();
4507  });
4508  arr = std::move(ret);
4509 }
4510 
4511 template < typename BasicJsonType, typename ConstructibleArrayType,
4512  enable_if_t <
4513  is_constructible_array_type<BasicJsonType, ConstructibleArrayType>::value&&
4514  !is_constructible_object_type<BasicJsonType, ConstructibleArrayType>::value&&
4516  !std::is_same<ConstructibleArrayType, typename BasicJsonType::binary_t>::value&&
4517  !is_basic_json<ConstructibleArrayType>::value,
4518  int > = 0 >
4519 auto from_json(const BasicJsonType& j, ConstructibleArrayType& arr)
4520 -> decltype(from_json_array_impl(j, arr, priority_tag<3> {}),
4521 j.template get<typename ConstructibleArrayType::value_type>(),
4522 void())
4523 {
4524  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4525  {
4526  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4527  }
4528 
4529  from_json_array_impl(j, arr, priority_tag<3> {});
4530 }
4531 
4532 template < typename BasicJsonType, typename T, std::size_t... Idx >
4533 std::array<T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType&& j,
4534  identity_tag<std::array<T, sizeof...(Idx)>> /*unused*/, index_sequence<Idx...> /*unused*/)
4535 {
4536  return { { std::forward<BasicJsonType>(j).at(Idx).template get<T>()... } };
4537 }
4538 
4539 template < typename BasicJsonType, typename T, std::size_t N >
4540 auto from_json(BasicJsonType&& j, identity_tag<std::array<T, N>> tag)
4541 -> decltype(from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {}))
4542 {
4543  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4544  {
4545  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4546  }
4547 
4548  return from_json_inplace_array_impl(std::forward<BasicJsonType>(j), tag, make_index_sequence<N> {});
4549 }
4550 
4551 template<typename BasicJsonType>
4552 inline void from_json(const BasicJsonType& j, typename BasicJsonType::binary_t& bin)
4553 {
4554  if (JSON_HEDLEY_UNLIKELY(!j.is_binary()))
4555  {
4556  JSON_THROW(type_error::create(302, concat("type must be binary, but is ", j.type_name()), &j));
4557  }
4558 
4559  bin = *j.template get_ptr<const typename BasicJsonType::binary_t*>();
4560 }
4561 
4562 template<typename BasicJsonType, typename ConstructibleObjectType,
4563  enable_if_t<is_constructible_object_type<BasicJsonType, ConstructibleObjectType>::value, int> = 0>
4564 inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
4565 {
4566  if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
4567  {
4568  JSON_THROW(type_error::create(302, concat("type must be object, but is ", j.type_name()), &j));
4569  }
4570 
4571  ConstructibleObjectType ret;
4572  const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
4573  using value_type = typename ConstructibleObjectType::value_type;
4574  std::transform(
4575  inner_object->begin(), inner_object->end(),
4576  std::inserter(ret, ret.begin()),
4577  [](typename BasicJsonType::object_t::value_type const & p)
4578  {
4579  return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
4580  });
4581  obj = std::move(ret);
4582 }
4583 
4584 // overload for arithmetic types, not chosen for basic_json template arguments
4585 // (BooleanType, etc..); note: Is it really necessary to provide explicit
4586 // overloads for boolean_t etc. in case of a custom BooleanType which is not
4587 // an arithmetic type?
4588 template < typename BasicJsonType, typename ArithmeticType,
4589  enable_if_t <
4590  std::is_arithmetic<ArithmeticType>::value&&
4591  !std::is_same<ArithmeticType, typename BasicJsonType::number_unsigned_t>::value&&
4592  !std::is_same<ArithmeticType, typename BasicJsonType::number_integer_t>::value&&
4593  !std::is_same<ArithmeticType, typename BasicJsonType::number_float_t>::value&&
4594  !std::is_same<ArithmeticType, typename BasicJsonType::boolean_t>::value,
4595  int > = 0 >
4596 inline void from_json(const BasicJsonType& j, ArithmeticType& val)
4597 {
4598  switch (static_cast<value_t>(j))
4599  {
4601  {
4602  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_unsigned_t*>());
4603  break;
4604  }
4606  {
4607  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_integer_t*>());
4608  break;
4609  }
4610  case value_t::number_float:
4611  {
4612  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::number_float_t*>());
4613  break;
4614  }
4615  case value_t::boolean:
4616  {
4617  val = static_cast<ArithmeticType>(*j.template get_ptr<const typename BasicJsonType::boolean_t*>());
4618  break;
4619  }
4620 
4621  case value_t::null:
4622  case value_t::object:
4623  case value_t::array:
4624  case value_t::string:
4625  case value_t::binary:
4626  case value_t::discarded:
4627  default:
4628  JSON_THROW(type_error::create(302, concat("type must be number, but is ", j.type_name()), &j));
4629  }
4630 }
4631 
4632 template<typename BasicJsonType, typename... Args, std::size_t... Idx>
4633 std::tuple<Args...> from_json_tuple_impl_base(BasicJsonType&& j, index_sequence<Idx...> /*unused*/)
4634 {
4635  return std::make_tuple(std::forward<BasicJsonType>(j).at(Idx).template get<Args>()...);
4636 }
4637 
4638 template < typename BasicJsonType, class A1, class A2 >
4639 std::pair<A1, A2> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::pair<A1, A2>> /*unused*/, priority_tag<0> /*unused*/)
4640 {
4641  return {std::forward<BasicJsonType>(j).at(0).template get<A1>(),
4642  std::forward<BasicJsonType>(j).at(1).template get<A2>()};
4643 }
4644 
4645 template<typename BasicJsonType, typename A1, typename A2>
4646 inline void from_json_tuple_impl(BasicJsonType&& j, std::pair<A1, A2>& p, priority_tag<1> /*unused*/)
4647 {
4648  p = from_json_tuple_impl(std::forward<BasicJsonType>(j), identity_tag<std::pair<A1, A2>> {}, priority_tag<0> {});
4649 }
4650 
4651 template<typename BasicJsonType, typename... Args>
4652 std::tuple<Args...> from_json_tuple_impl(BasicJsonType&& j, identity_tag<std::tuple<Args...>> /*unused*/, priority_tag<2> /*unused*/)
4653 {
4654  return from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4655 }
4656 
4657 template<typename BasicJsonType, typename... Args>
4658 inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple<Args...>& t, priority_tag<3> /*unused*/)
4659 {
4660  t = from_json_tuple_impl_base<BasicJsonType, Args...>(std::forward<BasicJsonType>(j), index_sequence_for<Args...> {});
4661 }
4662 
4663 template<typename BasicJsonType, typename TupleRelated>
4664 auto from_json(BasicJsonType&& j, TupleRelated&& t)
4665 -> decltype(from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {}))
4666 {
4667  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4668  {
4669  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4670  }
4671 
4672  return from_json_tuple_impl(std::forward<BasicJsonType>(j), std::forward<TupleRelated>(t), priority_tag<3> {});
4673 }
4674 
4675 template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator,
4676  typename = enable_if_t < !std::is_constructible <
4677  typename BasicJsonType::string_t, Key >::value >>
4678 inline void from_json(const BasicJsonType& j, std::map<Key, Value, Compare, Allocator>& m)
4679 {
4680  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4681  {
4682  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4683  }
4684  m.clear();
4685  for (const auto& p : j)
4686  {
4687  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4688  {
4689  JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
4690  }
4691  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4692  }
4693 }
4694 
4695 template < typename BasicJsonType, typename Key, typename Value, typename Hash, typename KeyEqual, typename Allocator,
4696  typename = enable_if_t < !std::is_constructible <
4697  typename BasicJsonType::string_t, Key >::value >>
4698 inline void from_json(const BasicJsonType& j, std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>& m)
4699 {
4700  if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
4701  {
4702  JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j));
4703  }
4704  m.clear();
4705  for (const auto& p : j)
4706  {
4707  if (JSON_HEDLEY_UNLIKELY(!p.is_array()))
4708  {
4709  JSON_THROW(type_error::create(302, concat("type must be array, but is ", p.type_name()), &j));
4710  }
4711  m.emplace(p.at(0).template get<Key>(), p.at(1).template get<Value>());
4712  }
4713 }
4714 
4715 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
4716 template<typename BasicJsonType>
4717 inline void from_json(const BasicJsonType& j, std_fs::path& p)
4718 {
4719  if (JSON_HEDLEY_UNLIKELY(!j.is_string()))
4720  {
4721  JSON_THROW(type_error::create(302, concat("type must be string, but is ", j.type_name()), &j));
4722  }
4723  p = *j.template get_ptr<const typename BasicJsonType::string_t*>();
4724 }
4725 #endif
4726 
4728 {
4729  template<typename BasicJsonType, typename T>
4730  auto operator()(const BasicJsonType& j, T&& val) const
4731  noexcept(noexcept(from_json(j, std::forward<T>(val))))
4732  -> decltype(from_json(j, std::forward<T>(val)))
4733  {
4734  return from_json(j, std::forward<T>(val));
4735  }
4736 };
4737 } // namespace detail
4738 
4739 #ifndef JSON_HAS_CPP_17
4743 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
4744 {
4745 #endif
4746 JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers)
4748 #ifndef JSON_HAS_CPP_17
4749 } // namespace
4750 #endif
4751 } // namespace nlohmann
4752 
4753 // #include <nlohmann/detail/conversions/to_json.hpp>
4754 
4755 
4756 #include <algorithm> // copy
4757 #include <iterator> // begin, end
4758 #include <string> // string
4759 #include <tuple> // tuple, get
4760 #include <type_traits> // is_same, is_constructible, is_floating_point, is_enum, underlying_type
4761 #include <utility> // move, forward, declval, pair
4762 #include <valarray> // valarray
4763 #include <vector> // vector
4764 
4765 // #include <nlohmann/detail/macro_scope.hpp>
4766 
4767 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
4768 
4769 
4770 #include <cstddef> // size_t
4771 #include <iterator> // input_iterator_tag
4772 #include <string> // string, to_string
4773 #include <tuple> // tuple_size, get, tuple_element
4774 #include <utility> // move
4775 
4776 #if JSON_HAS_RANGES
4777  #include <ranges> // enable_borrowed_range
4778 #endif
4779 
4780 // #include <nlohmann/detail/meta/type_traits.hpp>
4781 
4782 // #include <nlohmann/detail/value_t.hpp>
4783 
4784 
4785 namespace nlohmann
4786 {
4787 namespace detail
4788 {
4789 template<typename string_type>
4790 void int_to_string( string_type& target, std::size_t value )
4791 {
4792  // For ADL
4793  using std::to_string;
4794  target = to_string(value);
4795 }
4796 template<typename IteratorType> class iteration_proxy_value
4797 {
4798  public:
4799  using difference_type = std::ptrdiff_t;
4801  using pointer = value_type *;
4803  using iterator_category = std::input_iterator_tag;
4804  using string_type = typename std::remove_cv< typename std::remove_reference<decltype( std::declval<IteratorType>().key() ) >::type >::type;
4805 
4806  private:
4808  IteratorType anchor{};
4810  std::size_t array_index = 0;
4812  mutable std::size_t array_index_last = 0;
4814  mutable string_type array_index_str = "0";
4816  string_type empty_str{};
4817 
4818  public:
4819  explicit iteration_proxy_value() = default;
4820  explicit iteration_proxy_value(IteratorType it, std::size_t array_index_ = 0)
4821  noexcept(std::is_nothrow_move_constructible<IteratorType>::value
4822  && std::is_nothrow_default_constructible<string_type>::value)
4823  : anchor(std::move(it))
4824  , array_index(array_index_)
4825  {}
4826 
4829  // older GCCs are a bit fussy and require explicit noexcept specifiers on defaulted functions
4831  noexcept(std::is_nothrow_move_constructible<IteratorType>::value
4832  && std::is_nothrow_move_constructible<string_type>::value) = default;
4834  noexcept(std::is_nothrow_move_assignable<IteratorType>::value
4835  && std::is_nothrow_move_assignable<string_type>::value) = default;
4837 
4839  const iteration_proxy_value& operator*() const
4840  {
4841  return *this;
4842  }
4843 
4846  {
4847  ++anchor;
4848  ++array_index;
4849 
4850  return *this;
4851  }
4852 
4853  iteration_proxy_value operator++(int)& // NOLINT(cert-dcl21-cpp)
4854  {
4855  auto tmp = iteration_proxy_value(anchor, array_index);
4856  ++anchor;
4857  ++array_index;
4858  return tmp;
4859  }
4860 
4862  bool operator==(const iteration_proxy_value& o) const
4863  {
4864  return anchor == o.anchor;
4865  }
4866 
4868  bool operator!=(const iteration_proxy_value& o) const
4869  {
4870  return anchor != o.anchor;
4871  }
4872 
4874  const string_type& key() const
4875  {
4876  JSON_ASSERT(anchor.m_object != nullptr);
4877 
4878  switch (anchor.m_object->type())
4879  {
4880  // use integer array index as key
4881  case value_t::array:
4882  {
4883  if (array_index != array_index_last)
4884  {
4885  int_to_string( array_index_str, array_index );
4886  array_index_last = array_index;
4887  }
4888  return array_index_str;
4889  }
4890 
4891  // use key from the object
4892  case value_t::object:
4893  return anchor.key();
4894 
4895  // use an empty key for all primitive types
4896  case value_t::null:
4897  case value_t::string:
4898  case value_t::boolean:
4901  case value_t::number_float:
4902  case value_t::binary:
4903  case value_t::discarded:
4904  default:
4905  return empty_str;
4906  }
4907  }
4908 
4910  typename IteratorType::reference value() const
4911  {
4912  return anchor.value();
4913  }
4914 };
4915 
4917 template<typename IteratorType> class iteration_proxy
4918 {
4919  private:
4921  typename IteratorType::pointer container = nullptr;
4922 
4923  public:
4924  explicit iteration_proxy() = default;
4925 
4927  explicit iteration_proxy(typename IteratorType::reference cont) noexcept
4928  : container(&cont) {}
4929 
4932  iteration_proxy(iteration_proxy&&) noexcept = default;
4933  iteration_proxy& operator=(iteration_proxy&&) noexcept = default;
4934  ~iteration_proxy() = default;
4935 
4937  iteration_proxy_value<IteratorType> begin() const noexcept
4938  {
4939  return iteration_proxy_value<IteratorType>(container->begin());
4940  }
4941 
4944  {
4945  return iteration_proxy_value<IteratorType>(container->end());
4946  }
4947 };
4948 
4949 // Structured Bindings Support
4950 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4951 // And see https://github.com/nlohmann/json/pull/1391
4952 template<std::size_t N, typename IteratorType, enable_if_t<N == 0, int> = 0>
4954 {
4955  return i.key();
4956 }
4957 // Structured Bindings Support
4958 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4959 // And see https://github.com/nlohmann/json/pull/1391
4960 template<std::size_t N, typename IteratorType, enable_if_t<N == 1, int> = 0>
4961 auto get(const nlohmann::detail::iteration_proxy_value<IteratorType>& i) -> decltype(i.value())
4962 {
4963  return i.value();
4964 }
4965 } // namespace detail
4966 } // namespace nlohmann
4967 
4968 // The Addition to the STD Namespace is required to add
4969 // Structured Bindings Support to the iteration_proxy_value class
4970 // For further reference see https://blog.tartanllama.xyz/structured-bindings/
4971 // And see https://github.com/nlohmann/json/pull/1391
4972 namespace std
4973 {
4974 #if defined(__clang__)
4975  // Fix: https://github.com/nlohmann/json/issues/1401
4976  #pragma clang diagnostic push
4977  #pragma clang diagnostic ignored "-Wmismatched-tags"
4978 #endif
4979 template<typename IteratorType>
4980 class tuple_size<::nlohmann::detail::iteration_proxy_value<IteratorType>>
4981  : public std::integral_constant<std::size_t, 2> {};
4982 
4983 template<std::size_t N, typename IteratorType>
4984 class tuple_element<N, ::nlohmann::detail::iteration_proxy_value<IteratorType >>
4985 {
4986  public:
4987  using type = decltype(
4988  get<N>(std::declval <
4990 };
4991 #if defined(__clang__)
4992  #pragma clang diagnostic pop
4993 #endif
4994 } // namespace std
4995 
4996 #if JSON_HAS_RANGES
4997  template <typename IteratorType>
4998  inline constexpr bool ::std::ranges::enable_borrowed_range<::nlohmann::detail::iteration_proxy<IteratorType>> = true;
4999 #endif
5000 
5001 // #include <nlohmann/detail/meta/cpp_future.hpp>
5002 
5003 // #include <nlohmann/detail/meta/type_traits.hpp>
5004 
5005 // #include <nlohmann/detail/value_t.hpp>
5006 
5007 
5008 #if JSON_HAS_EXPERIMENTAL_FILESYSTEM
5009 #include <experimental/filesystem>
5010 namespace nlohmann::detail
5011 {
5012 namespace std_fs = std::experimental::filesystem;
5013 } // namespace nlohmann::detail
5014 #elif JSON_HAS_FILESYSTEM
5015 #include <filesystem>
5016 namespace nlohmann::detail
5017 {
5018 namespace std_fs = std::filesystem;
5019 } // namespace nlohmann::detail
5020 #endif
5021 
5022 namespace nlohmann
5023 {
5024 namespace detail
5025 {
5027 // constructors //
5029 
5030 /*
5031  * Note all external_constructor<>::construct functions need to call
5032  * j.m_value.destroy(j.m_type) to avoid a memory leak in case j contains an
5033  * allocated value (e.g., a string). See bug issue
5034  * https://github.com/nlohmann/json/issues/2865 for more information.
5035  */
5036 
5037 template<value_t> struct external_constructor;
5038 
5039 template<>
5041 {
5042  template<typename BasicJsonType>
5043  static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept
5044  {
5045  j.m_value.destroy(j.m_type);
5046  j.m_type = value_t::boolean;
5047  j.m_value = b;
5048  j.assert_invariant();
5049  }
5050 };
5051 
5052 template<>
5054 {
5055  template<typename BasicJsonType>
5056  static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s)
5057  {
5058  j.m_value.destroy(j.m_type);
5059  j.m_type = value_t::string;
5060  j.m_value = s;
5061  j.assert_invariant();
5062  }
5063 
5064  template<typename BasicJsonType>
5065  static void construct(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5066  {
5067  j.m_value.destroy(j.m_type);
5068  j.m_type = value_t::string;
5069  j.m_value = std::move(s);
5070  j.assert_invariant();
5071  }
5072 
5073  template < typename BasicJsonType, typename CompatibleStringType,
5075  int > = 0 >
5076  static void construct(BasicJsonType& j, const CompatibleStringType& str)
5077  {
5078  j.m_value.destroy(j.m_type);
5079  j.m_type = value_t::string;
5080  j.m_value.string = j.template create<typename BasicJsonType::string_t>(str);
5081  j.assert_invariant();
5082  }
5083 };
5084 
5085 template<>
5087 {
5088  template<typename BasicJsonType>
5089  static void construct(BasicJsonType& j, const typename BasicJsonType::binary_t& b)
5090  {
5091  j.m_value.destroy(j.m_type);
5092  j.m_type = value_t::binary;
5093  j.m_value = typename BasicJsonType::binary_t(b);
5094  j.assert_invariant();
5095  }
5096 
5097  template<typename BasicJsonType>
5098  static void construct(BasicJsonType& j, typename BasicJsonType::binary_t&& b)
5099  {
5100  j.m_value.destroy(j.m_type);
5101  j.m_type = value_t::binary;
5102  j.m_value = typename BasicJsonType::binary_t(std::move(b));
5103  j.assert_invariant();
5104  }
5105 };
5106 
5107 template<>
5109 {
5110  template<typename BasicJsonType>
5111  static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept
5112  {
5113  j.m_value.destroy(j.m_type);
5114  j.m_type = value_t::number_float;
5115  j.m_value = val;
5116  j.assert_invariant();
5117  }
5118 };
5119 
5120 template<>
5122 {
5123  template<typename BasicJsonType>
5124  static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept
5125  {
5126  j.m_value.destroy(j.m_type);
5127  j.m_type = value_t::number_unsigned;
5128  j.m_value = val;
5129  j.assert_invariant();
5130  }
5131 };
5132 
5133 template<>
5135 {
5136  template<typename BasicJsonType>
5137  static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept
5138  {
5139  j.m_value.destroy(j.m_type);
5140  j.m_type = value_t::number_integer;
5141  j.m_value = val;
5142  j.assert_invariant();
5143  }
5144 };
5145 
5146 template<>
5148 {
5149  template<typename BasicJsonType>
5150  static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr)
5151  {
5152  j.m_value.destroy(j.m_type);
5153  j.m_type = value_t::array;
5154  j.m_value = arr;
5155  j.set_parents();
5156  j.assert_invariant();
5157  }
5158 
5159  template<typename BasicJsonType>
5160  static void construct(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5161  {
5162  j.m_value.destroy(j.m_type);
5163  j.m_type = value_t::array;
5164  j.m_value = std::move(arr);
5165  j.set_parents();
5166  j.assert_invariant();
5167  }
5168 
5169  template < typename BasicJsonType, typename CompatibleArrayType,
5171  int > = 0 >
5172  static void construct(BasicJsonType& j, const CompatibleArrayType& arr)
5173  {
5174  using std::begin;
5175  using std::end;
5176 
5177  j.m_value.destroy(j.m_type);
5178  j.m_type = value_t::array;
5179  j.m_value.array = j.template create<typename BasicJsonType::array_t>(begin(arr), end(arr));
5180  j.set_parents();
5181  j.assert_invariant();
5182  }
5183 
5184  template<typename BasicJsonType>
5185  static void construct(BasicJsonType& j, const std::vector<bool>& arr)
5186  {
5187  j.m_value.destroy(j.m_type);
5188  j.m_type = value_t::array;
5189  j.m_value = value_t::array;
5190  j.m_value.array->reserve(arr.size());
5191  for (const bool x : arr)
5192  {
5193  j.m_value.array->push_back(x);
5194  j.set_parent(j.m_value.array->back());
5195  }
5196  j.assert_invariant();
5197  }
5198 
5199  template<typename BasicJsonType, typename T,
5201  static void construct(BasicJsonType& j, const std::valarray<T>& arr)
5202  {
5203  j.m_value.destroy(j.m_type);
5204  j.m_type = value_t::array;
5205  j.m_value = value_t::array;
5206  j.m_value.array->resize(arr.size());
5207  if (arr.size() > 0)
5208  {
5209  std::copy(std::begin(arr), std::end(arr), j.m_value.array->begin());
5210  }
5211  j.set_parents();
5212  j.assert_invariant();
5213  }
5214 };
5215 
5216 template<>
5218 {
5219  template<typename BasicJsonType>
5220  static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj)
5221  {
5222  j.m_value.destroy(j.m_type);
5223  j.m_type = value_t::object;
5224  j.m_value = obj;
5225  j.set_parents();
5226  j.assert_invariant();
5227  }
5228 
5229  template<typename BasicJsonType>
5230  static void construct(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5231  {
5232  j.m_value.destroy(j.m_type);
5233  j.m_type = value_t::object;
5234  j.m_value = std::move(obj);
5235  j.set_parents();
5236  j.assert_invariant();
5237  }
5238 
5239  template < typename BasicJsonType, typename CompatibleObjectType,
5241  static void construct(BasicJsonType& j, const CompatibleObjectType& obj)
5242  {
5243  using std::begin;
5244  using std::end;
5245 
5246  j.m_value.destroy(j.m_type);
5247  j.m_type = value_t::object;
5248  j.m_value.object = j.template create<typename BasicJsonType::object_t>(begin(obj), end(obj));
5249  j.set_parents();
5250  j.assert_invariant();
5251  }
5252 };
5253 
5255 // to_json //
5257 
5258 template<typename BasicJsonType, typename T,
5259  enable_if_t<std::is_same<T, typename BasicJsonType::boolean_t>::value, int> = 0>
5260 inline void to_json(BasicJsonType& j, T b) noexcept
5261 {
5263 }
5264 
5265 template<typename BasicJsonType,
5266  enable_if_t<std::is_convertible<const std::vector<bool>::reference&, typename BasicJsonType::boolean_t>::value, int> = 0>
5267 inline void to_json(BasicJsonType& j, const std::vector<bool>::reference& b) noexcept
5268 {
5269  external_constructor<value_t::boolean>::construct(j, static_cast<typename BasicJsonType::boolean_t>(b));
5270 }
5271 
5272 template<typename BasicJsonType, typename CompatibleString,
5273  enable_if_t<std::is_constructible<typename BasicJsonType::string_t, CompatibleString>::value, int> = 0>
5274 inline void to_json(BasicJsonType& j, const CompatibleString& s)
5275 {
5277 }
5278 
5279 template<typename BasicJsonType>
5280 inline void to_json(BasicJsonType& j, typename BasicJsonType::string_t&& s)
5281 {
5283 }
5284 
5285 template<typename BasicJsonType, typename FloatType,
5286  enable_if_t<std::is_floating_point<FloatType>::value, int> = 0>
5287 inline void to_json(BasicJsonType& j, FloatType val) noexcept
5288 {
5289  external_constructor<value_t::number_float>::construct(j, static_cast<typename BasicJsonType::number_float_t>(val));
5290 }
5291 
5292 template<typename BasicJsonType, typename CompatibleNumberUnsignedType,
5293  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_unsigned_t, CompatibleNumberUnsignedType>::value, int> = 0>
5294 inline void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept
5295 {
5296  external_constructor<value_t::number_unsigned>::construct(j, static_cast<typename BasicJsonType::number_unsigned_t>(val));
5297 }
5298 
5299 template<typename BasicJsonType, typename CompatibleNumberIntegerType,
5300  enable_if_t<is_compatible_integer_type<typename BasicJsonType::number_integer_t, CompatibleNumberIntegerType>::value, int> = 0>
5301 inline void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept
5302 {
5303  external_constructor<value_t::number_integer>::construct(j, static_cast<typename BasicJsonType::number_integer_t>(val));
5304 }
5305 
5306 #if !JSON_DISABLE_ENUM_SERIALIZATION
5307 template<typename BasicJsonType, typename EnumType,
5308  enable_if_t<std::is_enum<EnumType>::value, int> = 0>
5309 inline void to_json(BasicJsonType& j, EnumType e) noexcept
5310 {
5311  using underlying_type = typename std::underlying_type<EnumType>::type;
5312  external_constructor<value_t::number_integer>::construct(j, static_cast<underlying_type>(e));
5313 }
5314 #endif // JSON_DISABLE_ENUM_SERIALIZATION
5315 
5316 template<typename BasicJsonType>
5317 inline void to_json(BasicJsonType& j, const std::vector<bool>& e)
5318 {
5320 }
5321 
5322 template < typename BasicJsonType, typename CompatibleArrayType,
5323  enable_if_t < is_compatible_array_type<BasicJsonType,
5324  CompatibleArrayType>::value&&
5325  !is_compatible_object_type<BasicJsonType, CompatibleArrayType>::value&&
5327  !std::is_same<typename BasicJsonType::binary_t, CompatibleArrayType>::value&&
5328  !is_basic_json<CompatibleArrayType>::value,
5329  int > = 0 >
5330 inline void to_json(BasicJsonType& j, const CompatibleArrayType& arr)
5331 {
5333 }
5334 
5335 template<typename BasicJsonType>
5336 inline void to_json(BasicJsonType& j, const typename BasicJsonType::binary_t& bin)
5337 {
5339 }
5340 
5341 template<typename BasicJsonType, typename T,
5342  enable_if_t<std::is_convertible<T, BasicJsonType>::value, int> = 0>
5343 inline void to_json(BasicJsonType& j, const std::valarray<T>& arr)
5344 {
5346 }
5347 
5348 template<typename BasicJsonType>
5349 inline void to_json(BasicJsonType& j, typename BasicJsonType::array_t&& arr)
5350 {
5352 }
5353 
5354 template < typename BasicJsonType, typename CompatibleObjectType,
5355  enable_if_t < is_compatible_object_type<BasicJsonType, CompatibleObjectType>::value&& !is_basic_json<CompatibleObjectType>::value, int > = 0 >
5356 inline void to_json(BasicJsonType& j, const CompatibleObjectType& obj)
5357 {
5359 }
5360 
5361 template<typename BasicJsonType>
5362 inline void to_json(BasicJsonType& j, typename BasicJsonType::object_t&& obj)
5363 {
5365 }
5366 
5367 template <
5368  typename BasicJsonType, typename T, std::size_t N,
5369  enable_if_t < !std::is_constructible<typename BasicJsonType::string_t,
5370  const T(&)[N]>::value, // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5371  int > = 0 >
5372 inline void to_json(BasicJsonType& j, const T(&arr)[N]) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
5373 {
5375 }
5376 
5377 template < typename BasicJsonType, typename T1, typename T2, enable_if_t < std::is_constructible<BasicJsonType, T1>::value&& std::is_constructible<BasicJsonType, T2>::value, int > = 0 >
5378 inline void to_json(BasicJsonType& j, const std::pair<T1, T2>& p)
5379 {
5380  j = { p.first, p.second };
5381 }
5382 
5383 // for https://github.com/nlohmann/json/pull/1134
5384 template<typename BasicJsonType, typename T,
5385  enable_if_t<std::is_same<T, iteration_proxy_value<typename BasicJsonType::iterator>>::value, int> = 0>
5386 inline void to_json(BasicJsonType& j, const T& b)
5387 {
5388  j = { {b.key(), b.value()} };
5389 }
5390 
5391 template<typename BasicJsonType, typename Tuple, std::size_t... Idx>
5392 inline void to_json_tuple_impl(BasicJsonType& j, const Tuple& t, index_sequence<Idx...> /*unused*/)
5393 {
5394  j = { std::get<Idx>(t)... };
5395 }
5396 
5397 template<typename BasicJsonType, typename T, enable_if_t<is_constructible_tuple<BasicJsonType, T>::value, int > = 0>
5398 inline void to_json(BasicJsonType& j, const T& t)
5399 {
5400  to_json_tuple_impl(j, t, make_index_sequence<std::tuple_size<T>::value> {});
5401 }
5402 
5403 #if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
5404 template<typename BasicJsonType>
5405 inline void to_json(BasicJsonType& j, const std_fs::path& p)
5406 {
5407  j = p.string();
5408 }
5409 #endif
5410 
5412 {
5413  template<typename BasicJsonType, typename T>
5414  auto operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(to_json(j, std::forward<T>(val))))
5415  -> decltype(to_json(j, std::forward<T>(val)), void())
5416  {
5417  return to_json(j, std::forward<T>(val));
5418  }
5419 };
5420 } // namespace detail
5421 
5422 #ifndef JSON_HAS_CPP_17
5426 namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces)
5427 {
5428 #endif
5429 JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers)
5431 #ifndef JSON_HAS_CPP_17
5432 } // namespace
5433 #endif
5434 } // namespace nlohmann
5435 
5436 // #include <nlohmann/detail/meta/identity_tag.hpp>
5437 
5438 // #include <nlohmann/detail/meta/type_traits.hpp>
5439 
5440 
5441 namespace nlohmann
5442 {
5443 
5445 template<typename ValueType, typename>
5447 {
5450  template<typename BasicJsonType, typename TargetType = ValueType>
5451  static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
5452  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), val)))
5453  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), val), void())
5454  {
5455  ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
5456  }
5457 
5460  template<typename BasicJsonType, typename TargetType = ValueType>
5461  static auto from_json(BasicJsonType && j) noexcept(
5462  noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {})))
5463  -> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
5464  {
5465  return ::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {});
5466  }
5467 
5470  template<typename BasicJsonType, typename TargetType = ValueType>
5471  static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
5472  noexcept(::nlohmann::to_json(j, std::forward<TargetType>(val))))
5473  -> decltype(::nlohmann::to_json(j, std::forward<TargetType>(val)), void())
5474  {
5475  ::nlohmann::to_json(j, std::forward<TargetType>(val));
5476  }
5477 };
5478 } // namespace nlohmann
5479 
5480 // #include <nlohmann/byte_container_with_subtype.hpp>
5481 
5482 
5483 #include <cstdint> // uint8_t, uint64_t
5484 #include <tuple> // tie
5485 #include <utility> // move
5486 
5487 namespace nlohmann
5488 {
5489 
5492 template<typename BinaryType>
5493 class byte_container_with_subtype : public BinaryType
5494 {
5495  public:
5496  using container_type = BinaryType;
5497  using subtype_type = std::uint64_t;
5498 
5501  : container_type()
5502  {}
5503 
5506  : container_type(b)
5507  {}
5508 
5510  byte_container_with_subtype(container_type&& b) noexcept(noexcept(container_type(std::move(b))))
5511  : container_type(std::move(b))
5512  {}
5513 
5515  byte_container_with_subtype(const container_type& b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
5516  : container_type(b)
5517  , m_subtype(subtype_)
5518  , m_has_subtype(true)
5519  {}
5520 
5522  byte_container_with_subtype(container_type&& b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
5523  : container_type(std::move(b))
5524  , m_subtype(subtype_)
5525  , m_has_subtype(true)
5526  {}
5527 
5529  {
5530  return std::tie(static_cast<const BinaryType&>(*this), m_subtype, m_has_subtype) ==
5531  std::tie(static_cast<const BinaryType&>(rhs), rhs.m_subtype, rhs.m_has_subtype);
5532  }
5533 
5535  {
5536  return !(rhs == *this);
5537  }
5538 
5541  void set_subtype(subtype_type subtype_) noexcept
5542  {
5543  m_subtype = subtype_;
5544  m_has_subtype = true;
5545  }
5546 
5549  constexpr subtype_type subtype() const noexcept
5550  {
5551  return m_has_subtype ? m_subtype : static_cast<subtype_type>(-1);
5552  }
5553 
5556  constexpr bool has_subtype() const noexcept
5557  {
5558  return m_has_subtype;
5559  }
5560 
5563  void clear_subtype() noexcept
5564  {
5565  m_subtype = 0;
5566  m_has_subtype = false;
5567  }
5568 
5569  private:
5570  subtype_type m_subtype = 0;
5571  bool m_has_subtype = false;
5572 };
5573 
5574 } // namespace nlohmann
5575 
5576 // #include <nlohmann/detail/conversions/from_json.hpp>
5577 
5578 // #include <nlohmann/detail/conversions/to_json.hpp>
5579 
5580 // #include <nlohmann/detail/exceptions.hpp>
5581 
5582 // #include <nlohmann/detail/hash.hpp>
5583 
5584 
5585 #include <cstdint> // uint8_t
5586 #include <cstddef> // size_t
5587 #include <functional> // hash
5588 
5589 // #include <nlohmann/detail/macro_scope.hpp>
5590 
5591 // #include <nlohmann/detail/value_t.hpp>
5592 
5593 
5594 namespace nlohmann
5595 {
5596 namespace detail
5597 {
5598 
5599 // boost::hash_combine
5600 inline std::size_t combine(std::size_t seed, std::size_t h) noexcept
5601 {
5602  seed ^= h + 0x9e3779b9 + (seed << 6U) + (seed >> 2U);
5603  return seed;
5604 }
5605 
5617 template<typename BasicJsonType>
5618 std::size_t hash(const BasicJsonType& j)
5619 {
5620  using string_t = typename BasicJsonType::string_t;
5621  using number_integer_t = typename BasicJsonType::number_integer_t;
5622  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
5623  using number_float_t = typename BasicJsonType::number_float_t;
5624 
5625  const auto type = static_cast<std::size_t>(j.type());
5626  switch (j.type())
5627  {
5628  case BasicJsonType::value_t::null:
5629  case BasicJsonType::value_t::discarded:
5630  {
5631  return combine(type, 0);
5632  }
5633 
5634  case BasicJsonType::value_t::object:
5635  {
5636  auto seed = combine(type, j.size());
5637  for (const auto& element : j.items())
5638  {
5639  const auto h = std::hash<string_t> {}(element.key());
5640  seed = combine(seed, h);
5641  seed = combine(seed, hash(element.value()));
5642  }
5643  return seed;
5644  }
5645 
5646  case BasicJsonType::value_t::array:
5647  {
5648  auto seed = combine(type, j.size());
5649  for (const auto& element : j)
5650  {
5651  seed = combine(seed, hash(element));
5652  }
5653  return seed;
5654  }
5655 
5656  case BasicJsonType::value_t::string:
5657  {
5658  const auto h = std::hash<string_t> {}(j.template get_ref<const string_t&>());
5659  return combine(type, h);
5660  }
5661 
5662  case BasicJsonType::value_t::boolean:
5663  {
5664  const auto h = std::hash<bool> {}(j.template get<bool>());
5665  return combine(type, h);
5666  }
5667 
5668  case BasicJsonType::value_t::number_integer:
5669  {
5670  const auto h = std::hash<number_integer_t> {}(j.template get<number_integer_t>());
5671  return combine(type, h);
5672  }
5673 
5674  case BasicJsonType::value_t::number_unsigned:
5675  {
5676  const auto h = std::hash<number_unsigned_t> {}(j.template get<number_unsigned_t>());
5677  return combine(type, h);
5678  }
5679 
5680  case BasicJsonType::value_t::number_float:
5681  {
5682  const auto h = std::hash<number_float_t> {}(j.template get<number_float_t>());
5683  return combine(type, h);
5684  }
5685 
5686  case BasicJsonType::value_t::binary:
5687  {
5688  auto seed = combine(type, j.get_binary().size());
5689  const auto h = std::hash<bool> {}(j.get_binary().has_subtype());
5690  seed = combine(seed, h);
5691  seed = combine(seed, static_cast<std::size_t>(j.get_binary().subtype()));
5692  for (const auto byte : j.get_binary())
5693  {
5694  seed = combine(seed, std::hash<std::uint8_t> {}(byte));
5695  }
5696  return seed;
5697  }
5698 
5699  default: // LCOV_EXCL_LINE
5700  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
5701  return 0; // LCOV_EXCL_LINE
5702  }
5703 }
5704 
5705 } // namespace detail
5706 } // namespace nlohmann
5707 
5708 // #include <nlohmann/detail/input/binary_reader.hpp>
5709 
5710 
5711 #include <algorithm> // generate_n
5712 #include <array> // array
5713 #include <cmath> // ldexp
5714 #include <cstddef> // size_t
5715 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
5716 #include <cstdio> // snprintf
5717 #include <cstring> // memcpy
5718 #include <iterator> // back_inserter
5719 #include <limits> // numeric_limits
5720 #include <string> // char_traits, string
5721 #include <utility> // make_pair, move
5722 #include <vector> // vector
5723 #include <map> // map
5724 
5725 // #include <nlohmann/detail/exceptions.hpp>
5726 
5727 // #include <nlohmann/detail/input/input_adapters.hpp>
5728 
5729 
5730 #include <array> // array
5731 #include <cstddef> // size_t
5732 #include <cstring> // strlen
5733 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
5734 #include <memory> // shared_ptr, make_shared, addressof
5735 #include <numeric> // accumulate
5736 #include <string> // string, char_traits
5737 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
5738 #include <utility> // pair, declval
5739 
5740 #ifndef JSON_NO_IO
5741  #include <cstdio> // FILE *
5742  #include <istream> // istream
5743 #endif // JSON_NO_IO
5744 
5745 // #include <nlohmann/detail/iterators/iterator_traits.hpp>
5746 
5747 // #include <nlohmann/detail/macro_scope.hpp>
5748 
5749 
5750 namespace nlohmann
5751 {
5752 namespace detail
5753 {
5756 
5758 // input adapters //
5760 
5761 #ifndef JSON_NO_IO
5767 {
5768  public:
5769  using char_type = char;
5770 
5772  explicit file_input_adapter(std::FILE* f) noexcept
5773  : m_file(f)
5774  {}
5775 
5776  // make class move-only
5779  file_input_adapter& operator=(const file_input_adapter&) = delete;
5780  file_input_adapter& operator=(file_input_adapter&&) = delete;
5781  ~file_input_adapter() = default;
5782 
5783  std::char_traits<char>::int_type get_character() noexcept
5784  {
5785  return std::fgetc(m_file);
5786  }
5787 
5788  private:
5790  std::FILE* m_file;
5791 };
5792 
5793 
5804 {
5805  public:
5806  using char_type = char;
5807 
5809  {
5810  // clear stream flags; we use underlying streambuf I/O, do not
5811  // maintain ifstream flags, except eof
5812  if (is != nullptr)
5813  {
5814  is->clear(is->rdstate() & std::ios::eofbit);
5815  }
5816  }
5817 
5818  explicit input_stream_adapter(std::istream& i)
5819  : is(&i), sb(i.rdbuf())
5820  {}
5821 
5822  // delete because of pointer members
5826 
5828  : is(rhs.is), sb(rhs.sb)
5829  {
5830  rhs.is = nullptr;
5831  rhs.sb = nullptr;
5832  }
5833 
5834  // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to
5835  // ensure that std::char_traits<char>::eof() and the character 0xFF do not
5836  // end up as the same value, e.g. 0xFFFFFFFF.
5837  std::char_traits<char>::int_type get_character()
5838  {
5839  auto res = sb->sbumpc();
5840  // set eof manually, as we don't use the istream interface.
5841  if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
5842  {
5843  is->clear(is->rdstate() | std::ios::eofbit);
5844  }
5845  return res;
5846  }
5847 
5848  private:
5850  std::istream* is = nullptr;
5851  std::streambuf* sb = nullptr;
5852 };
5853 #endif // JSON_NO_IO
5854 
5855 // General-purpose iterator-based adapter. It might not be as fast as
5856 // theoretically possible for some containers, but it is extremely versatile.
5857 template<typename IteratorType>
5859 {
5860  public:
5861  using char_type = typename std::iterator_traits<IteratorType>::value_type;
5862 
5863  iterator_input_adapter(IteratorType first, IteratorType last)
5864  : current(std::move(first)), end(std::move(last))
5865  {}
5866 
5867  typename std::char_traits<char_type>::int_type get_character()
5868  {
5869  if (JSON_HEDLEY_LIKELY(current != end))
5870  {
5871  auto result = std::char_traits<char_type>::to_int_type(*current);
5872  std::advance(current, 1);
5873  return result;
5874  }
5875 
5876  return std::char_traits<char_type>::eof();
5877  }
5878 
5879  private:
5880  IteratorType current;
5881  IteratorType end;
5882 
5883  template<typename BaseInputAdapter, size_t T>
5885 
5886  bool empty() const
5887  {
5888  return current == end;
5889  }
5890 };
5891 
5892 
5893 template<typename BaseInputAdapter, size_t T>
5895 
5896 template<typename BaseInputAdapter>
5897 struct wide_string_input_helper<BaseInputAdapter, 4>
5898 {
5899  // UTF-32
5900  static void fill_buffer(BaseInputAdapter& input,
5901  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5902  size_t& utf8_bytes_index,
5903  size_t& utf8_bytes_filled)
5904  {
5905  utf8_bytes_index = 0;
5906 
5907  if (JSON_HEDLEY_UNLIKELY(input.empty()))
5908  {
5909  utf8_bytes[0] = std::char_traits<char>::eof();
5910  utf8_bytes_filled = 1;
5911  }
5912  else
5913  {
5914  // get the current character
5915  const auto wc = input.get_character();
5916 
5917  // UTF-32 to UTF-8 encoding
5918  if (wc < 0x80)
5919  {
5920  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5921  utf8_bytes_filled = 1;
5922  }
5923  else if (wc <= 0x7FF)
5924  {
5925  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
5926  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5927  utf8_bytes_filled = 2;
5928  }
5929  else if (wc <= 0xFFFF)
5930  {
5931  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
5932  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5933  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5934  utf8_bytes_filled = 3;
5935  }
5936  else if (wc <= 0x10FFFF)
5937  {
5938  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
5939  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
5940  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5941  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5942  utf8_bytes_filled = 4;
5943  }
5944  else
5945  {
5946  // unknown character
5947  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5948  utf8_bytes_filled = 1;
5949  }
5950  }
5951  }
5952 };
5953 
5954 template<typename BaseInputAdapter>
5955 struct wide_string_input_helper<BaseInputAdapter, 2>
5956 {
5957  // UTF-16
5958  static void fill_buffer(BaseInputAdapter& input,
5959  std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
5960  size_t& utf8_bytes_index,
5961  size_t& utf8_bytes_filled)
5962  {
5963  utf8_bytes_index = 0;
5964 
5965  if (JSON_HEDLEY_UNLIKELY(input.empty()))
5966  {
5967  utf8_bytes[0] = std::char_traits<char>::eof();
5968  utf8_bytes_filled = 1;
5969  }
5970  else
5971  {
5972  // get the current character
5973  const auto wc = input.get_character();
5974 
5975  // UTF-16 to UTF-8 encoding
5976  if (wc < 0x80)
5977  {
5978  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
5979  utf8_bytes_filled = 1;
5980  }
5981  else if (wc <= 0x7FF)
5982  {
5983  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
5984  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5985  utf8_bytes_filled = 2;
5986  }
5987  else if (0xD800 > wc || wc >= 0xE000)
5988  {
5989  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
5990  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
5991  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
5992  utf8_bytes_filled = 3;
5993  }
5994  else
5995  {
5996  if (JSON_HEDLEY_UNLIKELY(!input.empty()))
5997  {
5998  const auto wc2 = static_cast<unsigned int>(input.get_character());
5999  const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
6000  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
6001  utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
6002  utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
6003  utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
6004  utf8_bytes_filled = 4;
6005  }
6006  else
6007  {
6008  utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
6009  utf8_bytes_filled = 1;
6010  }
6011  }
6012  }
6013  }
6014 };
6015 
6016 // Wraps another input apdater to convert wide character types into individual bytes.
6017 template<typename BaseInputAdapter, typename WideCharType>
6019 {
6020  public:
6021  using char_type = char;
6022 
6023  wide_string_input_adapter(BaseInputAdapter base)
6024  : base_adapter(base) {}
6025 
6026  typename std::char_traits<char>::int_type get_character() noexcept
6027  {
6028  // check if buffer needs to be filled
6029  if (utf8_bytes_index == utf8_bytes_filled)
6030  {
6031  fill_buffer<sizeof(WideCharType)>();
6032 
6033  JSON_ASSERT(utf8_bytes_filled > 0);
6034  JSON_ASSERT(utf8_bytes_index == 0);
6035  }
6036 
6037  // use buffer
6038  JSON_ASSERT(utf8_bytes_filled > 0);
6039  JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
6040  return utf8_bytes[utf8_bytes_index++];
6041  }
6042 
6043  private:
6044  BaseInputAdapter base_adapter;
6045 
6046  template<size_t T>
6047  void fill_buffer()
6048  {
6049  wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
6050  }
6051 
6053  std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
6054 
6056  std::size_t utf8_bytes_index = 0;
6058  std::size_t utf8_bytes_filled = 0;
6059 };
6060 
6061 
6062 template<typename IteratorType, typename Enable = void>
6064 {
6065  using iterator_type = IteratorType;
6066  using char_type = typename std::iterator_traits<iterator_type>::value_type;
6068 
6069  static adapter_type create(IteratorType first, IteratorType last)
6070  {
6071  return adapter_type(std::move(first), std::move(last));
6072  }
6073 };
6074 
6075 template<typename T>
6077 {
6078  using value_type = typename std::iterator_traits<T>::value_type;
6079  enum
6080  {
6081  value = sizeof(value_type) > 1
6082  };
6083 };
6084 
6085 template<typename IteratorType>
6087 {
6088  using iterator_type = IteratorType;
6089  using char_type = typename std::iterator_traits<iterator_type>::value_type;
6092 
6093  static adapter_type create(IteratorType first, IteratorType last)
6094  {
6095  return adapter_type(base_adapter_type(std::move(first), std::move(last)));
6096  }
6097 };
6098 
6099 // General purpose iterator-based input
6100 template<typename IteratorType>
6101 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
6102 {
6103  using factory_type = iterator_input_adapter_factory<IteratorType>;
6104  return factory_type::create(first, last);
6105 }
6106 
6107 // Convenience shorthand from container to iterator
6108 // Enables ADL on begin(container) and end(container)
6109 // Encloses the using declarations in namespace for not to leak them to outside scope
6110 
6111 namespace container_input_adapter_factory_impl
6112 {
6113 
6114 using std::begin;
6115 using std::end;
6116 
6117 template<typename ContainerType, typename Enable = void>
6119 
6120 template<typename ContainerType>
6121 struct container_input_adapter_factory< ContainerType,
6122  void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
6123  {
6124  using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
6125 
6126  static adapter_type create(const ContainerType& container)
6127 {
6128  return input_adapter(begin(container), end(container));
6129 }
6130  };
6131 
6132 } // namespace container_input_adapter_factory_impl
6133 
6134 template<typename ContainerType>
6136 {
6138 }
6139 
6140 #ifndef JSON_NO_IO
6141 // Special cases with fast paths
6142 inline file_input_adapter input_adapter(std::FILE* file)
6143 {
6144  return file_input_adapter(file);
6145 }
6146 
6147 inline input_stream_adapter input_adapter(std::istream& stream)
6148 {
6149  return input_stream_adapter(stream);
6150 }
6151 
6152 inline input_stream_adapter input_adapter(std::istream&& stream)
6153 {
6154  return input_stream_adapter(stream);
6155 }
6156 #endif // JSON_NO_IO
6157 
6158 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
6159 
6160 // Null-delimited strings, and the like.
6161 template < typename CharT,
6162  typename std::enable_if <
6163  std::is_pointer<CharT>::value&&
6164  !std::is_array<CharT>::value&&
6166  sizeof(typename std::remove_pointer<CharT>::type) == 1,
6167  int >::type = 0 >
6169 {
6170  auto length = std::strlen(reinterpret_cast<const char*>(b));
6171  const auto* ptr = reinterpret_cast<const char*>(b);
6172  return input_adapter(ptr, ptr + length);
6173 }
6174 
6175 template<typename T, std::size_t N>
6176 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
6177 {
6178  return input_adapter(array, array + N);
6179 }
6180 
6181 // This class only handles inputs of input_buffer_adapter type.
6182 // It's required so that expressions like {ptr, len} can be implicitly cast
6183 // to the correct adapter.
6185 {
6186  public:
6187  template < typename CharT,
6188  typename std::enable_if <
6189  std::is_pointer<CharT>::value&&
6191  sizeof(typename std::remove_pointer<CharT>::type) == 1,
6192  int >::type = 0 >
6193  span_input_adapter(CharT b, std::size_t l)
6194  : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
6195 
6196  template<class IteratorType,
6197  typename std::enable_if<
6198  std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
6199  int>::type = 0>
6200  span_input_adapter(IteratorType first, IteratorType last)
6201  : ia(input_adapter(first, last)) {}
6202 
6204  {
6205  return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg)
6206  }
6207 
6208  private:
6210 };
6211 } // namespace detail
6212 } // namespace nlohmann
6213 
6214 // #include <nlohmann/detail/input/json_sax.hpp>
6215 
6216 
6217 #include <cstddef>
6218 #include <string> // string
6219 #include <utility> // move
6220 #include <vector> // vector
6221 
6222 // #include <nlohmann/detail/exceptions.hpp>
6223 
6224 // #include <nlohmann/detail/macro_scope.hpp>
6225 
6226 // #include <nlohmann/detail/string_concat.hpp>
6227 
6228 
6229 namespace nlohmann
6230 {
6231 
6240 template<typename BasicJsonType>
6241 struct json_sax
6242 {
6243  using number_integer_t = typename BasicJsonType::number_integer_t;
6244  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6245  using number_float_t = typename BasicJsonType::number_float_t;
6246  using string_t = typename BasicJsonType::string_t;
6247  using binary_t = typename BasicJsonType::binary_t;
6248 
6253  virtual bool null() = 0;
6254 
6260  virtual bool boolean(bool val) = 0;
6261 
6267  virtual bool number_integer(number_integer_t val) = 0;
6268 
6274  virtual bool number_unsigned(number_unsigned_t val) = 0;
6275 
6282  virtual bool number_float(number_float_t val, const string_t& s) = 0;
6283 
6290  virtual bool string(string_t& val) = 0;
6291 
6298  virtual bool binary(binary_t& val) = 0;
6299 
6306  virtual bool start_object(std::size_t elements) = 0;
6307 
6314  virtual bool key(string_t& val) = 0;
6315 
6320  virtual bool end_object() = 0;
6321 
6328  virtual bool start_array(std::size_t elements) = 0;
6329 
6334  virtual bool end_array() = 0;
6335 
6343  virtual bool parse_error(std::size_t position,
6344  const std::string& last_token,
6345  const detail::exception& ex) = 0;
6346 
6347  json_sax() = default;
6348  json_sax(const json_sax&) = default;
6349  json_sax(json_sax&&) noexcept = default;
6350  json_sax& operator=(const json_sax&) = default;
6351  json_sax& operator=(json_sax&&) noexcept = default;
6352  virtual ~json_sax() = default;
6353 };
6354 
6355 
6356 namespace detail
6357 {
6371 template<typename BasicJsonType>
6373 {
6374  public:
6375  using number_integer_t = typename BasicJsonType::number_integer_t;
6376  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6377  using number_float_t = typename BasicJsonType::number_float_t;
6378  using string_t = typename BasicJsonType::string_t;
6379  using binary_t = typename BasicJsonType::binary_t;
6380 
6386  explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptions_ = true)
6387  : root(r), allow_exceptions(allow_exceptions_)
6388  {}
6389 
6390  // make class move-only
6392  json_sax_dom_parser(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6394  json_sax_dom_parser& operator=(json_sax_dom_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6396 
6397  bool null()
6398  {
6399  handle_value(nullptr);
6400  return true;
6401  }
6402 
6403  bool boolean(bool val)
6404  {
6405  handle_value(val);
6406  return true;
6407  }
6408 
6410  {
6411  handle_value(val);
6412  return true;
6413  }
6414 
6416  {
6417  handle_value(val);
6418  return true;
6419  }
6420 
6421  bool number_float(number_float_t val, const string_t& /*unused*/)
6422  {
6423  handle_value(val);
6424  return true;
6425  }
6426 
6427  bool string(string_t& val)
6428  {
6429  handle_value(val);
6430  return true;
6431  }
6432 
6433  bool binary(binary_t& val)
6434  {
6435  handle_value(std::move(val));
6436  return true;
6437  }
6438 
6439  bool start_object(std::size_t len)
6440  {
6441  ref_stack.push_back(handle_value(BasicJsonType::value_t::object));
6442 
6443  if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6444  {
6445  JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6446  }
6447 
6448  return true;
6449  }
6450 
6451  bool key(string_t& val)
6452  {
6453  JSON_ASSERT(!ref_stack.empty());
6454  JSON_ASSERT(ref_stack.back()->is_object());
6455 
6456  // add null at given key and store the reference for later
6457  object_element = &(ref_stack.back()->m_value.object->operator[](val));
6458  return true;
6459  }
6460 
6461  bool end_object()
6462  {
6463  JSON_ASSERT(!ref_stack.empty());
6464  JSON_ASSERT(ref_stack.back()->is_object());
6465 
6466  ref_stack.back()->set_parents();
6467  ref_stack.pop_back();
6468  return true;
6469  }
6470 
6471  bool start_array(std::size_t len)
6472  {
6473  ref_stack.push_back(handle_value(BasicJsonType::value_t::array));
6474 
6475  if (JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6476  {
6477  JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6478  }
6479 
6480  return true;
6481  }
6482 
6483  bool end_array()
6484  {
6485  JSON_ASSERT(!ref_stack.empty());
6486  JSON_ASSERT(ref_stack.back()->is_array());
6487 
6488  ref_stack.back()->set_parents();
6489  ref_stack.pop_back();
6490  return true;
6491  }
6492 
6493  template<class Exception>
6494  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6495  const Exception& ex)
6496  {
6497  errored = true;
6498  static_cast<void>(ex);
6499  if (allow_exceptions)
6500  {
6501  JSON_THROW(ex);
6502  }
6503  return false;
6504  }
6505 
6506  constexpr bool is_errored() const
6507  {
6508  return errored;
6509  }
6510 
6511  private:
6518  template<typename Value>
6520  BasicJsonType* handle_value(Value&& v)
6521  {
6522  if (ref_stack.empty())
6523  {
6524  root = BasicJsonType(std::forward<Value>(v));
6525  return &root;
6526  }
6527 
6528  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6529 
6530  if (ref_stack.back()->is_array())
6531  {
6532  ref_stack.back()->m_value.array->emplace_back(std::forward<Value>(v));
6533  return &(ref_stack.back()->m_value.array->back());
6534  }
6535 
6536  JSON_ASSERT(ref_stack.back()->is_object());
6537  JSON_ASSERT(object_element);
6538  *object_element = BasicJsonType(std::forward<Value>(v));
6539  return object_element;
6540  }
6541 
6543  BasicJsonType& root;
6545  std::vector<BasicJsonType*> ref_stack {};
6547  BasicJsonType* object_element = nullptr;
6549  bool errored = false;
6551  const bool allow_exceptions = true;
6552 };
6553 
6554 template<typename BasicJsonType>
6556 {
6557  public:
6558  using number_integer_t = typename BasicJsonType::number_integer_t;
6559  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6560  using number_float_t = typename BasicJsonType::number_float_t;
6561  using string_t = typename BasicJsonType::string_t;
6562  using binary_t = typename BasicJsonType::binary_t;
6565 
6567  const parser_callback_t cb,
6568  const bool allow_exceptions_ = true)
6569  : root(r), callback(cb), allow_exceptions(allow_exceptions_)
6570  {
6571  keep_stack.push_back(true);
6572  }
6573 
6574  // make class move-only
6576  json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6578  json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
6580 
6581  bool null()
6582  {
6583  handle_value(nullptr);
6584  return true;
6585  }
6586 
6587  bool boolean(bool val)
6588  {
6589  handle_value(val);
6590  return true;
6591  }
6592 
6594  {
6595  handle_value(val);
6596  return true;
6597  }
6598 
6600  {
6601  handle_value(val);
6602  return true;
6603  }
6604 
6605  bool number_float(number_float_t val, const string_t& /*unused*/)
6606  {
6607  handle_value(val);
6608  return true;
6609  }
6610 
6611  bool string(string_t& val)
6612  {
6613  handle_value(val);
6614  return true;
6615  }
6616 
6617  bool binary(binary_t& val)
6618  {
6619  handle_value(std::move(val));
6620  return true;
6621  }
6622 
6623  bool start_object(std::size_t len)
6624  {
6625  // check callback for object start
6626  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::object_start, discarded);
6627  keep_stack.push_back(keep);
6628 
6629  auto val = handle_value(BasicJsonType::value_t::object, true);
6630  ref_stack.push_back(val.second);
6631 
6632  // check object limit
6633  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6634  {
6635  JSON_THROW(out_of_range::create(408, concat("excessive object size: ", std::to_string(len)), ref_stack.back()));
6636  }
6637 
6638  return true;
6639  }
6640 
6641  bool key(string_t& val)
6642  {
6643  BasicJsonType k = BasicJsonType(val);
6644 
6645  // check callback for key
6646  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::key, k);
6647  key_keep_stack.push_back(keep);
6648 
6649  // add discarded value at given key and store the reference for later
6650  if (keep && ref_stack.back())
6651  {
6652  object_element = &(ref_stack.back()->m_value.object->operator[](val) = discarded);
6653  }
6654 
6655  return true;
6656  }
6657 
6658  bool end_object()
6659  {
6660  if (ref_stack.back())
6661  {
6662  if (!callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::object_end, *ref_stack.back()))
6663  {
6664  // discard object
6665  *ref_stack.back() = discarded;
6666  }
6667  else
6668  {
6669  ref_stack.back()->set_parents();
6670  }
6671  }
6672 
6673  JSON_ASSERT(!ref_stack.empty());
6674  JSON_ASSERT(!keep_stack.empty());
6675  ref_stack.pop_back();
6676  keep_stack.pop_back();
6677 
6678  if (!ref_stack.empty() && ref_stack.back() && ref_stack.back()->is_structured())
6679  {
6680  // remove discarded value
6681  for (auto it = ref_stack.back()->begin(); it != ref_stack.back()->end(); ++it)
6682  {
6683  if (it->is_discarded())
6684  {
6685  ref_stack.back()->erase(it);
6686  break;
6687  }
6688  }
6689  }
6690 
6691  return true;
6692  }
6693 
6694  bool start_array(std::size_t len)
6695  {
6696  const bool keep = callback(static_cast<int>(ref_stack.size()), parse_event_t::array_start, discarded);
6697  keep_stack.push_back(keep);
6698 
6699  auto val = handle_value(BasicJsonType::value_t::array, true);
6700  ref_stack.push_back(val.second);
6701 
6702  // check array limit
6703  if (ref_stack.back() && JSON_HEDLEY_UNLIKELY(len != static_cast<std::size_t>(-1) && len > ref_stack.back()->max_size()))
6704  {
6705  JSON_THROW(out_of_range::create(408, concat("excessive array size: ", std::to_string(len)), ref_stack.back()));
6706  }
6707 
6708  return true;
6709  }
6710 
6711  bool end_array()
6712  {
6713  bool keep = true;
6714 
6715  if (ref_stack.back())
6716  {
6717  keep = callback(static_cast<int>(ref_stack.size()) - 1, parse_event_t::array_end, *ref_stack.back());
6718  if (keep)
6719  {
6720  ref_stack.back()->set_parents();
6721  }
6722  else
6723  {
6724  // discard array
6725  *ref_stack.back() = discarded;
6726  }
6727  }
6728 
6729  JSON_ASSERT(!ref_stack.empty());
6730  JSON_ASSERT(!keep_stack.empty());
6731  ref_stack.pop_back();
6732  keep_stack.pop_back();
6733 
6734  // remove discarded value
6735  if (!keep && !ref_stack.empty() && ref_stack.back()->is_array())
6736  {
6737  ref_stack.back()->m_value.array->pop_back();
6738  }
6739 
6740  return true;
6741  }
6742 
6743  template<class Exception>
6744  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
6745  const Exception& ex)
6746  {
6747  errored = true;
6748  static_cast<void>(ex);
6749  if (allow_exceptions)
6750  {
6751  JSON_THROW(ex);
6752  }
6753  return false;
6754  }
6755 
6756  constexpr bool is_errored() const
6757  {
6758  return errored;
6759  }
6760 
6761  private:
6777  template<typename Value>
6778  std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool skip_callback = false)
6779  {
6780  JSON_ASSERT(!keep_stack.empty());
6781 
6782  // do not handle this value if we know it would be added to a discarded
6783  // container
6784  if (!keep_stack.back())
6785  {
6786  return {false, nullptr};
6787  }
6788 
6789  // create value
6790  auto value = BasicJsonType(std::forward<Value>(v));
6791 
6792  // check callback
6793  const bool keep = skip_callback || callback(static_cast<int>(ref_stack.size()), parse_event_t::value, value);
6794 
6795  // do not handle this value if we just learnt it shall be discarded
6796  if (!keep)
6797  {
6798  return {false, nullptr};
6799  }
6800 
6801  if (ref_stack.empty())
6802  {
6803  root = std::move(value);
6804  return {true, &root};
6805  }
6806 
6807  // skip this value if we already decided to skip the parent
6808  // (https://github.com/nlohmann/json/issues/971#issuecomment-413678360)
6809  if (!ref_stack.back())
6810  {
6811  return {false, nullptr};
6812  }
6813 
6814  // we now only expect arrays and objects
6815  JSON_ASSERT(ref_stack.back()->is_array() || ref_stack.back()->is_object());
6816 
6817  // array
6818  if (ref_stack.back()->is_array())
6819  {
6820  ref_stack.back()->m_value.array->emplace_back(std::move(value));
6821  return {true, &(ref_stack.back()->m_value.array->back())};
6822  }
6823 
6824  // object
6825  JSON_ASSERT(ref_stack.back()->is_object());
6826  // check if we should store an element for the current key
6827  JSON_ASSERT(!key_keep_stack.empty());
6828  const bool store_element = key_keep_stack.back();
6829  key_keep_stack.pop_back();
6830 
6831  if (!store_element)
6832  {
6833  return {false, nullptr};
6834  }
6835 
6836  JSON_ASSERT(object_element);
6837  *object_element = std::move(value);
6838  return {true, object_element};
6839  }
6840 
6842  BasicJsonType& root;
6844  std::vector<BasicJsonType*> ref_stack {};
6846  std::vector<bool> keep_stack {};
6848  std::vector<bool> key_keep_stack {};
6850  BasicJsonType* object_element = nullptr;
6852  bool errored = false;
6854  const parser_callback_t callback = nullptr;
6856  const bool allow_exceptions = true;
6858  BasicJsonType discarded = BasicJsonType::value_t::discarded;
6859 };
6860 
6861 template<typename BasicJsonType>
6863 {
6864  public:
6865  using number_integer_t = typename BasicJsonType::number_integer_t;
6866  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
6867  using number_float_t = typename BasicJsonType::number_float_t;
6868  using string_t = typename BasicJsonType::string_t;
6869  using binary_t = typename BasicJsonType::binary_t;
6870 
6871  bool null()
6872  {
6873  return true;
6874  }
6875 
6876  bool boolean(bool /*unused*/)
6877  {
6878  return true;
6879  }
6880 
6882  {
6883  return true;
6884  }
6885 
6887  {
6888  return true;
6889  }
6890 
6891  bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
6892  {
6893  return true;
6894  }
6895 
6896  bool string(string_t& /*unused*/)
6897  {
6898  return true;
6899  }
6900 
6901  bool binary(binary_t& /*unused*/)
6902  {
6903  return true;
6904  }
6905 
6906  bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
6907  {
6908  return true;
6909  }
6910 
6911  bool key(string_t& /*unused*/)
6912  {
6913  return true;
6914  }
6915 
6916  bool end_object()
6917  {
6918  return true;
6919  }
6920 
6921  bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
6922  {
6923  return true;
6924  }
6925 
6926  bool end_array()
6927  {
6928  return true;
6929  }
6930 
6931  bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/, const detail::exception& /*unused*/)
6932  {
6933  return false;
6934  }
6935 };
6936 } // namespace detail
6937 
6938 } // namespace nlohmann
6939 
6940 // #include <nlohmann/detail/input/lexer.hpp>
6941 
6942 
6943 #include <array> // array
6944 #include <clocale> // localeconv
6945 #include <cstddef> // size_t
6946 #include <cstdio> // snprintf
6947 #include <cstdlib> // strtof, strtod, strtold, strtoll, strtoull
6948 #include <initializer_list> // initializer_list
6949 #include <string> // char_traits, string
6950 #include <utility> // move
6951 #include <vector> // vector
6952 
6953 // #include <nlohmann/detail/input/input_adapters.hpp>
6954 
6955 // #include <nlohmann/detail/input/position_t.hpp>
6956 
6957 // #include <nlohmann/detail/macro_scope.hpp>
6958 
6959 
6960 namespace nlohmann
6961 {
6962 namespace detail
6963 {
6965 // lexer //
6967 
6968 template<typename BasicJsonType>
6970 {
6971  public:
6973  enum class token_type
6974  {
6975  uninitialized,
6976  literal_true,
6977  literal_false,
6978  literal_null,
6979  value_string,
6980  value_unsigned,
6981  value_integer,
6982  value_float,
6983  begin_array,
6984  begin_object,
6985  end_array,
6986  end_object,
6987  name_separator,
6988  value_separator,
6989  parse_error,
6990  end_of_input,
6992  };
6993 
6997  static const char* token_type_name(const token_type t) noexcept
6998  {
6999  switch (t)
7000  {
7002  return "<uninitialized>";
7004  return "true literal";
7006  return "false literal";
7008  return "null literal";
7010  return "string literal";
7014  return "number literal";
7016  return "'['";
7018  return "'{'";
7019  case token_type::end_array:
7020  return "']'";
7022  return "'}'";
7024  return "':'";
7026  return "','";
7028  return "<parse error>";
7030  return "end of input";
7032  return "'[', '{', or a literal";
7033  // LCOV_EXCL_START
7034  default: // catch non-enum values
7035  return "unknown token";
7036  // LCOV_EXCL_STOP
7037  }
7038  }
7039 };
7045 template<typename BasicJsonType, typename InputAdapterType>
7046 class lexer : public lexer_base<BasicJsonType>
7047 {
7048  using number_integer_t = typename BasicJsonType::number_integer_t;
7049  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
7050  using number_float_t = typename BasicJsonType::number_float_t;
7051  using string_t = typename BasicJsonType::string_t;
7052  using char_type = typename InputAdapterType::char_type;
7053  using char_int_type = typename std::char_traits<char_type>::int_type;
7054 
7055  public:
7057 
7058  explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) noexcept
7059  : ia(std::move(adapter))
7060  , ignore_comments(ignore_comments_)
7061  , decimal_point_char(static_cast<char_int_type>(get_decimal_point()))
7062  {}
7063 
7064  // delete because of pointer members
7065  lexer(const lexer&) = delete;
7066  lexer(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7067  lexer& operator=(lexer&) = delete;
7068  lexer& operator=(lexer&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
7069  ~lexer() = default;
7070 
7071  private:
7073  // locales
7075 
7078  static char get_decimal_point() noexcept
7079  {
7080  const auto* loc = localeconv();
7081  JSON_ASSERT(loc != nullptr);
7082  return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point);
7083  }
7084 
7086  // scan functions
7088 
7104  int get_codepoint()
7105  {
7106  // this function only makes sense after reading `\u`
7107  JSON_ASSERT(current == 'u');
7108  int codepoint = 0;
7109 
7110  const auto factors = { 12u, 8u, 4u, 0u };
7111  for (const auto factor : factors)
7112  {
7113  get();
7114 
7115  if (current >= '0' && current <= '9')
7116  {
7117  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x30u) << factor);
7118  }
7119  else if (current >= 'A' && current <= 'F')
7120  {
7121  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x37u) << factor);
7122  }
7123  else if (current >= 'a' && current <= 'f')
7124  {
7125  codepoint += static_cast<int>((static_cast<unsigned int>(current) - 0x57u) << factor);
7126  }
7127  else
7128  {
7129  return -1;
7130  }
7131  }
7132 
7133  JSON_ASSERT(0x0000 <= codepoint && codepoint <= 0xFFFF);
7134  return codepoint;
7135  }
7136 
7152  bool next_byte_in_range(std::initializer_list<char_int_type> ranges)
7153  {
7154  JSON_ASSERT(ranges.size() == 2 || ranges.size() == 4 || ranges.size() == 6);
7155  add(current);
7156 
7157  for (auto range = ranges.begin(); range != ranges.end(); ++range)
7158  {
7159  get();
7160  if (JSON_HEDLEY_LIKELY(*range <= current && current <= *(++range)))
7161  {
7162  add(current);
7163  }
7164  else
7165  {
7166  error_message = "invalid string: ill-formed UTF-8 byte";
7167  return false;
7168  }
7169  }
7170 
7171  return true;
7172  }
7173 
7189  token_type scan_string()
7190  {
7191  // reset token_buffer (ignore opening quote)
7192  reset();
7193 
7194  // we entered the function by reading an open quote
7195  JSON_ASSERT(current == '\"');
7196 
7197  while (true)
7198  {
7199  // get next character
7200  switch (get())
7201  {
7202  // end of file while parsing string
7203  case std::char_traits<char_type>::eof():
7204  {
7205  error_message = "invalid string: missing closing quote";
7206  return token_type::parse_error;
7207  }
7208 
7209  // closing quote
7210  case '\"':
7211  {
7212  return token_type::value_string;
7213  }
7214 
7215  // escapes
7216  case '\\':
7217  {
7218  switch (get())
7219  {
7220  // quotation mark
7221  case '\"':
7222  add('\"');
7223  break;
7224  // reverse solidus
7225  case '\\':
7226  add('\\');
7227  break;
7228  // solidus
7229  case '/':
7230  add('/');
7231  break;
7232  // backspace
7233  case 'b':
7234  add('\b');
7235  break;
7236  // form feed
7237  case 'f':
7238  add('\f');
7239  break;
7240  // line feed
7241  case 'n':
7242  add('\n');
7243  break;
7244  // carriage return
7245  case 'r':
7246  add('\r');
7247  break;
7248  // tab
7249  case 't':
7250  add('\t');
7251  break;
7252 
7253  // unicode escapes
7254  case 'u':
7255  {
7256  const int codepoint1 = get_codepoint();
7257  int codepoint = codepoint1; // start with codepoint1
7258 
7259  if (JSON_HEDLEY_UNLIKELY(codepoint1 == -1))
7260  {
7261  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7262  return token_type::parse_error;
7263  }
7264 
7265  // check if code point is a high surrogate
7266  if (0xD800 <= codepoint1 && codepoint1 <= 0xDBFF)
7267  {
7268  // expect next \uxxxx entry
7269  if (JSON_HEDLEY_LIKELY(get() == '\\' && get() == 'u'))
7270  {
7271  const int codepoint2 = get_codepoint();
7272 
7273  if (JSON_HEDLEY_UNLIKELY(codepoint2 == -1))
7274  {
7275  error_message = "invalid string: '\\u' must be followed by 4 hex digits";
7276  return token_type::parse_error;
7277  }
7278 
7279  // check if codepoint2 is a low surrogate
7280  if (JSON_HEDLEY_LIKELY(0xDC00 <= codepoint2 && codepoint2 <= 0xDFFF))
7281  {
7282  // overwrite codepoint
7283  codepoint = static_cast<int>(
7284  // high surrogate occupies the most significant 22 bits
7285  (static_cast<unsigned int>(codepoint1) << 10u)
7286  // low surrogate occupies the least significant 15 bits
7287  + static_cast<unsigned int>(codepoint2)
7288  // there is still the 0xD800, 0xDC00 and 0x10000 noise
7289  // in the result, so we have to subtract with:
7290  // (0xD800 << 10) + DC00 - 0x10000 = 0x35FDC00
7291  - 0x35FDC00u);
7292  }
7293  else
7294  {
7295  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7296  return token_type::parse_error;
7297  }
7298  }
7299  else
7300  {
7301  error_message = "invalid string: surrogate U+D800..U+DBFF must be followed by U+DC00..U+DFFF";
7302  return token_type::parse_error;
7303  }
7304  }
7305  else
7306  {
7307  if (JSON_HEDLEY_UNLIKELY(0xDC00 <= codepoint1 && codepoint1 <= 0xDFFF))
7308  {
7309  error_message = "invalid string: surrogate U+DC00..U+DFFF must follow U+D800..U+DBFF";
7310  return token_type::parse_error;
7311  }
7312  }
7313 
7314  // result of the above calculation yields a proper codepoint
7315  JSON_ASSERT(0x00 <= codepoint && codepoint <= 0x10FFFF);
7316 
7317  // translate codepoint into bytes
7318  if (codepoint < 0x80)
7319  {
7320  // 1-byte characters: 0xxxxxxx (ASCII)
7321  add(static_cast<char_int_type>(codepoint));
7322  }
7323  else if (codepoint <= 0x7FF)
7324  {
7325  // 2-byte characters: 110xxxxx 10xxxxxx
7326  add(static_cast<char_int_type>(0xC0u | (static_cast<unsigned int>(codepoint) >> 6u)));
7327  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7328  }
7329  else if (codepoint <= 0xFFFF)
7330  {
7331  // 3-byte characters: 1110xxxx 10xxxxxx 10xxxxxx
7332  add(static_cast<char_int_type>(0xE0u | (static_cast<unsigned int>(codepoint) >> 12u)));
7333  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7334  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7335  }
7336  else
7337  {
7338  // 4-byte characters: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
7339  add(static_cast<char_int_type>(0xF0u | (static_cast<unsigned int>(codepoint) >> 18u)));
7340  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 12u) & 0x3Fu)));
7341  add(static_cast<char_int_type>(0x80u | ((static_cast<unsigned int>(codepoint) >> 6u) & 0x3Fu)));
7342  add(static_cast<char_int_type>(0x80u | (static_cast<unsigned int>(codepoint) & 0x3Fu)));
7343  }
7344 
7345  break;
7346  }
7347 
7348  // other characters after escape
7349  default:
7350  error_message = "invalid string: forbidden character after backslash";
7351  return token_type::parse_error;
7352  }
7353 
7354  break;
7355  }
7356 
7357  // invalid control characters
7358  case 0x00:
7359  {
7360  error_message = "invalid string: control character U+0000 (NUL) must be escaped to \\u0000";
7361  return token_type::parse_error;
7362  }
7363 
7364  case 0x01:
7365  {
7366  error_message = "invalid string: control character U+0001 (SOH) must be escaped to \\u0001";
7367  return token_type::parse_error;
7368  }
7369 
7370  case 0x02:
7371  {
7372  error_message = "invalid string: control character U+0002 (STX) must be escaped to \\u0002";
7373  return token_type::parse_error;
7374  }
7375 
7376  case 0x03:
7377  {
7378  error_message = "invalid string: control character U+0003 (ETX) must be escaped to \\u0003";
7379  return token_type::parse_error;
7380  }
7381 
7382  case 0x04:
7383  {
7384  error_message = "invalid string: control character U+0004 (EOT) must be escaped to \\u0004";
7385  return token_type::parse_error;
7386  }
7387 
7388  case 0x05:
7389  {
7390  error_message = "invalid string: control character U+0005 (ENQ) must be escaped to \\u0005";
7391  return token_type::parse_error;
7392  }
7393 
7394  case 0x06:
7395  {
7396  error_message = "invalid string: control character U+0006 (ACK) must be escaped to \\u0006";
7397  return token_type::parse_error;
7398  }
7399 
7400  case 0x07:
7401  {
7402  error_message = "invalid string: control character U+0007 (BEL) must be escaped to \\u0007";
7403  return token_type::parse_error;
7404  }
7405 
7406  case 0x08:
7407  {
7408  error_message = "invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b";
7409  return token_type::parse_error;
7410  }
7411 
7412  case 0x09:
7413  {
7414  error_message = "invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t";
7415  return token_type::parse_error;
7416  }
7417 
7418  case 0x0A:
7419  {
7420  error_message = "invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n";
7421  return token_type::parse_error;
7422  }
7423 
7424  case 0x0B:
7425  {
7426  error_message = "invalid string: control character U+000B (VT) must be escaped to \\u000B";
7427  return token_type::parse_error;
7428  }
7429 
7430  case 0x0C:
7431  {
7432  error_message = "invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f";
7433  return token_type::parse_error;
7434  }
7435 
7436  case 0x0D:
7437  {
7438  error_message = "invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r";
7439  return token_type::parse_error;
7440  }
7441 
7442  case 0x0E:
7443  {
7444  error_message = "invalid string: control character U+000E (SO) must be escaped to \\u000E";
7445  return token_type::parse_error;
7446  }
7447 
7448  case 0x0F:
7449  {
7450  error_message = "invalid string: control character U+000F (SI) must be escaped to \\u000F";
7451  return token_type::parse_error;
7452  }
7453 
7454  case 0x10:
7455  {
7456  error_message = "invalid string: control character U+0010 (DLE) must be escaped to \\u0010";
7457  return token_type::parse_error;
7458  }
7459 
7460  case 0x11:
7461  {
7462  error_message = "invalid string: control character U+0011 (DC1) must be escaped to \\u0011";
7463  return token_type::parse_error;
7464  }
7465 
7466  case 0x12:
7467  {
7468  error_message = "invalid string: control character U+0012 (DC2) must be escaped to \\u0012";
7469  return token_type::parse_error;
7470  }
7471 
7472  case 0x13:
7473  {
7474  error_message = "invalid string: control character U+0013 (DC3) must be escaped to \\u0013";
7475  return token_type::parse_error;
7476  }
7477 
7478  case 0x14:
7479  {
7480  error_message = "invalid string: control character U+0014 (DC4) must be escaped to \\u0014";
7481  return token_type::parse_error;
7482  }
7483 
7484  case 0x15:
7485  {
7486  error_message = "invalid string: control character U+0015 (NAK) must be escaped to \\u0015";
7487  return token_type::parse_error;
7488  }
7489 
7490  case 0x16:
7491  {
7492  error_message = "invalid string: control character U+0016 (SYN) must be escaped to \\u0016";
7493  return token_type::parse_error;
7494  }
7495 
7496  case 0x17:
7497  {
7498  error_message = "invalid string: control character U+0017 (ETB) must be escaped to \\u0017";
7499  return token_type::parse_error;
7500  }
7501 
7502  case 0x18:
7503  {
7504  error_message = "invalid string: control character U+0018 (CAN) must be escaped to \\u0018";
7505  return token_type::parse_error;
7506  }
7507 
7508  case 0x19:
7509  {
7510  error_message = "invalid string: control character U+0019 (EM) must be escaped to \\u0019";
7511  return token_type::parse_error;
7512  }
7513 
7514  case 0x1A:
7515  {
7516  error_message = "invalid string: control character U+001A (SUB) must be escaped to \\u001A";
7517  return token_type::parse_error;
7518  }
7519 
7520  case 0x1B:
7521  {
7522  error_message = "invalid string: control character U+001B (ESC) must be escaped to \\u001B";
7523  return token_type::parse_error;
7524  }
7525 
7526  case 0x1C:
7527  {
7528  error_message = "invalid string: control character U+001C (FS) must be escaped to \\u001C";
7529  return token_type::parse_error;
7530  }
7531 
7532  case 0x1D:
7533  {
7534  error_message = "invalid string: control character U+001D (GS) must be escaped to \\u001D";
7535  return token_type::parse_error;
7536  }
7537 
7538  case 0x1E:
7539  {
7540  error_message = "invalid string: control character U+001E (RS) must be escaped to \\u001E";
7541  return token_type::parse_error;
7542  }
7543 
7544  case 0x1F:
7545  {
7546  error_message = "invalid string: control character U+001F (US) must be escaped to \\u001F";
7547  return token_type::parse_error;
7548  }
7549 
7550  // U+0020..U+007F (except U+0022 (quote) and U+005C (backspace))
7551  case 0x20:
7552  case 0x21:
7553  case 0x23:
7554  case 0x24:
7555  case 0x25:
7556  case 0x26:
7557  case 0x27:
7558  case 0x28:
7559  case 0x29:
7560  case 0x2A:
7561  case 0x2B:
7562  case 0x2C:
7563  case 0x2D:
7564  case 0x2E:
7565  case 0x2F:
7566  case 0x30:
7567  case 0x31:
7568  case 0x32:
7569  case 0x33:
7570  case 0x34:
7571  case 0x35:
7572  case 0x36:
7573  case 0x37:
7574  case 0x38:
7575  case 0x39:
7576  case 0x3A:
7577  case 0x3B:
7578  case 0x3C:
7579  case 0x3D:
7580  case 0x3E:
7581  case 0x3F:
7582  case 0x40:
7583  case 0x41:
7584  case 0x42:
7585  case 0x43:
7586  case 0x44:
7587  case 0x45:
7588  case 0x46:
7589  case 0x47:
7590  case 0x48:
7591  case 0x49:
7592  case 0x4A:
7593  case 0x4B:
7594  case 0x4C:
7595  case 0x4D:
7596  case 0x4E:
7597  case 0x4F:
7598  case 0x50:
7599  case 0x51:
7600  case 0x52:
7601  case 0x53:
7602  case 0x54:
7603  case 0x55:
7604  case 0x56:
7605  case 0x57:
7606  case 0x58:
7607  case 0x59:
7608  case 0x5A:
7609  case 0x5B:
7610  case 0x5D:
7611  case 0x5E:
7612  case 0x5F:
7613  case 0x60:
7614  case 0x61:
7615  case 0x62:
7616  case 0x63:
7617  case 0x64:
7618  case 0x65:
7619  case 0x66:
7620  case 0x67:
7621  case 0x68:
7622  case 0x69:
7623  case 0x6A:
7624  case 0x6B:
7625  case 0x6C:
7626  case 0x6D:
7627  case 0x6E:
7628  case 0x6F:
7629  case 0x70:
7630  case 0x71:
7631  case 0x72:
7632  case 0x73:
7633  case 0x74:
7634  case 0x75:
7635  case 0x76:
7636  case 0x77:
7637  case 0x78:
7638  case 0x79:
7639  case 0x7A:
7640  case 0x7B:
7641  case 0x7C:
7642  case 0x7D:
7643  case 0x7E:
7644  case 0x7F:
7645  {
7646  add(current);
7647  break;
7648  }
7649 
7650  // U+0080..U+07FF: bytes C2..DF 80..BF
7651  case 0xC2:
7652  case 0xC3:
7653  case 0xC4:
7654  case 0xC5:
7655  case 0xC6:
7656  case 0xC7:
7657  case 0xC8:
7658  case 0xC9:
7659  case 0xCA:
7660  case 0xCB:
7661  case 0xCC:
7662  case 0xCD:
7663  case 0xCE:
7664  case 0xCF:
7665  case 0xD0:
7666  case 0xD1:
7667  case 0xD2:
7668  case 0xD3:
7669  case 0xD4:
7670  case 0xD5:
7671  case 0xD6:
7672  case 0xD7:
7673  case 0xD8:
7674  case 0xD9:
7675  case 0xDA:
7676  case 0xDB:
7677  case 0xDC:
7678  case 0xDD:
7679  case 0xDE:
7680  case 0xDF:
7681  {
7682  if (JSON_HEDLEY_UNLIKELY(!next_byte_in_range({0x80, 0xBF})))
7683  {
7684  return token_type::parse_error;
7685  }
7686  break;
7687  }
7688 
7689  // U+0800..U+0FFF: bytes E0 A0..BF 80..BF
7690  case 0xE0:
7691  {
7692  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0xA0, 0xBF, 0x80, 0xBF}))))
7693  {
7694  return token_type::parse_error;
7695  }
7696  break;
7697  }
7698 
7699  // U+1000..U+CFFF: bytes E1..EC 80..BF 80..BF
7700  // U+E000..U+FFFF: bytes EE..EF 80..BF 80..BF
7701  case 0xE1:
7702  case 0xE2:
7703  case 0xE3:
7704  case 0xE4:
7705  case 0xE5:
7706  case 0xE6:
7707  case 0xE7:
7708  case 0xE8:
7709  case 0xE9:
7710  case 0xEA:
7711  case 0xEB:
7712  case 0xEC:
7713  case 0xEE:
7714  case 0xEF:
7715  {
7716  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF}))))
7717  {
7718  return token_type::parse_error;
7719  }
7720  break;
7721  }
7722 
7723  // U+D000..U+D7FF: bytes ED 80..9F 80..BF
7724  case 0xED:
7725  {
7726  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x9F, 0x80, 0xBF}))))
7727  {
7728  return token_type::parse_error;
7729  }
7730  break;
7731  }
7732 
7733  // U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
7734  case 0xF0:
7735  {
7736  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x90, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7737  {
7738  return token_type::parse_error;
7739  }
7740  break;
7741  }
7742 
7743  // U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
7744  case 0xF1:
7745  case 0xF2:
7746  case 0xF3:
7747  {
7748  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0xBF, 0x80, 0xBF, 0x80, 0xBF}))))
7749  {
7750  return token_type::parse_error;
7751  }
7752  break;
7753  }
7754 
7755  // U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
7756  case 0xF4:
7757  {
7758  if (JSON_HEDLEY_UNLIKELY(!(next_byte_in_range({0x80, 0x8F, 0x80, 0xBF, 0x80, 0xBF}))))
7759  {
7760  return token_type::parse_error;
7761  }
7762  break;
7763  }
7764 
7765  // remaining bytes (80..C1 and F5..FF) are ill-formed
7766  default:
7767  {
7768  error_message = "invalid string: ill-formed UTF-8 byte";
7769  return token_type::parse_error;
7770  }
7771  }
7772  }
7773  }
7774 
7779  bool scan_comment()
7780  {
7781  switch (get())
7782  {
7783  // single-line comments skip input until a newline or EOF is read
7784  case '/':
7785  {
7786  while (true)
7787  {
7788  switch (get())
7789  {
7790  case '\n':
7791  case '\r':
7792  case std::char_traits<char_type>::eof():
7793  case '\0':
7794  return true;
7795 
7796  default:
7797  break;
7798  }
7799  }
7800  }
7801 
7802  // multi-line comments skip input until */ is read
7803  case '*':
7804  {
7805  while (true)
7806  {
7807  switch (get())
7808  {
7809  case std::char_traits<char_type>::eof():
7810  case '\0':
7811  {
7812  error_message = "invalid comment; missing closing '*/'";
7813  return false;
7814  }
7815 
7816  case '*':
7817  {
7818  switch (get())
7819  {
7820  case '/':
7821  return true;
7822 
7823  default:
7824  {
7825  unget();
7826  continue;
7827  }
7828  }
7829  }
7830 
7831  default:
7832  continue;
7833  }
7834  }
7835  }
7836 
7837  // unexpected character after reading '/'
7838  default:
7839  {
7840  error_message = "invalid comment; expecting '/' or '*' after '/'";
7841  return false;
7842  }
7843  }
7844  }
7845 
7847  static void strtof(float& f, const char* str, char** endptr) noexcept
7848  {
7849  f = std::strtof(str, endptr);
7850  }
7851 
7853  static void strtof(double& f, const char* str, char** endptr) noexcept
7854  {
7855  f = std::strtod(str, endptr);
7856  }
7857 
7859  static void strtof(long double& f, const char* str, char** endptr) noexcept
7860  {
7861  f = std::strtold(str, endptr);
7862  }
7863 
7904  token_type scan_number() // lgtm [cpp/use-of-goto]
7905  {
7906  // reset token_buffer to store the number's bytes
7907  reset();
7908 
7909  // the type of the parsed number; initially set to unsigned; will be
7910  // changed if minus sign, decimal point or exponent is read
7911  token_type number_type = token_type::value_unsigned;
7912 
7913  // state (init): we just found out we need to scan a number
7914  switch (current)
7915  {
7916  case '-':
7917  {
7918  add(current);
7919  goto scan_number_minus;
7920  }
7921 
7922  case '0':
7923  {
7924  add(current);
7925  goto scan_number_zero;
7926  }
7927 
7928  case '1':
7929  case '2':
7930  case '3':
7931  case '4':
7932  case '5':
7933  case '6':
7934  case '7':
7935  case '8':
7936  case '9':
7937  {
7938  add(current);
7939  goto scan_number_any1;
7940  }
7941 
7942  // all other characters are rejected outside scan_number()
7943  default: // LCOV_EXCL_LINE
7944  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
7945  }
7946 
7947 scan_number_minus:
7948  // state: we just parsed a leading minus sign
7949  number_type = token_type::value_integer;
7950  switch (get())
7951  {
7952  case '0':
7953  {
7954  add(current);
7955  goto scan_number_zero;
7956  }
7957 
7958  case '1':
7959  case '2':
7960  case '3':
7961  case '4':
7962  case '5':
7963  case '6':
7964  case '7':
7965  case '8':
7966  case '9':
7967  {
7968  add(current);
7969  goto scan_number_any1;
7970  }
7971 
7972  default:
7973  {
7974  error_message = "invalid number; expected digit after '-'";
7975  return token_type::parse_error;
7976  }
7977  }
7978 
7979 scan_number_zero:
7980  // state: we just parse a zero (maybe with a leading minus sign)
7981  switch (get())
7982  {
7983  case '.':
7984  {
7985  add(decimal_point_char);
7986  goto scan_number_decimal1;
7987  }
7988 
7989  case 'e':
7990  case 'E':
7991  {
7992  add(current);
7993  goto scan_number_exponent;
7994  }
7995 
7996  default:
7997  goto scan_number_done;
7998  }
7999 
8000 scan_number_any1:
8001  // state: we just parsed a number 0-9 (maybe with a leading minus sign)
8002  switch (get())
8003  {
8004  case '0':
8005  case '1':
8006  case '2':
8007  case '3':
8008  case '4':
8009  case '5':
8010  case '6':
8011  case '7':
8012  case '8':
8013  case '9':
8014  {
8015  add(current);
8016  goto scan_number_any1;
8017  }
8018 
8019  case '.':
8020  {
8021  add(decimal_point_char);
8022  goto scan_number_decimal1;
8023  }
8024 
8025  case 'e':
8026  case 'E':
8027  {
8028  add(current);
8029  goto scan_number_exponent;
8030  }
8031 
8032  default:
8033  goto scan_number_done;
8034  }
8035 
8036 scan_number_decimal1:
8037  // state: we just parsed a decimal point
8038  number_type = token_type::value_float;
8039  switch (get())
8040  {
8041  case '0':
8042  case '1':
8043  case '2':
8044  case '3':
8045  case '4':
8046  case '5':
8047  case '6':
8048  case '7':
8049  case '8':
8050  case '9':
8051  {
8052  add(current);
8053  goto scan_number_decimal2;
8054  }
8055 
8056  default:
8057  {
8058  error_message = "invalid number; expected digit after '.'";
8059  return token_type::parse_error;
8060  }
8061  }
8062 
8063 scan_number_decimal2:
8064  // we just parsed at least one number after a decimal point
8065  switch (get())
8066  {
8067  case '0':
8068  case '1':
8069  case '2':
8070  case '3':
8071  case '4':
8072  case '5':
8073  case '6':
8074  case '7':
8075  case '8':
8076  case '9':
8077  {
8078  add(current);
8079  goto scan_number_decimal2;
8080  }
8081 
8082  case 'e':
8083  case 'E':
8084  {
8085  add(current);
8086  goto scan_number_exponent;
8087  }
8088 
8089  default:
8090  goto scan_number_done;
8091  }
8092 
8093 scan_number_exponent:
8094  // we just parsed an exponent
8095  number_type = token_type::value_float;
8096  switch (get())
8097  {
8098  case '+':
8099  case '-':
8100  {
8101  add(current);
8102  goto scan_number_sign;
8103  }
8104 
8105  case '0':
8106  case '1':
8107  case '2':
8108  case '3':
8109  case '4':
8110  case '5':
8111  case '6':
8112  case '7':
8113  case '8':
8114  case '9':
8115  {
8116  add(current);
8117  goto scan_number_any2;
8118  }
8119 
8120  default:
8121  {
8122  error_message =
8123  "invalid number; expected '+', '-', or digit after exponent";
8124  return token_type::parse_error;
8125  }
8126  }
8127 
8128 scan_number_sign:
8129  // we just parsed an exponent sign
8130  switch (get())
8131  {
8132  case '0':
8133  case '1':
8134  case '2':
8135  case '3':
8136  case '4':
8137  case '5':
8138  case '6':
8139  case '7':
8140  case '8':
8141  case '9':
8142  {
8143  add(current);
8144  goto scan_number_any2;
8145  }
8146 
8147  default:
8148  {
8149  error_message = "invalid number; expected digit after exponent sign";
8150  return token_type::parse_error;
8151  }
8152  }
8153 
8154 scan_number_any2:
8155  // we just parsed a number after the exponent or exponent sign
8156  switch (get())
8157  {
8158  case '0':
8159  case '1':
8160  case '2':
8161  case '3':
8162  case '4':
8163  case '5':
8164  case '6':
8165  case '7':
8166  case '8':
8167  case '9':
8168  {
8169  add(current);
8170  goto scan_number_any2;
8171  }
8172 
8173  default:
8174  goto scan_number_done;
8175  }
8176 
8177 scan_number_done:
8178  // unget the character after the number (we only read it to know that
8179  // we are done scanning a number)
8180  unget();
8181 
8182  char* endptr = nullptr; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8183  errno = 0;
8184 
8185  // try to parse integers first and fall back to floats
8186  if (number_type == token_type::value_unsigned)
8187  {
8188  const auto x = std::strtoull(token_buffer.data(), &endptr, 10);
8189 
8190  // we checked the number format before
8191  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8192 
8193  if (errno == 0)
8194  {
8195  value_unsigned = static_cast<number_unsigned_t>(x);
8196  if (value_unsigned == x)
8197  {
8198  return token_type::value_unsigned;
8199  }
8200  }
8201  }
8202  else if (number_type == token_type::value_integer)
8203  {
8204  const auto x = std::strtoll(token_buffer.data(), &endptr, 10);
8205 
8206  // we checked the number format before
8207  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8208 
8209  if (errno == 0)
8210  {
8211  value_integer = static_cast<number_integer_t>(x);
8212  if (value_integer == x)
8213  {
8214  return token_type::value_integer;
8215  }
8216  }
8217  }
8218 
8219  // this code is reached if we parse a floating-point number or if an
8220  // integer conversion above failed
8221  strtof(value_float, token_buffer.data(), &endptr);
8222 
8223  // we checked the number format before
8224  JSON_ASSERT(endptr == token_buffer.data() + token_buffer.size());
8225 
8226  return token_type::value_float;
8227  }
8228 
8235  token_type scan_literal(const char_type* literal_text, const std::size_t length,
8236  token_type return_type)
8237  {
8238  JSON_ASSERT(std::char_traits<char_type>::to_char_type(current) == literal_text[0]);
8239  for (std::size_t i = 1; i < length; ++i)
8240  {
8241  if (JSON_HEDLEY_UNLIKELY(std::char_traits<char_type>::to_char_type(get()) != literal_text[i]))
8242  {
8243  error_message = "invalid literal";
8244  return token_type::parse_error;
8245  }
8246  }
8247  return return_type;
8248  }
8249 
8251  // input management
8253 
8255  void reset() noexcept
8256  {
8257  token_buffer.clear();
8258  token_string.clear();
8259  token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8260  }
8261 
8262  /*
8263  @brief get next character from the input
8264 
8265  This function provides the interface to the used input adapter. It does
8266  not throw in case the input reached EOF, but returns a
8267  `std::char_traits<char>::eof()` in that case. Stores the scanned characters
8268  for use in error messages.
8269 
8270  @return character read from the input
8271  */
8272  char_int_type get()
8273  {
8274  ++position.chars_read_total;
8275  ++position.chars_read_current_line;
8276 
8277  if (next_unget)
8278  {
8279  // just reset the next_unget variable and work with current
8280  next_unget = false;
8281  }
8282  else
8283  {
8284  current = ia.get_character();
8285  }
8286 
8287  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8288  {
8289  token_string.push_back(std::char_traits<char_type>::to_char_type(current));
8290  }
8291 
8292  if (current == '\n')
8293  {
8294  ++position.lines_read;
8295  position.chars_read_current_line = 0;
8296  }
8297 
8298  return current;
8299  }
8300 
8309  void unget()
8310  {
8311  next_unget = true;
8312 
8313  --position.chars_read_total;
8314 
8315  // in case we "unget" a newline, we have to also decrement the lines_read
8316  if (position.chars_read_current_line == 0)
8317  {
8318  if (position.lines_read > 0)
8319  {
8320  --position.lines_read;
8321  }
8322  }
8323  else
8324  {
8325  --position.chars_read_current_line;
8326  }
8327 
8328  if (JSON_HEDLEY_LIKELY(current != std::char_traits<char_type>::eof()))
8329  {
8330  JSON_ASSERT(!token_string.empty());
8331  token_string.pop_back();
8332  }
8333  }
8334 
8336  void add(char_int_type c)
8337  {
8338  token_buffer.push_back(static_cast<typename string_t::value_type>(c));
8339  }
8340 
8341  public:
8343  // value getters
8345 
8347  constexpr number_integer_t get_number_integer() const noexcept
8348  {
8349  return value_integer;
8350  }
8351 
8353  constexpr number_unsigned_t get_number_unsigned() const noexcept
8354  {
8355  return value_unsigned;
8356  }
8357 
8359  constexpr number_float_t get_number_float() const noexcept
8360  {
8361  return value_float;
8362  }
8363 
8365  string_t& get_string()
8366  {
8367  return token_buffer;
8368  }
8369 
8371  // diagnostics
8373 
8375  constexpr position_t get_position() const noexcept
8376  {
8377  return position;
8378  }
8379 
8383  std::string get_token_string() const
8384  {
8385  // escape control characters
8386  std::string result;
8387  for (const auto c : token_string)
8388  {
8389  if (static_cast<unsigned char>(c) <= '\x1F')
8390  {
8391  // escape control characters
8392  std::array<char, 9> cs{{}};
8393  static_cast<void>((std::snprintf)(cs.data(), cs.size(), "<U+%.4X>", static_cast<unsigned char>(c))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
8394  result += cs.data();
8395  }
8396  else
8397  {
8398  // add character as is
8399  result.push_back(static_cast<std::string::value_type>(c));
8400  }
8401  }
8402 
8403  return result;
8404  }
8405 
8408  constexpr const char* get_error_message() const noexcept
8409  {
8410  return error_message;
8411  }
8412 
8414  // actual scanner
8416 
8421  bool skip_bom()
8422  {
8423  if (get() == 0xEF)
8424  {
8425  // check if we completely parse the BOM
8426  return get() == 0xBB && get() == 0xBF;
8427  }
8428 
8429  // the first character is not the beginning of the BOM; unget it to
8430  // process is later
8431  unget();
8432  return true;
8433  }
8434 
8436  {
8437  do
8438  {
8439  get();
8440  }
8441  while (current == ' ' || current == '\t' || current == '\n' || current == '\r');
8442  }
8443 
8445  {
8446  // initially, skip the BOM
8447  if (position.chars_read_total == 0 && !skip_bom())
8448  {
8449  error_message = "invalid BOM; must be 0xEF 0xBB 0xBF if given";
8450  return token_type::parse_error;
8451  }
8452 
8453  // read next character and ignore whitespace
8454  skip_whitespace();
8455 
8456  // ignore comments
8457  while (ignore_comments && current == '/')
8458  {
8459  if (!scan_comment())
8460  {
8461  return token_type::parse_error;
8462  }
8463 
8464  // skip following whitespace
8465  skip_whitespace();
8466  }
8467 
8468  switch (current)
8469  {
8470  // structural characters
8471  case '[':
8472  return token_type::begin_array;
8473  case ']':
8474  return token_type::end_array;
8475  case '{':
8476  return token_type::begin_object;
8477  case '}':
8478  return token_type::end_object;
8479  case ':':
8480  return token_type::name_separator;
8481  case ',':
8482  return token_type::value_separator;
8483 
8484  // literals
8485  case 't':
8486  {
8487  std::array<char_type, 4> true_literal = {{static_cast<char_type>('t'), static_cast<char_type>('r'), static_cast<char_type>('u'), static_cast<char_type>('e')}};
8488  return scan_literal(true_literal.data(), true_literal.size(), token_type::literal_true);
8489  }
8490  case 'f':
8491  {
8492  std::array<char_type, 5> false_literal = {{static_cast<char_type>('f'), static_cast<char_type>('a'), static_cast<char_type>('l'), static_cast<char_type>('s'), static_cast<char_type>('e')}};
8493  return scan_literal(false_literal.data(), false_literal.size(), token_type::literal_false);
8494  }
8495  case 'n':
8496  {
8497  std::array<char_type, 4> null_literal = {{static_cast<char_type>('n'), static_cast<char_type>('u'), static_cast<char_type>('l'), static_cast<char_type>('l')}};
8498  return scan_literal(null_literal.data(), null_literal.size(), token_type::literal_null);
8499  }
8500 
8501  // string
8502  case '\"':
8503  return scan_string();
8504 
8505  // number
8506  case '-':
8507  case '0':
8508  case '1':
8509  case '2':
8510  case '3':
8511  case '4':
8512  case '5':
8513  case '6':
8514  case '7':
8515  case '8':
8516  case '9':
8517  return scan_number();
8518 
8519  // end of input (the null byte is needed when parsing from
8520  // string literals)
8521  case '\0':
8522  case std::char_traits<char_type>::eof():
8523  return token_type::end_of_input;
8524 
8525  // error
8526  default:
8527  error_message = "invalid literal";
8528  return token_type::parse_error;
8529  }
8530  }
8531 
8532  private:
8534  InputAdapterType ia;
8535 
8537  const bool ignore_comments = false;
8538 
8540  char_int_type current = std::char_traits<char_type>::eof();
8541 
8543  bool next_unget = false;
8544 
8546  position_t position {};
8547 
8549  std::vector<char_type> token_string {};
8550 
8552  string_t token_buffer {};
8553 
8555  const char* error_message = "";
8556 
8557  // number values
8558  number_integer_t value_integer = 0;
8559  number_unsigned_t value_unsigned = 0;
8560  number_float_t value_float = 0;
8561 
8563  const char_int_type decimal_point_char = '.';
8564 };
8565 } // namespace detail
8566 } // namespace nlohmann
8567 
8568 // #include <nlohmann/detail/macro_scope.hpp>
8569 
8570 // #include <nlohmann/detail/meta/is_sax.hpp>
8571 
8572 
8573 #include <cstdint> // size_t
8574 #include <utility> // declval
8575 #include <string> // string
8576 
8577 // #include <nlohmann/detail/meta/detected.hpp>
8578 
8579 // #include <nlohmann/detail/meta/type_traits.hpp>
8580 
8581 
8582 namespace nlohmann
8583 {
8584 namespace detail
8585 {
8586 template<typename T>
8587 using null_function_t = decltype(std::declval<T&>().null());
8588 
8589 template<typename T>
8591  decltype(std::declval<T&>().boolean(std::declval<bool>()));
8592 
8593 template<typename T, typename Integer>
8595  decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
8596 
8597 template<typename T, typename Unsigned>
8599  decltype(std::declval<T&>().number_unsigned(std::declval<Unsigned>()));
8600 
8601 template<typename T, typename Float, typename String>
8602 using number_float_function_t = decltype(std::declval<T&>().number_float(
8603  std::declval<Float>(), std::declval<const String&>()));
8604 
8605 template<typename T, typename String>
8607  decltype(std::declval<T&>().string(std::declval<String&>()));
8608 
8609 template<typename T, typename Binary>
8611  decltype(std::declval<T&>().binary(std::declval<Binary&>()));
8612 
8613 template<typename T>
8615  decltype(std::declval<T&>().start_object(std::declval<std::size_t>()));
8616 
8617 template<typename T, typename String>
8619  decltype(std::declval<T&>().key(std::declval<String&>()));
8620 
8621 template<typename T>
8622 using end_object_function_t = decltype(std::declval<T&>().end_object());
8623 
8624 template<typename T>
8626  decltype(std::declval<T&>().start_array(std::declval<std::size_t>()));
8627 
8628 template<typename T>
8629 using end_array_function_t = decltype(std::declval<T&>().end_array());
8630 
8631 template<typename T, typename Exception>
8632 using parse_error_function_t = decltype(std::declval<T&>().parse_error(
8633  std::declval<std::size_t>(), std::declval<const std::string&>(),
8634  std::declval<const Exception&>()));
8635 
8636 template<typename SAX, typename BasicJsonType>
8637 struct is_sax
8638 {
8639  private:
8641  "BasicJsonType must be of type basic_json<...>");
8642 
8643  using number_integer_t = typename BasicJsonType::number_integer_t;
8644  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8645  using number_float_t = typename BasicJsonType::number_float_t;
8646  using string_t = typename BasicJsonType::string_t;
8647  using binary_t = typename BasicJsonType::binary_t;
8648  using exception_t = typename BasicJsonType::exception;
8649 
8650  public:
8651  static constexpr bool value =
8665 };
8666 
8667 template<typename SAX, typename BasicJsonType>
8669 {
8670  private:
8672  "BasicJsonType must be of type basic_json<...>");
8673 
8674  using number_integer_t = typename BasicJsonType::number_integer_t;
8675  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8676  using number_float_t = typename BasicJsonType::number_float_t;
8677  using string_t = typename BasicJsonType::string_t;
8678  using binary_t = typename BasicJsonType::binary_t;
8679  using exception_t = typename BasicJsonType::exception;
8680 
8681  public:
8683  "Missing/invalid function: bool null()");
8685  "Missing/invalid function: bool boolean(bool)");
8687  "Missing/invalid function: bool boolean(bool)");
8688  static_assert(
8690  number_integer_t>::value,
8691  "Missing/invalid function: bool number_integer(number_integer_t)");
8692  static_assert(
8694  number_unsigned_t>::value,
8695  "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
8696  static_assert(is_detected_exact<bool, number_float_function_t, SAX,
8697  number_float_t, string_t>::value,
8698  "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
8699  static_assert(
8701  "Missing/invalid function: bool string(string_t&)");
8702  static_assert(
8704  "Missing/invalid function: bool binary(binary_t&)");
8706  "Missing/invalid function: bool start_object(std::size_t)");
8708  "Missing/invalid function: bool key(string_t&)");
8710  "Missing/invalid function: bool end_object()");
8712  "Missing/invalid function: bool start_array(std::size_t)");
8714  "Missing/invalid function: bool end_array()");
8715  static_assert(
8717  "Missing/invalid function: bool parse_error(std::size_t, const "
8718  "std::string&, const exception&)");
8719 };
8720 } // namespace detail
8721 } // namespace nlohmann
8722 
8723 // #include <nlohmann/detail/meta/type_traits.hpp>
8724 
8725 // #include <nlohmann/detail/string_concat.hpp>
8726 
8727 // #include <nlohmann/detail/value_t.hpp>
8728 
8729 
8730 namespace nlohmann
8731 {
8732 namespace detail
8733 {
8734 
8737 {
8738  error,
8739  ignore,
8740  store
8741 };
8742 
8750 static inline bool little_endianness(int num = 1) noexcept
8751 {
8752  return *reinterpret_cast<char*>(&num) == 1;
8753 }
8754 
8755 
8757 // binary reader //
8759 
8763 template<typename BasicJsonType, typename InputAdapterType, typename SAX = json_sax_dom_parser<BasicJsonType>>
8765 {
8766  using number_integer_t = typename BasicJsonType::number_integer_t;
8767  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
8768  using number_float_t = typename BasicJsonType::number_float_t;
8769  using string_t = typename BasicJsonType::string_t;
8770  using binary_t = typename BasicJsonType::binary_t;
8771  using json_sax_t = SAX;
8772  using char_type = typename InputAdapterType::char_type;
8773  using char_int_type = typename std::char_traits<char_type>::int_type;
8774 
8775  public:
8781  explicit binary_reader(InputAdapterType&& adapter, const input_format_t format = input_format_t::json) noexcept : ia(std::move(adapter)), input_format(format)
8782  {
8784  }
8785 
8786  // make class move-only
8787  binary_reader(const binary_reader&) = delete;
8788  binary_reader(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8790  binary_reader& operator=(binary_reader&&) = default; // NOLINT(hicpp-noexcept-move,performance-noexcept-move-constructor)
8791  ~binary_reader() = default;
8792 
8802  bool sax_parse(const input_format_t format,
8803  json_sax_t* sax_,
8804  const bool strict = true,
8805  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
8806  {
8807  sax = sax_;
8808  bool result = false;
8809 
8810  switch (format)
8811  {
8812  case input_format_t::bson:
8813  result = parse_bson_internal();
8814  break;
8815 
8816  case input_format_t::cbor:
8817  result = parse_cbor_internal(true, tag_handler);
8818  break;
8819 
8821  result = parse_msgpack_internal();
8822  break;
8823 
8826  result = parse_ubjson_internal();
8827  break;
8828 
8829  case input_format_t::json: // LCOV_EXCL_LINE
8830  default: // LCOV_EXCL_LINE
8831  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
8832  }
8833 
8834  // strict mode: next byte must be EOF
8835  if (result && strict)
8836  {
8837  if (input_format == input_format_t::ubjson || input_format == input_format_t::bjdata)
8838  {
8839  get_ignore_noop();
8840  }
8841  else
8842  {
8843  get();
8844  }
8845 
8846  if (JSON_HEDLEY_UNLIKELY(current != std::char_traits<char_type>::eof()))
8847  {
8848  return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read,
8849  exception_message(input_format, concat("expected end of input; last byte: 0x", get_token_string()), "value"), nullptr));
8850  }
8851  }
8852 
8853  return result;
8854  }
8855 
8856  private:
8858  // BSON //
8860 
8865  bool parse_bson_internal()
8866  {
8867  std::int32_t document_size{};
8868  get_number<std::int32_t, true>(input_format_t::bson, document_size);
8869 
8870  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
8871  {
8872  return false;
8873  }
8874 
8875  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/false)))
8876  {
8877  return false;
8878  }
8879 
8880  return sax->end_object();
8881  }
8882 
8890  bool get_bson_cstr(string_t& result)
8891  {
8892  auto out = std::back_inserter(result);
8893  while (true)
8894  {
8895  get();
8896  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "cstring")))
8897  {
8898  return false;
8899  }
8900  if (current == 0x00)
8901  {
8902  return true;
8903  }
8904  *out++ = static_cast<typename string_t::value_type>(current);
8905  }
8906  }
8907 
8919  template<typename NumberType>
8920  bool get_bson_string(const NumberType len, string_t& result)
8921  {
8922  if (JSON_HEDLEY_UNLIKELY(len < 1))
8923  {
8924  auto last_token = get_token_string();
8925  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
8926  exception_message(input_format_t::bson, concat("string length must be at least 1, is ", std::to_string(len)), "string"), nullptr));
8927  }
8928 
8929  return get_string(input_format_t::bson, len - static_cast<NumberType>(1), result) && get() != std::char_traits<char_type>::eof();
8930  }
8931 
8941  template<typename NumberType>
8942  bool get_bson_binary(const NumberType len, binary_t& result)
8943  {
8944  if (JSON_HEDLEY_UNLIKELY(len < 0))
8945  {
8946  auto last_token = get_token_string();
8947  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
8948  exception_message(input_format_t::bson, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary"), nullptr));
8949  }
8950 
8951  // All BSON binary values have a subtype
8952  std::uint8_t subtype{};
8953  get_number<std::uint8_t>(input_format_t::bson, subtype);
8954  result.set_subtype(subtype);
8955 
8956  return get_binary(input_format_t::bson, len, result);
8957  }
8958 
8969  bool parse_bson_element_internal(const char_int_type element_type,
8970  const std::size_t element_type_parse_position)
8971  {
8972  switch (element_type)
8973  {
8974  case 0x01: // double
8975  {
8976  double number{};
8977  return get_number<double, true>(input_format_t::bson, number) && sax->number_float(static_cast<number_float_t>(number), "");
8978  }
8979 
8980  case 0x02: // string
8981  {
8982  std::int32_t len{};
8983  string_t value;
8984  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_string(len, value) && sax->string(value);
8985  }
8986 
8987  case 0x03: // object
8988  {
8989  return parse_bson_internal();
8990  }
8991 
8992  case 0x04: // array
8993  {
8994  return parse_bson_array();
8995  }
8996 
8997  case 0x05: // binary
8998  {
8999  std::int32_t len{};
9000  binary_t value;
9001  return get_number<std::int32_t, true>(input_format_t::bson, len) && get_bson_binary(len, value) && sax->binary(value);
9002  }
9003 
9004  case 0x08: // boolean
9005  {
9006  return sax->boolean(get() != 0);
9007  }
9008 
9009  case 0x0A: // null
9010  {
9011  return sax->null();
9012  }
9013 
9014  case 0x10: // int32
9015  {
9016  std::int32_t value{};
9017  return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9018  }
9019 
9020  case 0x12: // int64
9021  {
9022  std::int64_t value{};
9023  return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
9024  }
9025 
9026  default: // anything else not supported (yet)
9027  {
9028  std::array<char, 3> cr{{}};
9029  static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(element_type))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
9030  std::string cr_str{cr.data()};
9031  return sax->parse_error(element_type_parse_position, cr_str,
9032  parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
9033  }
9034  }
9035  }
9036 
9049  bool parse_bson_element_list(const bool is_array)
9050  {
9051  string_t key;
9052 
9053  while (auto element_type = get())
9054  {
9055  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::bson, "element list")))
9056  {
9057  return false;
9058  }
9059 
9060  const std::size_t element_type_parse_position = chars_read;
9061  if (JSON_HEDLEY_UNLIKELY(!get_bson_cstr(key)))
9062  {
9063  return false;
9064  }
9065 
9066  if (!is_array && !sax->key(key))
9067  {
9068  return false;
9069  }
9070 
9071  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_internal(element_type, element_type_parse_position)))
9072  {
9073  return false;
9074  }
9075 
9076  // get_bson_cstr only appends
9077  key.clear();
9078  }
9079 
9080  return true;
9081  }
9082 
9087  bool parse_bson_array()
9088  {
9089  std::int32_t document_size{};
9090  get_number<std::int32_t, true>(input_format_t::bson, document_size);
9091 
9092  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
9093  {
9094  return false;
9095  }
9096 
9097  if (JSON_HEDLEY_UNLIKELY(!parse_bson_element_list(/*is_array*/true)))
9098  {
9099  return false;
9100  }
9101 
9102  return sax->end_array();
9103  }
9104 
9106  // CBOR //
9108 
9117  bool parse_cbor_internal(const bool get_char,
9118  const cbor_tag_handler_t tag_handler)
9119  {
9120  switch (get_char ? get() : current)
9121  {
9122  // EOF
9123  case std::char_traits<char_type>::eof():
9124  return unexpect_eof(input_format_t::cbor, "value");
9125 
9126  // Integer 0x00..0x17 (0..23)
9127  case 0x00:
9128  case 0x01:
9129  case 0x02:
9130  case 0x03:
9131  case 0x04:
9132  case 0x05:
9133  case 0x06:
9134  case 0x07:
9135  case 0x08:
9136  case 0x09:
9137  case 0x0A:
9138  case 0x0B:
9139  case 0x0C:
9140  case 0x0D:
9141  case 0x0E:
9142  case 0x0F:
9143  case 0x10:
9144  case 0x11:
9145  case 0x12:
9146  case 0x13:
9147  case 0x14:
9148  case 0x15:
9149  case 0x16:
9150  case 0x17:
9151  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
9152 
9153  case 0x18: // Unsigned integer (one-byte uint8_t follows)
9154  {
9155  std::uint8_t number{};
9156  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9157  }
9158 
9159  case 0x19: // Unsigned integer (two-byte uint16_t follows)
9160  {
9161  std::uint16_t number{};
9162  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9163  }
9164 
9165  case 0x1A: // Unsigned integer (four-byte uint32_t follows)
9166  {
9167  std::uint32_t number{};
9168  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9169  }
9170 
9171  case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
9172  {
9173  std::uint64_t number{};
9174  return get_number(input_format_t::cbor, number) && sax->number_unsigned(number);
9175  }
9176 
9177  // Negative integer -1-0x00..-1-0x17 (-1..-24)
9178  case 0x20:
9179  case 0x21:
9180  case 0x22:
9181  case 0x23:
9182  case 0x24:
9183  case 0x25:
9184  case 0x26:
9185  case 0x27:
9186  case 0x28:
9187  case 0x29:
9188  case 0x2A:
9189  case 0x2B:
9190  case 0x2C:
9191  case 0x2D:
9192  case 0x2E:
9193  case 0x2F:
9194  case 0x30:
9195  case 0x31:
9196  case 0x32:
9197  case 0x33:
9198  case 0x34:
9199  case 0x35:
9200  case 0x36:
9201  case 0x37:
9202  return sax->number_integer(static_cast<std::int8_t>(0x20 - 1 - current));
9203 
9204  case 0x38: // Negative integer (one-byte uint8_t follows)
9205  {
9206  std::uint8_t number{};
9207  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9208  }
9209 
9210  case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
9211  {
9212  std::uint16_t number{};
9213  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9214  }
9215 
9216  case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
9217  {
9218  std::uint32_t number{};
9219  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1) - number);
9220  }
9221 
9222  case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
9223  {
9224  std::uint64_t number{};
9225  return get_number(input_format_t::cbor, number) && sax->number_integer(static_cast<number_integer_t>(-1)
9226  - static_cast<number_integer_t>(number));
9227  }
9228 
9229  // Binary data (0x00..0x17 bytes follow)
9230  case 0x40:
9231  case 0x41:
9232  case 0x42:
9233  case 0x43:
9234  case 0x44:
9235  case 0x45:
9236  case 0x46:
9237  case 0x47:
9238  case 0x48:
9239  case 0x49:
9240  case 0x4A:
9241  case 0x4B:
9242  case 0x4C:
9243  case 0x4D:
9244  case 0x4E:
9245  case 0x4F:
9246  case 0x50:
9247  case 0x51:
9248  case 0x52:
9249  case 0x53:
9250  case 0x54:
9251  case 0x55:
9252  case 0x56:
9253  case 0x57:
9254  case 0x58: // Binary data (one-byte uint8_t for n follows)
9255  case 0x59: // Binary data (two-byte uint16_t for n follow)
9256  case 0x5A: // Binary data (four-byte uint32_t for n follow)
9257  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9258  case 0x5F: // Binary data (indefinite length)
9259  {
9260  binary_t b;
9261  return get_cbor_binary(b) && sax->binary(b);
9262  }
9263 
9264  // UTF-8 string (0x00..0x17 bytes follow)
9265  case 0x60:
9266  case 0x61:
9267  case 0x62:
9268  case 0x63:
9269  case 0x64:
9270  case 0x65:
9271  case 0x66:
9272  case 0x67:
9273  case 0x68:
9274  case 0x69:
9275  case 0x6A:
9276  case 0x6B:
9277  case 0x6C:
9278  case 0x6D:
9279  case 0x6E:
9280  case 0x6F:
9281  case 0x70:
9282  case 0x71:
9283  case 0x72:
9284  case 0x73:
9285  case 0x74:
9286  case 0x75:
9287  case 0x76:
9288  case 0x77:
9289  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9290  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9291  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9292  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9293  case 0x7F: // UTF-8 string (indefinite length)
9294  {
9295  string_t s;
9296  return get_cbor_string(s) && sax->string(s);
9297  }
9298 
9299  // array (0x00..0x17 data items follow)
9300  case 0x80:
9301  case 0x81:
9302  case 0x82:
9303  case 0x83:
9304  case 0x84:
9305  case 0x85:
9306  case 0x86:
9307  case 0x87:
9308  case 0x88:
9309  case 0x89:
9310  case 0x8A:
9311  case 0x8B:
9312  case 0x8C:
9313  case 0x8D:
9314  case 0x8E:
9315  case 0x8F:
9316  case 0x90:
9317  case 0x91:
9318  case 0x92:
9319  case 0x93:
9320  case 0x94:
9321  case 0x95:
9322  case 0x96:
9323  case 0x97:
9324  return get_cbor_array(
9325  conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9326 
9327  case 0x98: // array (one-byte uint8_t for n follows)
9328  {
9329  std::uint8_t len{};
9330  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9331  }
9332 
9333  case 0x99: // array (two-byte uint16_t for n follow)
9334  {
9335  std::uint16_t len{};
9336  return get_number(input_format_t::cbor, len) && get_cbor_array(static_cast<std::size_t>(len), tag_handler);
9337  }
9338 
9339  case 0x9A: // array (four-byte uint32_t for n follow)
9340  {
9341  std::uint32_t len{};
9342  return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9343  }
9344 
9345  case 0x9B: // array (eight-byte uint64_t for n follow)
9346  {
9347  std::uint64_t len{};
9348  return get_number(input_format_t::cbor, len) && get_cbor_array(conditional_static_cast<std::size_t>(len), tag_handler);
9349  }
9350 
9351  case 0x9F: // array (indefinite length)
9352  return get_cbor_array(static_cast<std::size_t>(-1), tag_handler);
9353 
9354  // map (0x00..0x17 pairs of data items follow)
9355  case 0xA0:
9356  case 0xA1:
9357  case 0xA2:
9358  case 0xA3:
9359  case 0xA4:
9360  case 0xA5:
9361  case 0xA6:
9362  case 0xA7:
9363  case 0xA8:
9364  case 0xA9:
9365  case 0xAA:
9366  case 0xAB:
9367  case 0xAC:
9368  case 0xAD:
9369  case 0xAE:
9370  case 0xAF:
9371  case 0xB0:
9372  case 0xB1:
9373  case 0xB2:
9374  case 0xB3:
9375  case 0xB4:
9376  case 0xB5:
9377  case 0xB6:
9378  case 0xB7:
9379  return get_cbor_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x1Fu), tag_handler);
9380 
9381  case 0xB8: // map (one-byte uint8_t for n follows)
9382  {
9383  std::uint8_t len{};
9384  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9385  }
9386 
9387  case 0xB9: // map (two-byte uint16_t for n follow)
9388  {
9389  std::uint16_t len{};
9390  return get_number(input_format_t::cbor, len) && get_cbor_object(static_cast<std::size_t>(len), tag_handler);
9391  }
9392 
9393  case 0xBA: // map (four-byte uint32_t for n follow)
9394  {
9395  std::uint32_t len{};
9396  return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9397  }
9398 
9399  case 0xBB: // map (eight-byte uint64_t for n follow)
9400  {
9401  std::uint64_t len{};
9402  return get_number(input_format_t::cbor, len) && get_cbor_object(conditional_static_cast<std::size_t>(len), tag_handler);
9403  }
9404 
9405  case 0xBF: // map (indefinite length)
9406  return get_cbor_object(static_cast<std::size_t>(-1), tag_handler);
9407 
9408  case 0xC6: // tagged item
9409  case 0xC7:
9410  case 0xC8:
9411  case 0xC9:
9412  case 0xCA:
9413  case 0xCB:
9414  case 0xCC:
9415  case 0xCD:
9416  case 0xCE:
9417  case 0xCF:
9418  case 0xD0:
9419  case 0xD1:
9420  case 0xD2:
9421  case 0xD3:
9422  case 0xD4:
9423  case 0xD8: // tagged item (1 bytes follow)
9424  case 0xD9: // tagged item (2 bytes follow)
9425  case 0xDA: // tagged item (4 bytes follow)
9426  case 0xDB: // tagged item (8 bytes follow)
9427  {
9428  switch (tag_handler)
9429  {
9431  {
9432  auto last_token = get_token_string();
9433  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9434  exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9435  }
9436 
9438  {
9439  // ignore binary subtype
9440  switch (current)
9441  {
9442  case 0xD8:
9443  {
9444  std::uint8_t subtype_to_ignore{};
9445  get_number(input_format_t::cbor, subtype_to_ignore);
9446  break;
9447  }
9448  case 0xD9:
9449  {
9450  std::uint16_t subtype_to_ignore{};
9451  get_number(input_format_t::cbor, subtype_to_ignore);
9452  break;
9453  }
9454  case 0xDA:
9455  {
9456  std::uint32_t subtype_to_ignore{};
9457  get_number(input_format_t::cbor, subtype_to_ignore);
9458  break;
9459  }
9460  case 0xDB:
9461  {
9462  std::uint64_t subtype_to_ignore{};
9463  get_number(input_format_t::cbor, subtype_to_ignore);
9464  break;
9465  }
9466  default:
9467  break;
9468  }
9469  return parse_cbor_internal(true, tag_handler);
9470  }
9471 
9473  {
9474  binary_t b;
9475  // use binary subtype and store in binary container
9476  switch (current)
9477  {
9478  case 0xD8:
9479  {
9480  std::uint8_t subtype{};
9481  get_number(input_format_t::cbor, subtype);
9482  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9483  break;
9484  }
9485  case 0xD9:
9486  {
9487  std::uint16_t subtype{};
9488  get_number(input_format_t::cbor, subtype);
9489  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9490  break;
9491  }
9492  case 0xDA:
9493  {
9494  std::uint32_t subtype{};
9495  get_number(input_format_t::cbor, subtype);
9496  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9497  break;
9498  }
9499  case 0xDB:
9500  {
9501  std::uint64_t subtype{};
9502  get_number(input_format_t::cbor, subtype);
9503  b.set_subtype(detail::conditional_static_cast<typename binary_t::subtype_type>(subtype));
9504  break;
9505  }
9506  default:
9507  return parse_cbor_internal(true, tag_handler);
9508  }
9509  get();
9510  return get_cbor_binary(b) && sax->binary(b);
9511  }
9512 
9513  default: // LCOV_EXCL_LINE
9514  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
9515  return false; // LCOV_EXCL_LINE
9516  }
9517  }
9518 
9519  case 0xF4: // false
9520  return sax->boolean(false);
9521 
9522  case 0xF5: // true
9523  return sax->boolean(true);
9524 
9525  case 0xF6: // null
9526  return sax->null();
9527 
9528  case 0xF9: // Half-Precision Float (two-byte IEEE 754)
9529  {
9530  const auto byte1_raw = get();
9531  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9532  {
9533  return false;
9534  }
9535  const auto byte2_raw = get();
9536  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "number")))
9537  {
9538  return false;
9539  }
9540 
9541  const auto byte1 = static_cast<unsigned char>(byte1_raw);
9542  const auto byte2 = static_cast<unsigned char>(byte2_raw);
9543 
9544  // code from RFC 7049, Appendix D, Figure 3:
9545  // As half-precision floating-point numbers were only added
9546  // to IEEE 754 in 2008, today's programming platforms often
9547  // still only have limited support for them. It is very
9548  // easy to include at least decoding support for them even
9549  // without such support. An example of a small decoder for
9550  // half-precision floating-point numbers in the C language
9551  // is shown in Fig. 3.
9552  const auto half = static_cast<unsigned int>((byte1 << 8u) + byte2);
9553  const double val = [&half]
9554  {
9555  const int exp = (half >> 10u) & 0x1Fu;
9556  const unsigned int mant = half & 0x3FFu;
9557  JSON_ASSERT(0 <= exp&& exp <= 32);
9558  JSON_ASSERT(mant <= 1024);
9559  switch (exp)
9560  {
9561  case 0:
9562  return std::ldexp(mant, -24);
9563  case 31:
9564  return (mant == 0)
9565  ? std::numeric_limits<double>::infinity()
9566  : std::numeric_limits<double>::quiet_NaN();
9567  default:
9568  return std::ldexp(mant + 1024, exp - 25);
9569  }
9570  }();
9571  return sax->number_float((half & 0x8000u) != 0
9572  ? static_cast<number_float_t>(-val)
9573  : static_cast<number_float_t>(val), "");
9574  }
9575 
9576  case 0xFA: // Single-Precision Float (four-byte IEEE 754)
9577  {
9578  float number{};
9579  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9580  }
9581 
9582  case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
9583  {
9584  double number{};
9585  return get_number(input_format_t::cbor, number) && sax->number_float(static_cast<number_float_t>(number), "");
9586  }
9587 
9588  default: // anything else (0xFF is handled inside the other types)
9589  {
9590  auto last_token = get_token_string();
9591  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
9592  exception_message(input_format_t::cbor, concat("invalid byte: 0x", last_token), "value"), nullptr));
9593  }
9594  }
9595  }
9596 
9608  bool get_cbor_string(string_t& result)
9609  {
9610  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "string")))
9611  {
9612  return false;
9613  }
9614 
9615  switch (current)
9616  {
9617  // UTF-8 string (0x00..0x17 bytes follow)
9618  case 0x60:
9619  case 0x61:
9620  case 0x62:
9621  case 0x63:
9622  case 0x64:
9623  case 0x65:
9624  case 0x66:
9625  case 0x67:
9626  case 0x68:
9627  case 0x69:
9628  case 0x6A:
9629  case 0x6B:
9630  case 0x6C:
9631  case 0x6D:
9632  case 0x6E:
9633  case 0x6F:
9634  case 0x70:
9635  case 0x71:
9636  case 0x72:
9637  case 0x73:
9638  case 0x74:
9639  case 0x75:
9640  case 0x76:
9641  case 0x77:
9642  {
9643  return get_string(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9644  }
9645 
9646  case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
9647  {
9648  std::uint8_t len{};
9649  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9650  }
9651 
9652  case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
9653  {
9654  std::uint16_t len{};
9655  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9656  }
9657 
9658  case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
9659  {
9660  std::uint32_t len{};
9661  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9662  }
9663 
9664  case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
9665  {
9666  std::uint64_t len{};
9667  return get_number(input_format_t::cbor, len) && get_string(input_format_t::cbor, len, result);
9668  }
9669 
9670  case 0x7F: // UTF-8 string (indefinite length)
9671  {
9672  while (get() != 0xFF)
9673  {
9674  string_t chunk;
9675  if (!get_cbor_string(chunk))
9676  {
9677  return false;
9678  }
9679  result.append(chunk);
9680  }
9681  return true;
9682  }
9683 
9684  default:
9685  {
9686  auto last_token = get_token_string();
9687  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
9688  exception_message(input_format_t::cbor, concat("expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x", last_token), "string"), nullptr));
9689  }
9690  }
9691  }
9692 
9704  bool get_cbor_binary(binary_t& result)
9705  {
9706  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::cbor, "binary")))
9707  {
9708  return false;
9709  }
9710 
9711  switch (current)
9712  {
9713  // Binary data (0x00..0x17 bytes follow)
9714  case 0x40:
9715  case 0x41:
9716  case 0x42:
9717  case 0x43:
9718  case 0x44:
9719  case 0x45:
9720  case 0x46:
9721  case 0x47:
9722  case 0x48:
9723  case 0x49:
9724  case 0x4A:
9725  case 0x4B:
9726  case 0x4C:
9727  case 0x4D:
9728  case 0x4E:
9729  case 0x4F:
9730  case 0x50:
9731  case 0x51:
9732  case 0x52:
9733  case 0x53:
9734  case 0x54:
9735  case 0x55:
9736  case 0x56:
9737  case 0x57:
9738  {
9739  return get_binary(input_format_t::cbor, static_cast<unsigned int>(current) & 0x1Fu, result);
9740  }
9741 
9742  case 0x58: // Binary data (one-byte uint8_t for n follows)
9743  {
9744  std::uint8_t len{};
9745  return get_number(input_format_t::cbor, len) &&
9746  get_binary(input_format_t::cbor, len, result);
9747  }
9748 
9749  case 0x59: // Binary data (two-byte uint16_t for n follow)
9750  {
9751  std::uint16_t len{};
9752  return get_number(input_format_t::cbor, len) &&
9753  get_binary(input_format_t::cbor, len, result);
9754  }
9755 
9756  case 0x5A: // Binary data (four-byte uint32_t for n follow)
9757  {
9758  std::uint32_t len{};
9759  return get_number(input_format_t::cbor, len) &&
9760  get_binary(input_format_t::cbor, len, result);
9761  }
9762 
9763  case 0x5B: // Binary data (eight-byte uint64_t for n follow)
9764  {
9765  std::uint64_t len{};
9766  return get_number(input_format_t::cbor, len) &&
9767  get_binary(input_format_t::cbor, len, result);
9768  }
9769 
9770  case 0x5F: // Binary data (indefinite length)
9771  {
9772  while (get() != 0xFF)
9773  {
9774  binary_t chunk;
9775  if (!get_cbor_binary(chunk))
9776  {
9777  return false;
9778  }
9779  result.insert(result.end(), chunk.begin(), chunk.end());
9780  }
9781  return true;
9782  }
9783 
9784  default:
9785  {
9786  auto last_token = get_token_string();
9787  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
9788  exception_message(input_format_t::cbor, concat("expected length specification (0x40-0x5B) or indefinite binary array type (0x5F); last byte: 0x", last_token), "binary"), nullptr));
9789  }
9790  }
9791  }
9792 
9799  bool get_cbor_array(const std::size_t len,
9800  const cbor_tag_handler_t tag_handler)
9801  {
9802  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
9803  {
9804  return false;
9805  }
9806 
9807  if (len != static_cast<std::size_t>(-1))
9808  {
9809  for (std::size_t i = 0; i < len; ++i)
9810  {
9811  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9812  {
9813  return false;
9814  }
9815  }
9816  }
9817  else
9818  {
9819  while (get() != 0xFF)
9820  {
9821  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(false, tag_handler)))
9822  {
9823  return false;
9824  }
9825  }
9826  }
9827 
9828  return sax->end_array();
9829  }
9830 
9837  bool get_cbor_object(const std::size_t len,
9838  const cbor_tag_handler_t tag_handler)
9839  {
9840  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
9841  {
9842  return false;
9843  }
9844 
9845  if (len != 0)
9846  {
9847  string_t key;
9848  if (len != static_cast<std::size_t>(-1))
9849  {
9850  for (std::size_t i = 0; i < len; ++i)
9851  {
9852  get();
9853  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9854  {
9855  return false;
9856  }
9857 
9858  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9859  {
9860  return false;
9861  }
9862  key.clear();
9863  }
9864  }
9865  else
9866  {
9867  while (get() != 0xFF)
9868  {
9869  if (JSON_HEDLEY_UNLIKELY(!get_cbor_string(key) || !sax->key(key)))
9870  {
9871  return false;
9872  }
9873 
9874  if (JSON_HEDLEY_UNLIKELY(!parse_cbor_internal(true, tag_handler)))
9875  {
9876  return false;
9877  }
9878  key.clear();
9879  }
9880  }
9881  }
9882 
9883  return sax->end_object();
9884  }
9885 
9887  // MsgPack //
9889 
9893  bool parse_msgpack_internal()
9894  {
9895  switch (get())
9896  {
9897  // EOF
9898  case std::char_traits<char_type>::eof():
9899  return unexpect_eof(input_format_t::msgpack, "value");
9900 
9901  // positive fixint
9902  case 0x00:
9903  case 0x01:
9904  case 0x02:
9905  case 0x03:
9906  case 0x04:
9907  case 0x05:
9908  case 0x06:
9909  case 0x07:
9910  case 0x08:
9911  case 0x09:
9912  case 0x0A:
9913  case 0x0B:
9914  case 0x0C:
9915  case 0x0D:
9916  case 0x0E:
9917  case 0x0F:
9918  case 0x10:
9919  case 0x11:
9920  case 0x12:
9921  case 0x13:
9922  case 0x14:
9923  case 0x15:
9924  case 0x16:
9925  case 0x17:
9926  case 0x18:
9927  case 0x19:
9928  case 0x1A:
9929  case 0x1B:
9930  case 0x1C:
9931  case 0x1D:
9932  case 0x1E:
9933  case 0x1F:
9934  case 0x20:
9935  case 0x21:
9936  case 0x22:
9937  case 0x23:
9938  case 0x24:
9939  case 0x25:
9940  case 0x26:
9941  case 0x27:
9942  case 0x28:
9943  case 0x29:
9944  case 0x2A:
9945  case 0x2B:
9946  case 0x2C:
9947  case 0x2D:
9948  case 0x2E:
9949  case 0x2F:
9950  case 0x30:
9951  case 0x31:
9952  case 0x32:
9953  case 0x33:
9954  case 0x34:
9955  case 0x35:
9956  case 0x36:
9957  case 0x37:
9958  case 0x38:
9959  case 0x39:
9960  case 0x3A:
9961  case 0x3B:
9962  case 0x3C:
9963  case 0x3D:
9964  case 0x3E:
9965  case 0x3F:
9966  case 0x40:
9967  case 0x41:
9968  case 0x42:
9969  case 0x43:
9970  case 0x44:
9971  case 0x45:
9972  case 0x46:
9973  case 0x47:
9974  case 0x48:
9975  case 0x49:
9976  case 0x4A:
9977  case 0x4B:
9978  case 0x4C:
9979  case 0x4D:
9980  case 0x4E:
9981  case 0x4F:
9982  case 0x50:
9983  case 0x51:
9984  case 0x52:
9985  case 0x53:
9986  case 0x54:
9987  case 0x55:
9988  case 0x56:
9989  case 0x57:
9990  case 0x58:
9991  case 0x59:
9992  case 0x5A:
9993  case 0x5B:
9994  case 0x5C:
9995  case 0x5D:
9996  case 0x5E:
9997  case 0x5F:
9998  case 0x60:
9999  case 0x61:
10000  case 0x62:
10001  case 0x63:
10002  case 0x64:
10003  case 0x65:
10004  case 0x66:
10005  case 0x67:
10006  case 0x68:
10007  case 0x69:
10008  case 0x6A:
10009  case 0x6B:
10010  case 0x6C:
10011  case 0x6D:
10012  case 0x6E:
10013  case 0x6F:
10014  case 0x70:
10015  case 0x71:
10016  case 0x72:
10017  case 0x73:
10018  case 0x74:
10019  case 0x75:
10020  case 0x76:
10021  case 0x77:
10022  case 0x78:
10023  case 0x79:
10024  case 0x7A:
10025  case 0x7B:
10026  case 0x7C:
10027  case 0x7D:
10028  case 0x7E:
10029  case 0x7F:
10030  return sax->number_unsigned(static_cast<number_unsigned_t>(current));
10031 
10032  // fixmap
10033  case 0x80:
10034  case 0x81:
10035  case 0x82:
10036  case 0x83:
10037  case 0x84:
10038  case 0x85:
10039  case 0x86:
10040  case 0x87:
10041  case 0x88:
10042  case 0x89:
10043  case 0x8A:
10044  case 0x8B:
10045  case 0x8C:
10046  case 0x8D:
10047  case 0x8E:
10048  case 0x8F:
10049  return get_msgpack_object(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10050 
10051  // fixarray
10052  case 0x90:
10053  case 0x91:
10054  case 0x92:
10055  case 0x93:
10056  case 0x94:
10057  case 0x95:
10058  case 0x96:
10059  case 0x97:
10060  case 0x98:
10061  case 0x99:
10062  case 0x9A:
10063  case 0x9B:
10064  case 0x9C:
10065  case 0x9D:
10066  case 0x9E:
10067  case 0x9F:
10068  return get_msgpack_array(conditional_static_cast<std::size_t>(static_cast<unsigned int>(current) & 0x0Fu));
10069 
10070  // fixstr
10071  case 0xA0:
10072  case 0xA1:
10073  case 0xA2:
10074  case 0xA3:
10075  case 0xA4:
10076  case 0xA5:
10077  case 0xA6:
10078  case 0xA7:
10079  case 0xA8:
10080  case 0xA9:
10081  case 0xAA:
10082  case 0xAB:
10083  case 0xAC:
10084  case 0xAD:
10085  case 0xAE:
10086  case 0xAF:
10087  case 0xB0:
10088  case 0xB1:
10089  case 0xB2:
10090  case 0xB3:
10091  case 0xB4:
10092  case 0xB5:
10093  case 0xB6:
10094  case 0xB7:
10095  case 0xB8:
10096  case 0xB9:
10097  case 0xBA:
10098  case 0xBB:
10099  case 0xBC:
10100  case 0xBD:
10101  case 0xBE:
10102  case 0xBF:
10103  case 0xD9: // str 8
10104  case 0xDA: // str 16
10105  case 0xDB: // str 32
10106  {
10107  string_t s;
10108  return get_msgpack_string(s) && sax->string(s);
10109  }
10110 
10111  case 0xC0: // nil
10112  return sax->null();
10113 
10114  case 0xC2: // false
10115  return sax->boolean(false);
10116 
10117  case 0xC3: // true
10118  return sax->boolean(true);
10119 
10120  case 0xC4: // bin 8
10121  case 0xC5: // bin 16
10122  case 0xC6: // bin 32
10123  case 0xC7: // ext 8
10124  case 0xC8: // ext 16
10125  case 0xC9: // ext 32
10126  case 0xD4: // fixext 1
10127  case 0xD5: // fixext 2
10128  case 0xD6: // fixext 4
10129  case 0xD7: // fixext 8
10130  case 0xD8: // fixext 16
10131  {
10132  binary_t b;
10133  return get_msgpack_binary(b) && sax->binary(b);
10134  }
10135 
10136  case 0xCA: // float 32
10137  {
10138  float number{};
10139  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10140  }
10141 
10142  case 0xCB: // float 64
10143  {
10144  double number{};
10145  return get_number(input_format_t::msgpack, number) && sax->number_float(static_cast<number_float_t>(number), "");
10146  }
10147 
10148  case 0xCC: // uint 8
10149  {
10150  std::uint8_t number{};
10151  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10152  }
10153 
10154  case 0xCD: // uint 16
10155  {
10156  std::uint16_t number{};
10157  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10158  }
10159 
10160  case 0xCE: // uint 32
10161  {
10162  std::uint32_t number{};
10163  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10164  }
10165 
10166  case 0xCF: // uint 64
10167  {
10168  std::uint64_t number{};
10169  return get_number(input_format_t::msgpack, number) && sax->number_unsigned(number);
10170  }
10171 
10172  case 0xD0: // int 8
10173  {
10174  std::int8_t number{};
10175  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10176  }
10177 
10178  case 0xD1: // int 16
10179  {
10180  std::int16_t number{};
10181  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10182  }
10183 
10184  case 0xD2: // int 32
10185  {
10186  std::int32_t number{};
10187  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10188  }
10189 
10190  case 0xD3: // int 64
10191  {
10192  std::int64_t number{};
10193  return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
10194  }
10195 
10196  case 0xDC: // array 16
10197  {
10198  std::uint16_t len{};
10199  return get_number(input_format_t::msgpack, len) && get_msgpack_array(static_cast<std::size_t>(len));
10200  }
10201 
10202  case 0xDD: // array 32
10203  {
10204  std::uint32_t len{};
10205  return get_number(input_format_t::msgpack, len) && get_msgpack_array(conditional_static_cast<std::size_t>(len));
10206  }
10207 
10208  case 0xDE: // map 16
10209  {
10210  std::uint16_t len{};
10211  return get_number(input_format_t::msgpack, len) && get_msgpack_object(static_cast<std::size_t>(len));
10212  }
10213 
10214  case 0xDF: // map 32
10215  {
10216  std::uint32_t len{};
10217  return get_number(input_format_t::msgpack, len) && get_msgpack_object(conditional_static_cast<std::size_t>(len));
10218  }
10219 
10220  // negative fixint
10221  case 0xE0:
10222  case 0xE1:
10223  case 0xE2:
10224  case 0xE3:
10225  case 0xE4:
10226  case 0xE5:
10227  case 0xE6:
10228  case 0xE7:
10229  case 0xE8:
10230  case 0xE9:
10231  case 0xEA:
10232  case 0xEB:
10233  case 0xEC:
10234  case 0xED:
10235  case 0xEE:
10236  case 0xEF:
10237  case 0xF0:
10238  case 0xF1:
10239  case 0xF2:
10240  case 0xF3:
10241  case 0xF4:
10242  case 0xF5:
10243  case 0xF6:
10244  case 0xF7:
10245  case 0xF8:
10246  case 0xF9:
10247  case 0xFA:
10248  case 0xFB:
10249  case 0xFC:
10250  case 0xFD:
10251  case 0xFE:
10252  case 0xFF:
10253  return sax->number_integer(static_cast<std::int8_t>(current));
10254 
10255  default: // anything else
10256  {
10257  auto last_token = get_token_string();
10258  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10259  exception_message(input_format_t::msgpack, concat("invalid byte: 0x", last_token), "value"), nullptr));
10260  }
10261  }
10262  }
10263 
10274  bool get_msgpack_string(string_t& result)
10275  {
10276  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format_t::msgpack, "string")))
10277  {
10278  return false;
10279  }
10280 
10281  switch (current)
10282  {
10283  // fixstr
10284  case 0xA0:
10285  case 0xA1:
10286  case 0xA2:
10287  case 0xA3:
10288  case 0xA4:
10289  case 0xA5:
10290  case 0xA6:
10291  case 0xA7:
10292  case 0xA8:
10293  case 0xA9:
10294  case 0xAA:
10295  case 0xAB:
10296  case 0xAC:
10297  case 0xAD:
10298  case 0xAE:
10299  case 0xAF:
10300  case 0xB0:
10301  case 0xB1:
10302  case 0xB2:
10303  case 0xB3:
10304  case 0xB4:
10305  case 0xB5:
10306  case 0xB6:
10307  case 0xB7:
10308  case 0xB8:
10309  case 0xB9:
10310  case 0xBA:
10311  case 0xBB:
10312  case 0xBC:
10313  case 0xBD:
10314  case 0xBE:
10315  case 0xBF:
10316  {
10317  return get_string(input_format_t::msgpack, static_cast<unsigned int>(current) & 0x1Fu, result);
10318  }
10319 
10320  case 0xD9: // str 8
10321  {
10322  std::uint8_t len{};
10323  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10324  }
10325 
10326  case 0xDA: // str 16
10327  {
10328  std::uint16_t len{};
10329  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10330  }
10331 
10332  case 0xDB: // str 32
10333  {
10334  std::uint32_t len{};
10335  return get_number(input_format_t::msgpack, len) && get_string(input_format_t::msgpack, len, result);
10336  }
10337 
10338  default:
10339  {
10340  auto last_token = get_token_string();
10341  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
10342  exception_message(input_format_t::msgpack, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", last_token), "string"), nullptr));
10343  }
10344  }
10345  }
10346 
10357  bool get_msgpack_binary(binary_t& result)
10358  {
10359  // helper function to set the subtype
10360  auto assign_and_return_true = [&result](std::int8_t subtype)
10361  {
10362  result.set_subtype(static_cast<std::uint8_t>(subtype));
10363  return true;
10364  };
10365 
10366  switch (current)
10367  {
10368  case 0xC4: // bin 8
10369  {
10370  std::uint8_t len{};
10371  return get_number(input_format_t::msgpack, len) &&
10372  get_binary(input_format_t::msgpack, len, result);
10373  }
10374 
10375  case 0xC5: // bin 16
10376  {
10377  std::uint16_t len{};
10378  return get_number(input_format_t::msgpack, len) &&
10379  get_binary(input_format_t::msgpack, len, result);
10380  }
10381 
10382  case 0xC6: // bin 32
10383  {
10384  std::uint32_t len{};
10385  return get_number(input_format_t::msgpack, len) &&
10386  get_binary(input_format_t::msgpack, len, result);
10387  }
10388 
10389  case 0xC7: // ext 8
10390  {
10391  std::uint8_t len{};
10392  std::int8_t subtype{};
10393  return get_number(input_format_t::msgpack, len) &&
10394  get_number(input_format_t::msgpack, subtype) &&
10395  get_binary(input_format_t::msgpack, len, result) &&
10396  assign_and_return_true(subtype);
10397  }
10398 
10399  case 0xC8: // ext 16
10400  {
10401  std::uint16_t len{};
10402  std::int8_t subtype{};
10403  return get_number(input_format_t::msgpack, len) &&
10404  get_number(input_format_t::msgpack, subtype) &&
10405  get_binary(input_format_t::msgpack, len, result) &&
10406  assign_and_return_true(subtype);
10407  }
10408 
10409  case 0xC9: // ext 32
10410  {
10411  std::uint32_t len{};
10412  std::int8_t subtype{};
10413  return get_number(input_format_t::msgpack, len) &&
10414  get_number(input_format_t::msgpack, subtype) &&
10415  get_binary(input_format_t::msgpack, len, result) &&
10416  assign_and_return_true(subtype);
10417  }
10418 
10419  case 0xD4: // fixext 1
10420  {
10421  std::int8_t subtype{};
10422  return get_number(input_format_t::msgpack, subtype) &&
10423  get_binary(input_format_t::msgpack, 1, result) &&
10424  assign_and_return_true(subtype);
10425  }
10426 
10427  case 0xD5: // fixext 2
10428  {
10429  std::int8_t subtype{};
10430  return get_number(input_format_t::msgpack, subtype) &&
10431  get_binary(input_format_t::msgpack, 2, result) &&
10432  assign_and_return_true(subtype);
10433  }
10434 
10435  case 0xD6: // fixext 4
10436  {
10437  std::int8_t subtype{};
10438  return get_number(input_format_t::msgpack, subtype) &&
10439  get_binary(input_format_t::msgpack, 4, result) &&
10440  assign_and_return_true(subtype);
10441  }
10442 
10443  case 0xD7: // fixext 8
10444  {
10445  std::int8_t subtype{};
10446  return get_number(input_format_t::msgpack, subtype) &&
10447  get_binary(input_format_t::msgpack, 8, result) &&
10448  assign_and_return_true(subtype);
10449  }
10450 
10451  case 0xD8: // fixext 16
10452  {
10453  std::int8_t subtype{};
10454  return get_number(input_format_t::msgpack, subtype) &&
10455  get_binary(input_format_t::msgpack, 16, result) &&
10456  assign_and_return_true(subtype);
10457  }
10458 
10459  default: // LCOV_EXCL_LINE
10460  return false; // LCOV_EXCL_LINE
10461  }
10462  }
10463 
10468  bool get_msgpack_array(const std::size_t len)
10469  {
10470  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(len)))
10471  {
10472  return false;
10473  }
10474 
10475  for (std::size_t i = 0; i < len; ++i)
10476  {
10477  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10478  {
10479  return false;
10480  }
10481  }
10482 
10483  return sax->end_array();
10484  }
10485 
10490  bool get_msgpack_object(const std::size_t len)
10491  {
10492  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(len)))
10493  {
10494  return false;
10495  }
10496 
10497  string_t key;
10498  for (std::size_t i = 0; i < len; ++i)
10499  {
10500  get();
10501  if (JSON_HEDLEY_UNLIKELY(!get_msgpack_string(key) || !sax->key(key)))
10502  {
10503  return false;
10504  }
10505 
10506  if (JSON_HEDLEY_UNLIKELY(!parse_msgpack_internal()))
10507  {
10508  return false;
10509  }
10510  key.clear();
10511  }
10512 
10513  return sax->end_object();
10514  }
10515 
10517  // UBJSON //
10519 
10527  bool parse_ubjson_internal(const bool get_char = true)
10528  {
10529  return get_ubjson_value(get_char ? get_ignore_noop() : current);
10530  }
10531 
10546  bool get_ubjson_string(string_t& result, const bool get_char = true)
10547  {
10548  if (get_char)
10549  {
10550  get(); // TODO(niels): may we ignore N here?
10551  }
10552 
10553  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
10554  {
10555  return false;
10556  }
10557 
10558  switch (current)
10559  {
10560  case 'U':
10561  {
10562  std::uint8_t len{};
10563  return get_number(input_format, len) && get_string(input_format, len, result);
10564  }
10565 
10566  case 'i':
10567  {
10568  std::int8_t len{};
10569  return get_number(input_format, len) && get_string(input_format, len, result);
10570  }
10571 
10572  case 'I':
10573  {
10574  std::int16_t len{};
10575  return get_number(input_format, len) && get_string(input_format, len, result);
10576  }
10577 
10578  case 'l':
10579  {
10580  std::int32_t len{};
10581  return get_number(input_format, len) && get_string(input_format, len, result);
10582  }
10583 
10584  case 'L':
10585  {
10586  std::int64_t len{};
10587  return get_number(input_format, len) && get_string(input_format, len, result);
10588  }
10589 
10590  case 'u':
10591  {
10592  if (input_format != input_format_t::bjdata)
10593  {
10594  break;
10595  }
10596  std::uint16_t len{};
10597  return get_number(input_format, len) && get_string(input_format, len, result);
10598  }
10599 
10600  case 'm':
10601  {
10602  if (input_format != input_format_t::bjdata)
10603  {
10604  break;
10605  }
10606  std::uint32_t len{};
10607  return get_number(input_format, len) && get_string(input_format, len, result);
10608  }
10609 
10610  case 'M':
10611  {
10612  if (input_format != input_format_t::bjdata)
10613  {
10614  break;
10615  }
10616  std::uint64_t len{};
10617  return get_number(input_format, len) && get_string(input_format, len, result);
10618  }
10619 
10620  default:
10621  break;
10622  }
10623  auto last_token = get_token_string();
10624  std::string message;
10625 
10626  if (input_format != input_format_t::bjdata)
10627  {
10628  message = "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token;
10629  }
10630  else
10631  {
10632  message = "expected length type specification (U, i, u, I, m, l, M, L); last byte: 0x" + last_token;
10633  }
10634  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "string"), nullptr));
10635  }
10636 
10641  bool get_ubjson_ndarray_size(std::vector<size_t>& dim)
10642  {
10643  std::pair<std::size_t, char_int_type> size_and_type;
10644  size_t dimlen = 0;
10645  bool no_ndarray = true;
10646 
10647  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type, no_ndarray)))
10648  {
10649  return false;
10650  }
10651 
10652  if (size_and_type.first != string_t::npos)
10653  {
10654  if (size_and_type.second != 0)
10655  {
10656  if (size_and_type.second != 'N')
10657  {
10658  for (std::size_t i = 0; i < size_and_type.first; ++i)
10659  {
10660  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, size_and_type.second)))
10661  {
10662  return false;
10663  }
10664  dim.push_back(dimlen);
10665  }
10666  }
10667  }
10668  else
10669  {
10670  for (std::size_t i = 0; i < size_and_type.first; ++i)
10671  {
10672  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray)))
10673  {
10674  return false;
10675  }
10676  dim.push_back(dimlen);
10677  }
10678  }
10679  }
10680  else
10681  {
10682  while (current != ']')
10683  {
10684  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_value(dimlen, no_ndarray, current)))
10685  {
10686  return false;
10687  }
10688  dim.push_back(dimlen);
10689  get_ignore_noop();
10690  }
10691  }
10692  return true;
10693  }
10694 
10706  bool get_ubjson_size_value(std::size_t& result, bool& is_ndarray, char_int_type prefix = 0)
10707  {
10708  if (prefix == 0)
10709  {
10710  prefix = get_ignore_noop();
10711  }
10712 
10713  switch (prefix)
10714  {
10715  case 'U':
10716  {
10717  std::uint8_t number{};
10718  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10719  {
10720  return false;
10721  }
10722  result = static_cast<std::size_t>(number);
10723  return true;
10724  }
10725 
10726  case 'i':
10727  {
10728  std::int8_t number{};
10729  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10730  {
10731  return false;
10732  }
10733  if (number < 0)
10734  {
10735  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
10736  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
10737  }
10738  result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
10739  return true;
10740  }
10741 
10742  case 'I':
10743  {
10744  std::int16_t number{};
10745  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10746  {
10747  return false;
10748  }
10749  if (number < 0)
10750  {
10751  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
10752  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
10753  }
10754  result = static_cast<std::size_t>(number);
10755  return true;
10756  }
10757 
10758  case 'l':
10759  {
10760  std::int32_t number{};
10761  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10762  {
10763  return false;
10764  }
10765  if (number < 0)
10766  {
10767  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
10768  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
10769  }
10770  result = static_cast<std::size_t>(number);
10771  return true;
10772  }
10773 
10774  case 'L':
10775  {
10776  std::int64_t number{};
10777  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10778  {
10779  return false;
10780  }
10781  if (number < 0)
10782  {
10783  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
10784  exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
10785  }
10786  if (!value_in_range_of<std::size_t>(number))
10787  {
10788  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
10789  exception_message(input_format, "integer value overflow", "size"), nullptr));
10790  }
10791  result = static_cast<std::size_t>(number);
10792  return true;
10793  }
10794 
10795  case 'u':
10796  {
10797  if (input_format != input_format_t::bjdata)
10798  {
10799  break;
10800  }
10801  std::uint16_t number{};
10802  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10803  {
10804  return false;
10805  }
10806  result = static_cast<std::size_t>(number);
10807  return true;
10808  }
10809 
10810  case 'm':
10811  {
10812  if (input_format != input_format_t::bjdata)
10813  {
10814  break;
10815  }
10816  std::uint32_t number{};
10817  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10818  {
10819  return false;
10820  }
10821  result = conditional_static_cast<std::size_t>(number);
10822  return true;
10823  }
10824 
10825  case 'M':
10826  {
10827  if (input_format != input_format_t::bjdata)
10828  {
10829  break;
10830  }
10831  std::uint64_t number{};
10832  if (JSON_HEDLEY_UNLIKELY(!get_number(input_format, number)))
10833  {
10834  return false;
10835  }
10836  if (!value_in_range_of<std::size_t>(number))
10837  {
10838  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
10839  exception_message(input_format, "integer value overflow", "size"), nullptr));
10840  }
10841  result = detail::conditional_static_cast<std::size_t>(number);
10842  return true;
10843  }
10844 
10845  case '[':
10846  {
10847  if (input_format != input_format_t::bjdata)
10848  {
10849  break;
10850  }
10851  if (is_ndarray) // ndarray dimensional vector can only contain integers, and can not embed another array
10852  {
10853  return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read, exception_message(input_format, "ndarray dimentional vector is not allowed", "size"), nullptr));
10854  }
10855  std::vector<size_t> dim;
10856  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
10857  {
10858  return false;
10859  }
10860  if (dim.size() == 1 || (dim.size() == 2 && dim.at(0) == 1)) // return normal array size if 1D row vector
10861  {
10862  result = dim.at(dim.size() - 1);
10863  return true;
10864  }
10865  if (!dim.empty()) // if ndarray, convert to an object in JData annotated array format
10866  {
10867  for (auto i : dim) // test if any dimension in an ndarray is 0, if so, return a 1D empty container
10868  {
10869  if ( i == 0 )
10870  {
10871  result = 0;
10872  return true;
10873  }
10874  }
10875 
10876  string_t key = "_ArraySize_";
10877  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(3) || !sax->key(key) || !sax->start_array(dim.size())))
10878  {
10879  return false;
10880  }
10881  result = 1;
10882  for (auto i : dim)
10883  {
10884  result *= i;
10885  if (result == 0 || result == string_t::npos) // because dim elements shall not have zeros, result = 0 means overflow happened; it also can't be string_t::npos as it is used to initialize size in get_ubjson_size_type()
10886  {
10887  return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message(input_format, "excessive ndarray size caused overflow", "size"), nullptr));
10888  }
10889  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
10890  {
10891  return false;
10892  }
10893  }
10894  is_ndarray = true;
10895  return sax->end_array();
10896  }
10897  result = 0;
10898  return true;
10899  }
10900 
10901  default:
10902  break;
10903  }
10904  auto last_token = get_token_string();
10905  std::string message;
10906 
10907  if (input_format != input_format_t::bjdata)
10908  {
10909  message = "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token;
10910  }
10911  else
10912  {
10913  message = "expected length type specification (U, i, u, I, m, l, M, L) after '#'; last byte: 0x" + last_token;
10914  }
10915  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format, message, "size"), nullptr));
10916  }
10917 
10929  bool get_ubjson_size_type(std::pair<std::size_t, char_int_type>& result, bool inside_ndarray = false)
10930  {
10931  result.first = string_t::npos; // size
10932  result.second = 0; // type
10933  bool is_ndarray = false;
10934 
10935  get_ignore_noop();
10936 
10937  if (current == '$')
10938  {
10939  std::vector<char_int_type> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
10940 
10941  result.second = get(); // must not ignore 'N', because 'N' maybe the type
10942  if (JSON_HEDLEY_UNLIKELY( input_format == input_format_t::bjdata && std::find(bjdx.begin(), bjdx.end(), result.second) != bjdx.end() ))
10943  {
10944  auto last_token = get_token_string();
10945  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10946  exception_message(input_format, concat("marker 0x", last_token, " is not a permitted optimized array type"), "type"), nullptr));
10947  }
10948 
10949  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "type")))
10950  {
10951  return false;
10952  }
10953 
10954  get_ignore_noop();
10955  if (JSON_HEDLEY_UNLIKELY(current != '#'))
10956  {
10957  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "value")))
10958  {
10959  return false;
10960  }
10961  auto last_token = get_token_string();
10962  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
10963  exception_message(input_format, concat("expected '#' after type information; last byte: 0x", last_token), "size"), nullptr));
10964  }
10965 
10966  bool is_error = get_ubjson_size_value(result.first, is_ndarray);
10967  if (input_format == input_format_t::bjdata && is_ndarray)
10968  {
10969  if (inside_ndarray)
10970  {
10971  return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
10972  exception_message(input_format, "ndarray can not be recursive", "size"), nullptr));
10973  }
10974  result.second |= (1 << 8); // use bit 8 to indicate ndarray, all UBJSON and BJData markers should be ASCII letters
10975  }
10976  return is_error;
10977  }
10978 
10979  if (current == '#')
10980  {
10981  bool is_error = get_ubjson_size_value(result.first, is_ndarray);
10982  if (input_format == input_format_t::bjdata && is_ndarray)
10983  {
10984  return sax->parse_error(chars_read, get_token_string(), parse_error::create(112, chars_read,
10985  exception_message(input_format, "ndarray requires both type and size", "size"), nullptr));
10986  }
10987  return is_error;
10988  }
10989 
10990  return true;
10991  }
10992 
10997  bool get_ubjson_value(const char_int_type prefix)
10998  {
10999  switch (prefix)
11000  {
11001  case std::char_traits<char_type>::eof(): // EOF
11002  return unexpect_eof(input_format, "value");
11003 
11004  case 'T': // true
11005  return sax->boolean(true);
11006  case 'F': // false
11007  return sax->boolean(false);
11008 
11009  case 'Z': // null
11010  return sax->null();
11011 
11012  case 'U':
11013  {
11014  std::uint8_t number{};
11015  return get_number(input_format, number) && sax->number_unsigned(number);
11016  }
11017 
11018  case 'i':
11019  {
11020  std::int8_t number{};
11021  return get_number(input_format, number) && sax->number_integer(number);
11022  }
11023 
11024  case 'I':
11025  {
11026  std::int16_t number{};
11027  return get_number(input_format, number) && sax->number_integer(number);
11028  }
11029 
11030  case 'l':
11031  {
11032  std::int32_t number{};
11033  return get_number(input_format, number) && sax->number_integer(number);
11034  }
11035 
11036  case 'L':
11037  {
11038  std::int64_t number{};
11039  return get_number(input_format, number) && sax->number_integer(number);
11040  }
11041 
11042  case 'u':
11043  {
11044  if (input_format != input_format_t::bjdata)
11045  {
11046  break;
11047  }
11048  std::uint16_t number{};
11049  return get_number(input_format, number) && sax->number_unsigned(number);
11050  }
11051 
11052  case 'm':
11053  {
11054  if (input_format != input_format_t::bjdata)
11055  {
11056  break;
11057  }
11058  std::uint32_t number{};
11059  return get_number(input_format, number) && sax->number_unsigned(number);
11060  }
11061 
11062  case 'M':
11063  {
11064  if (input_format != input_format_t::bjdata)
11065  {
11066  break;
11067  }
11068  std::uint64_t number{};
11069  return get_number(input_format, number) && sax->number_unsigned(number);
11070  }
11071 
11072  case 'h':
11073  {
11074  if (input_format != input_format_t::bjdata)
11075  {
11076  break;
11077  }
11078  const auto byte1_raw = get();
11079  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11080  {
11081  return false;
11082  }
11083  const auto byte2_raw = get();
11084  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11085  {
11086  return false;
11087  }
11088 
11089  const auto byte1 = static_cast<unsigned char>(byte1_raw);
11090  const auto byte2 = static_cast<unsigned char>(byte2_raw);
11091 
11092  // code from RFC 7049, Appendix D, Figure 3:
11093  // As half-precision floating-point numbers were only added
11094  // to IEEE 754 in 2008, today's programming platforms often
11095  // still only have limited support for them. It is very
11096  // easy to include at least decoding support for them even
11097  // without such support. An example of a small decoder for
11098  // half-precision floating-point numbers in the C language
11099  // is shown in Fig. 3.
11100  const auto half = static_cast<unsigned int>((byte2 << 8u) + byte1);
11101  const double val = [&half]
11102  {
11103  const int exp = (half >> 10u) & 0x1Fu;
11104  const unsigned int mant = half & 0x3FFu;
11105  JSON_ASSERT(0 <= exp&& exp <= 32);
11106  JSON_ASSERT(mant <= 1024);
11107  switch (exp)
11108  {
11109  case 0:
11110  return std::ldexp(mant, -24);
11111  case 31:
11112  return (mant == 0)
11113  ? std::numeric_limits<double>::infinity()
11114  : std::numeric_limits<double>::quiet_NaN();
11115  default:
11116  return std::ldexp(mant + 1024, exp - 25);
11117  }
11118  }();
11119  return sax->number_float((half & 0x8000u) != 0
11120  ? static_cast<number_float_t>(-val)
11121  : static_cast<number_float_t>(val), "");
11122  }
11123 
11124  case 'd':
11125  {
11126  float number{};
11127  return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11128  }
11129 
11130  case 'D':
11131  {
11132  double number{};
11133  return get_number(input_format, number) && sax->number_float(static_cast<number_float_t>(number), "");
11134  }
11135 
11136  case 'H':
11137  {
11138  return get_ubjson_high_precision_number();
11139  }
11140 
11141  case 'C': // char
11142  {
11143  get();
11144  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "char")))
11145  {
11146  return false;
11147  }
11148  if (JSON_HEDLEY_UNLIKELY(current > 127))
11149  {
11150  auto last_token = get_token_string();
11151  return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read,
11152  exception_message(input_format, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", last_token), "char"), nullptr));
11153  }
11154  string_t s(1, static_cast<typename string_t::value_type>(current));
11155  return sax->string(s);
11156  }
11157 
11158  case 'S': // string
11159  {
11160  string_t s;
11161  return get_ubjson_string(s) && sax->string(s);
11162  }
11163 
11164  case '[': // array
11165  return get_ubjson_array();
11166 
11167  case '{': // object
11168  return get_ubjson_object();
11169 
11170  default: // anything else
11171  break;
11172  }
11173  auto last_token = get_token_string();
11174  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format, "invalid byte: 0x" + last_token, "value"), nullptr));
11175  }
11176 
11180  bool get_ubjson_array()
11181  {
11182  std::pair<std::size_t, char_int_type> size_and_type;
11183  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11184  {
11185  return false;
11186  }
11187 
11188  // if bit-8 of size_and_type.second is set to 1, encode bjdata ndarray as an object in JData annotated array format (https://github.com/NeuroJSON/jdata):
11189  // {"_ArrayType_" : "typeid", "_ArraySize_" : [n1, n2, ...], "_ArrayData_" : [v1, v2, ...]}
11190 
11191  if (input_format == input_format_t::bjdata && size_and_type.first != string_t::npos && (size_and_type.second & (1 << 8)) != 0)
11192  {
11193  std::map<char_int_type, string_t> bjdtype = {{'U', "uint8"}, {'i', "int8"}, {'u', "uint16"}, {'I', "int16"},
11194  {'m', "uint32"}, {'l', "int32"}, {'M', "uint64"}, {'L', "int64"}, {'d', "single"}, {'D', "double"}, {'C', "char"}
11195  };
11196 
11197  size_and_type.second &= ~(static_cast<char_int_type>(1) << 8); // use bit 8 to indicate ndarray, here we remove the bit to restore the type marker
11198 
11199  string_t key = "_ArrayType_";
11200  if (JSON_HEDLEY_UNLIKELY(bjdtype.count(size_and_type.second) == 0))
11201  {
11202  auto last_token = get_token_string();
11203  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11204  exception_message(input_format, "invalid byte: 0x" + last_token, "type"), nullptr));
11205  }
11206 
11207  if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->string(bjdtype[size_and_type.second]) ))
11208  {
11209  return false;
11210  }
11211 
11212  if (size_and_type.second == 'C')
11213  {
11214  size_and_type.second = 'U';
11215  }
11216 
11217  key = "_ArrayData_";
11218  if (JSON_HEDLEY_UNLIKELY(!sax->key(key) || !sax->start_array(size_and_type.first) ))
11219  {
11220  return false;
11221  }
11222 
11223  for (std::size_t i = 0; i < size_and_type.first; ++i)
11224  {
11225  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11226  {
11227  return false;
11228  }
11229  }
11230 
11231  return (sax->end_array() && sax->end_object());
11232  }
11233 
11234  if (size_and_type.first != string_t::npos)
11235  {
11236  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(size_and_type.first)))
11237  {
11238  return false;
11239  }
11240 
11241  if (size_and_type.second != 0)
11242  {
11243  if (size_and_type.second != 'N')
11244  {
11245  for (std::size_t i = 0; i < size_and_type.first; ++i)
11246  {
11247  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11248  {
11249  return false;
11250  }
11251  }
11252  }
11253  }
11254  else
11255  {
11256  for (std::size_t i = 0; i < size_and_type.first; ++i)
11257  {
11258  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11259  {
11260  return false;
11261  }
11262  }
11263  }
11264  }
11265  else
11266  {
11267  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
11268  {
11269  return false;
11270  }
11271 
11272  while (current != ']')
11273  {
11274  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal(false)))
11275  {
11276  return false;
11277  }
11278  get_ignore_noop();
11279  }
11280  }
11281 
11282  return sax->end_array();
11283  }
11284 
11288  bool get_ubjson_object()
11289  {
11290  std::pair<std::size_t, char_int_type> size_and_type;
11291  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_size_type(size_and_type)))
11292  {
11293  return false;
11294  }
11295 
11296  // do not accept ND-array size in objects in BJData
11297  if (input_format == input_format_t::bjdata && size_and_type.first != string_t::npos && (size_and_type.second & (1 << 8)) != 0)
11298  {
11299  auto last_token = get_token_string();
11300  return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read,
11301  exception_message(input_format, "BJData object does not support ND-array size in optimized format", "object"), nullptr));
11302  }
11303 
11304  string_t key;
11305  if (size_and_type.first != string_t::npos)
11306  {
11307  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(size_and_type.first)))
11308  {
11309  return false;
11310  }
11311 
11312  if (size_and_type.second != 0)
11313  {
11314  for (std::size_t i = 0; i < size_and_type.first; ++i)
11315  {
11316  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11317  {
11318  return false;
11319  }
11320  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_value(size_and_type.second)))
11321  {
11322  return false;
11323  }
11324  key.clear();
11325  }
11326  }
11327  else
11328  {
11329  for (std::size_t i = 0; i < size_and_type.first; ++i)
11330  {
11331  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key) || !sax->key(key)))
11332  {
11333  return false;
11334  }
11335  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11336  {
11337  return false;
11338  }
11339  key.clear();
11340  }
11341  }
11342  }
11343  else
11344  {
11345  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11346  {
11347  return false;
11348  }
11349 
11350  while (current != '}')
11351  {
11352  if (JSON_HEDLEY_UNLIKELY(!get_ubjson_string(key, false) || !sax->key(key)))
11353  {
11354  return false;
11355  }
11356  if (JSON_HEDLEY_UNLIKELY(!parse_ubjson_internal()))
11357  {
11358  return false;
11359  }
11360  get_ignore_noop();
11361  key.clear();
11362  }
11363  }
11364 
11365  return sax->end_object();
11366  }
11367 
11368  // Note, no reader for UBJSON binary types is implemented because they do
11369  // not exist
11370 
11371  bool get_ubjson_high_precision_number()
11372  {
11373  // get size of following number string
11374  std::size_t size{};
11375  bool no_ndarray = true;
11376  auto res = get_ubjson_size_value(size, no_ndarray);
11377  if (JSON_HEDLEY_UNLIKELY(!res))
11378  {
11379  return res;
11380  }
11381 
11382  // get number string
11383  std::vector<char> number_vector;
11384  for (std::size_t i = 0; i < size; ++i)
11385  {
11386  get();
11387  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(input_format, "number")))
11388  {
11389  return false;
11390  }
11391  number_vector.push_back(static_cast<char>(current));
11392  }
11393 
11394  // parse number string
11395  using ia_type = decltype(detail::input_adapter(number_vector));
11396  auto number_lexer = detail::lexer<BasicJsonType, ia_type>(detail::input_adapter(number_vector), false);
11397  const auto result_number = number_lexer.scan();
11398  const auto number_string = number_lexer.get_token_string();
11399  const auto result_remainder = number_lexer.scan();
11400 
11401  using token_type = typename detail::lexer_base<BasicJsonType>::token_type;
11402 
11403  if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
11404  {
11405  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11406  exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11407  }
11408 
11409  switch (result_number)
11410  {
11411  case token_type::value_integer:
11412  return sax->number_integer(number_lexer.get_number_integer());
11413  case token_type::value_unsigned:
11414  return sax->number_unsigned(number_lexer.get_number_unsigned());
11415  case token_type::value_float:
11416  return sax->number_float(number_lexer.get_number_float(), std::move(number_string));
11417  case token_type::uninitialized:
11418  case token_type::literal_true:
11419  case token_type::literal_false:
11420  case token_type::literal_null:
11421  case token_type::value_string:
11422  case token_type::begin_array:
11423  case token_type::begin_object:
11424  case token_type::end_array:
11425  case token_type::end_object:
11426  case token_type::name_separator:
11427  case token_type::value_separator:
11428  case token_type::parse_error:
11429  case token_type::end_of_input:
11430  case token_type::literal_or_value:
11431  default:
11432  return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
11433  exception_message(input_format, concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
11434  }
11435  }
11436 
11438  // Utility functions //
11440 
11450  char_int_type get()
11451  {
11452  ++chars_read;
11453  return current = ia.get_character();
11454  }
11455 
11459  char_int_type get_ignore_noop()
11460  {
11461  do
11462  {
11463  get();
11464  }
11465  while (current == 'N');
11466 
11467  return current;
11468  }
11469 
11470  /*
11471  @brief read a number from the input
11472 
11473  @tparam NumberType the type of the number
11474  @param[in] format the current format (for diagnostics)
11475  @param[out] result number of type @a NumberType
11476 
11477  @return whether conversion completed
11478 
11479  @note This function needs to respect the system's endianness, because
11480  bytes in CBOR, MessagePack, and UBJSON are stored in network order
11481  (big endian) and therefore need reordering on little endian systems.
11482  On the other hand, BSON and BJData use little endian and should reorder
11483  on big endian systems.
11484  */
11485  template<typename NumberType, bool InputIsLittleEndian = false>
11486  bool get_number(const input_format_t format, NumberType& result)
11487  {
11488  // step 1: read input into array with system's byte order
11489  std::array<std::uint8_t, sizeof(NumberType)> vec{};
11490  for (std::size_t i = 0; i < sizeof(NumberType); ++i)
11491  {
11492  get();
11493  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "number")))
11494  {
11495  return false;
11496  }
11497 
11498  // reverse byte order prior to conversion if necessary
11499  if (is_little_endian != (InputIsLittleEndian || format == input_format_t::bjdata))
11500  {
11501  vec[sizeof(NumberType) - i - 1] = static_cast<std::uint8_t>(current);
11502  }
11503  else
11504  {
11505  vec[i] = static_cast<std::uint8_t>(current); // LCOV_EXCL_LINE
11506  }
11507  }
11508 
11509  // step 2: convert array into number of type T and return
11510  std::memcpy(&result, vec.data(), sizeof(NumberType));
11511  return true;
11512  }
11513 
11528  template<typename NumberType>
11529  bool get_string(const input_format_t format,
11530  const NumberType len,
11531  string_t& result)
11532  {
11533  bool success = true;
11534  for (NumberType i = 0; i < len; i++)
11535  {
11536  get();
11537  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "string")))
11538  {
11539  success = false;
11540  break;
11541  }
11542  result.push_back(static_cast<typename string_t::value_type>(current));
11543  }
11544  return success;
11545  }
11546 
11561  template<typename NumberType>
11562  bool get_binary(const input_format_t format,
11563  const NumberType len,
11564  binary_t& result)
11565  {
11566  bool success = true;
11567  for (NumberType i = 0; i < len; i++)
11568  {
11569  get();
11570  if (JSON_HEDLEY_UNLIKELY(!unexpect_eof(format, "binary")))
11571  {
11572  success = false;
11573  break;
11574  }
11575  result.push_back(static_cast<std::uint8_t>(current));
11576  }
11577  return success;
11578  }
11579 
11586  bool unexpect_eof(const input_format_t format, const char* context) const
11587  {
11588  if (JSON_HEDLEY_UNLIKELY(current == std::char_traits<char_type>::eof()))
11589  {
11590  return sax->parse_error(chars_read, "<end of file>",
11591  parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context), nullptr));
11592  }
11593  return true;
11594  }
11595 
11599  std::string get_token_string() const
11600  {
11601  std::array<char, 3> cr{{}};
11602  static_cast<void>((std::snprintf)(cr.data(), cr.size(), "%.2hhX", static_cast<unsigned char>(current))); // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
11603  return std::string{cr.data()};
11604  }
11605 
11612  std::string exception_message(const input_format_t format,
11613  const std::string& detail,
11614  const std::string& context) const
11615  {
11616  std::string error_msg = "syntax error while parsing ";
11617 
11618  switch (format)
11619  {
11620  case input_format_t::cbor:
11621  error_msg += "CBOR";
11622  break;
11623 
11625  error_msg += "MessagePack";
11626  break;
11627 
11629  error_msg += "UBJSON";
11630  break;
11631 
11632  case input_format_t::bson:
11633  error_msg += "BSON";
11634  break;
11635 
11637  error_msg += "BJData";
11638  break;
11639 
11640  case input_format_t::json: // LCOV_EXCL_LINE
11641  default: // LCOV_EXCL_LINE
11642  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
11643  }
11644 
11645  return concat(error_msg, ' ', context, ": ", detail);
11646  }
11647 
11648  private:
11650  InputAdapterType ia;
11651 
11653  char_int_type current = std::char_traits<char_type>::eof();
11654 
11656  std::size_t chars_read = 0;
11657 
11659  const bool is_little_endian = little_endianness();
11660 
11662  const input_format_t input_format = input_format_t::json;
11663 
11665  json_sax_t* sax = nullptr;
11666 };
11667 } // namespace detail
11668 } // namespace nlohmann
11669 
11670 // #include <nlohmann/detail/input/input_adapters.hpp>
11671 
11672 // #include <nlohmann/detail/input/lexer.hpp>
11673 
11674 // #include <nlohmann/detail/input/parser.hpp>
11675 
11676 
11677 #include <cmath> // isfinite
11678 #include <cstdint> // uint8_t
11679 #include <functional> // function
11680 #include <string> // string
11681 #include <utility> // move
11682 #include <vector> // vector
11683 
11684 // #include <nlohmann/detail/exceptions.hpp>
11685 
11686 // #include <nlohmann/detail/input/input_adapters.hpp>
11687 
11688 // #include <nlohmann/detail/input/json_sax.hpp>
11689 
11690 // #include <nlohmann/detail/input/lexer.hpp>
11691 
11692 // #include <nlohmann/detail/macro_scope.hpp>
11693 
11694 // #include <nlohmann/detail/meta/is_sax.hpp>
11695 
11696 // #include <nlohmann/detail/string_concat.hpp>
11697 
11698 // #include <nlohmann/detail/value_t.hpp>
11699 
11700 
11701 namespace nlohmann
11702 {
11703 namespace detail
11704 {
11706 // parser //
11708 
11709 enum class parse_event_t : std::uint8_t
11710 {
11712  object_start,
11714  object_end,
11716  array_start,
11718  array_end,
11720  key,
11722  value
11723 };
11724 
11725 template<typename BasicJsonType>
11727  std::function<bool(int /*depth*/, parse_event_t /*event*/, BasicJsonType& /*parsed*/)>;
11728 
11734 template<typename BasicJsonType, typename InputAdapterType>
11735 class parser
11736 {
11737  using number_integer_t = typename BasicJsonType::number_integer_t;
11738  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
11739  using number_float_t = typename BasicJsonType::number_float_t;
11740  using string_t = typename BasicJsonType::string_t;
11742  using token_type = typename lexer_t::token_type;
11743 
11744  public:
11746  explicit parser(InputAdapterType&& adapter,
11747  const parser_callback_t<BasicJsonType> cb = nullptr,
11748  const bool allow_exceptions_ = true,
11749  const bool skip_comments = false)
11750  : callback(cb)
11751  , m_lexer(std::move(adapter), skip_comments)
11752  , allow_exceptions(allow_exceptions_)
11753  {
11754  // read first token
11755  get_token();
11756  }
11757 
11768  void parse(const bool strict, BasicJsonType& result)
11769  {
11770  if (callback)
11771  {
11772  json_sax_dom_callback_parser<BasicJsonType> sdp(result, callback, allow_exceptions);
11773  sax_parse_internal(&sdp);
11774 
11775  // in strict mode, input must be completely read
11776  if (strict && (get_token() != token_type::end_of_input))
11777  {
11778  sdp.parse_error(m_lexer.get_position(),
11779  m_lexer.get_token_string(),
11780  parse_error::create(101, m_lexer.get_position(),
11781  exception_message(token_type::end_of_input, "value"), nullptr));
11782  }
11783 
11784  // in case of an error, return discarded value
11785  if (sdp.is_errored())
11786  {
11787  result = value_t::discarded;
11788  return;
11789  }
11790 
11791  // set top-level value to null if it was discarded by the callback
11792  // function
11793  if (result.is_discarded())
11794  {
11795  result = nullptr;
11796  }
11797  }
11798  else
11799  {
11800  json_sax_dom_parser<BasicJsonType> sdp(result, allow_exceptions);
11801  sax_parse_internal(&sdp);
11802 
11803  // in strict mode, input must be completely read
11804  if (strict && (get_token() != token_type::end_of_input))
11805  {
11806  sdp.parse_error(m_lexer.get_position(),
11807  m_lexer.get_token_string(),
11808  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
11809  }
11810 
11811  // in case of an error, return discarded value
11812  if (sdp.is_errored())
11813  {
11814  result = value_t::discarded;
11815  return;
11816  }
11817  }
11818 
11819  result.assert_invariant();
11820  }
11821 
11828  bool accept(const bool strict = true)
11829  {
11830  json_sax_acceptor<BasicJsonType> sax_acceptor;
11831  return sax_parse(&sax_acceptor, strict);
11832  }
11833 
11834  template<typename SAX>
11836  bool sax_parse(SAX* sax, const bool strict = true)
11837  {
11839  const bool result = sax_parse_internal(sax);
11840 
11841  // strict mode: next byte must be EOF
11842  if (result && strict && (get_token() != token_type::end_of_input))
11843  {
11844  return sax->parse_error(m_lexer.get_position(),
11845  m_lexer.get_token_string(),
11846  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_of_input, "value"), nullptr));
11847  }
11848 
11849  return result;
11850  }
11851 
11852  private:
11853  template<typename SAX>
11855  bool sax_parse_internal(SAX* sax)
11856  {
11857  // stack to remember the hierarchy of structured values we are parsing
11858  // true = array; false = object
11859  std::vector<bool> states;
11860  // value to avoid a goto (see comment where set to true)
11861  bool skip_to_state_evaluation = false;
11862 
11863  while (true)
11864  {
11865  if (!skip_to_state_evaluation)
11866  {
11867  // invariant: get_token() was called before each iteration
11868  switch (last_token)
11869  {
11870  case token_type::begin_object:
11871  {
11872  if (JSON_HEDLEY_UNLIKELY(!sax->start_object(static_cast<std::size_t>(-1))))
11873  {
11874  return false;
11875  }
11876 
11877  // closing } -> we are done
11878  if (get_token() == token_type::end_object)
11879  {
11880  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
11881  {
11882  return false;
11883  }
11884  break;
11885  }
11886 
11887  // parse key
11888  if (JSON_HEDLEY_UNLIKELY(last_token != token_type::value_string))
11889  {
11890  return sax->parse_error(m_lexer.get_position(),
11891  m_lexer.get_token_string(),
11892  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
11893  }
11894  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
11895  {
11896  return false;
11897  }
11898 
11899  // parse separator (:)
11900  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
11901  {
11902  return sax->parse_error(m_lexer.get_position(),
11903  m_lexer.get_token_string(),
11904  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
11905  }
11906 
11907  // remember we are now inside an object
11908  states.push_back(false);
11909 
11910  // parse values
11911  get_token();
11912  continue;
11913  }
11914 
11915  case token_type::begin_array:
11916  {
11917  if (JSON_HEDLEY_UNLIKELY(!sax->start_array(static_cast<std::size_t>(-1))))
11918  {
11919  return false;
11920  }
11921 
11922  // closing ] -> we are done
11923  if (get_token() == token_type::end_array)
11924  {
11925  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
11926  {
11927  return false;
11928  }
11929  break;
11930  }
11931 
11932  // remember we are now inside an array
11933  states.push_back(true);
11934 
11935  // parse values (no need to call get_token)
11936  continue;
11937  }
11938 
11939  case token_type::value_float:
11940  {
11941  const auto res = m_lexer.get_number_float();
11942 
11943  if (JSON_HEDLEY_UNLIKELY(!std::isfinite(res)))
11944  {
11945  return sax->parse_error(m_lexer.get_position(),
11946  m_lexer.get_token_string(),
11947  out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
11948  }
11949 
11950  if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
11951  {
11952  return false;
11953  }
11954 
11955  break;
11956  }
11957 
11958  case token_type::literal_false:
11959  {
11960  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(false)))
11961  {
11962  return false;
11963  }
11964  break;
11965  }
11966 
11967  case token_type::literal_null:
11968  {
11969  if (JSON_HEDLEY_UNLIKELY(!sax->null()))
11970  {
11971  return false;
11972  }
11973  break;
11974  }
11975 
11976  case token_type::literal_true:
11977  {
11978  if (JSON_HEDLEY_UNLIKELY(!sax->boolean(true)))
11979  {
11980  return false;
11981  }
11982  break;
11983  }
11984 
11985  case token_type::value_integer:
11986  {
11987  if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(m_lexer.get_number_integer())))
11988  {
11989  return false;
11990  }
11991  break;
11992  }
11993 
11994  case token_type::value_string:
11995  {
11996  if (JSON_HEDLEY_UNLIKELY(!sax->string(m_lexer.get_string())))
11997  {
11998  return false;
11999  }
12000  break;
12001  }
12002 
12003  case token_type::value_unsigned:
12004  {
12005  if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(m_lexer.get_number_unsigned())))
12006  {
12007  return false;
12008  }
12009  break;
12010  }
12011 
12012  case token_type::parse_error:
12013  {
12014  // using "uninitialized" to avoid "expected" message
12015  return sax->parse_error(m_lexer.get_position(),
12016  m_lexer.get_token_string(),
12017  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::uninitialized, "value"), nullptr));
12018  }
12019 
12020  case token_type::uninitialized:
12021  case token_type::end_array:
12022  case token_type::end_object:
12023  case token_type::name_separator:
12024  case token_type::value_separator:
12025  case token_type::end_of_input:
12026  case token_type::literal_or_value:
12027  default: // the last token was unexpected
12028  {
12029  return sax->parse_error(m_lexer.get_position(),
12030  m_lexer.get_token_string(),
12031  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::literal_or_value, "value"), nullptr));
12032  }
12033  }
12034  }
12035  else
12036  {
12037  skip_to_state_evaluation = false;
12038  }
12039 
12040  // we reached this line after we successfully parsed a value
12041  if (states.empty())
12042  {
12043  // empty stack: we reached the end of the hierarchy: done
12044  return true;
12045  }
12046 
12047  if (states.back()) // array
12048  {
12049  // comma -> next value
12050  if (get_token() == token_type::value_separator)
12051  {
12052  // parse a new value
12053  get_token();
12054  continue;
12055  }
12056 
12057  // closing ]
12058  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_array))
12059  {
12060  if (JSON_HEDLEY_UNLIKELY(!sax->end_array()))
12061  {
12062  return false;
12063  }
12064 
12065  // We are done with this array. Before we can parse a
12066  // new value, we need to evaluate the new state first.
12067  // By setting skip_to_state_evaluation to false, we
12068  // are effectively jumping to the beginning of this if.
12069  JSON_ASSERT(!states.empty());
12070  states.pop_back();
12071  skip_to_state_evaluation = true;
12072  continue;
12073  }
12074 
12075  return sax->parse_error(m_lexer.get_position(),
12076  m_lexer.get_token_string(),
12077  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_array, "array"), nullptr));
12078  }
12079 
12080  // states.back() is false -> object
12081 
12082  // comma -> next value
12083  if (get_token() == token_type::value_separator)
12084  {
12085  // parse key
12086  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::value_string))
12087  {
12088  return sax->parse_error(m_lexer.get_position(),
12089  m_lexer.get_token_string(),
12090  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::value_string, "object key"), nullptr));
12091  }
12092 
12093  if (JSON_HEDLEY_UNLIKELY(!sax->key(m_lexer.get_string())))
12094  {
12095  return false;
12096  }
12097 
12098  // parse separator (:)
12099  if (JSON_HEDLEY_UNLIKELY(get_token() != token_type::name_separator))
12100  {
12101  return sax->parse_error(m_lexer.get_position(),
12102  m_lexer.get_token_string(),
12103  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator, "object separator"), nullptr));
12104  }
12105 
12106  // parse values
12107  get_token();
12108  continue;
12109  }
12110 
12111  // closing }
12112  if (JSON_HEDLEY_LIKELY(last_token == token_type::end_object))
12113  {
12114  if (JSON_HEDLEY_UNLIKELY(!sax->end_object()))
12115  {
12116  return false;
12117  }
12118 
12119  // We are done with this object. Before we can parse a
12120  // new value, we need to evaluate the new state first.
12121  // By setting skip_to_state_evaluation to false, we
12122  // are effectively jumping to the beginning of this if.
12123  JSON_ASSERT(!states.empty());
12124  states.pop_back();
12125  skip_to_state_evaluation = true;
12126  continue;
12127  }
12128 
12129  return sax->parse_error(m_lexer.get_position(),
12130  m_lexer.get_token_string(),
12131  parse_error::create(101, m_lexer.get_position(), exception_message(token_type::end_object, "object"), nullptr));
12132  }
12133  }
12134 
12136  token_type get_token()
12137  {
12138  return last_token = m_lexer.scan();
12139  }
12140 
12141  std::string exception_message(const token_type expected, const std::string& context)
12142  {
12143  std::string error_msg = "syntax error ";
12144 
12145  if (!context.empty())
12146  {
12147  error_msg += concat("while parsing ", context, ' ');
12148  }
12149 
12150  error_msg += "- ";
12151 
12152  if (last_token == token_type::parse_error)
12153  {
12154  error_msg += concat(m_lexer.get_error_message(), "; last read: '",
12155  m_lexer.get_token_string(), '\'');
12156  }
12157  else
12158  {
12159  error_msg += concat("unexpected ", lexer_t::token_type_name(last_token));
12160  }
12161 
12162  if (expected != token_type::uninitialized)
12163  {
12164  error_msg += concat("; expected ", lexer_t::token_type_name(expected));
12165  }
12166 
12167  return error_msg;
12168  }
12169 
12170  private:
12172  const parser_callback_t<BasicJsonType> callback = nullptr;
12174  token_type last_token = token_type::uninitialized;
12176  lexer_t m_lexer;
12178  const bool allow_exceptions = true;
12179 };
12180 
12181 } // namespace detail
12182 } // namespace nlohmann
12183 
12184 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
12185 
12186 
12187 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12188 
12189 
12190 #include <cstddef> // ptrdiff_t
12191 #include <limits> // numeric_limits
12192 
12193 // #include <nlohmann/detail/macro_scope.hpp>
12194 
12195 
12196 namespace nlohmann
12197 {
12198 namespace detail
12199 {
12200 /*
12201 @brief an iterator for primitive JSON types
12202 
12203 This class models an iterator for primitive JSON types (boolean, number,
12204 string). It's only purpose is to allow the iterator/const_iterator classes
12205 to "iterate" over primitive values. Internally, the iterator is modeled by
12206 a `difference_type` variable. Value begin_value (`0`) models the begin,
12207 end_value (`1`) models past the end.
12208 */
12210 {
12211  private:
12212  using difference_type = std::ptrdiff_t;
12213  static constexpr difference_type begin_value = 0;
12214  static constexpr difference_type end_value = begin_value + 1;
12215 
12218  difference_type m_it = (std::numeric_limits<std::ptrdiff_t>::min)();
12219 
12220  public:
12221  constexpr difference_type get_value() const noexcept
12222  {
12223  return m_it;
12224  }
12225 
12227  void set_begin() noexcept
12228  {
12229  m_it = begin_value;
12230  }
12231 
12233  void set_end() noexcept
12234  {
12235  m_it = end_value;
12236  }
12237 
12239  constexpr bool is_begin() const noexcept
12240  {
12241  return m_it == begin_value;
12242  }
12243 
12245  constexpr bool is_end() const noexcept
12246  {
12247  return m_it == end_value;
12248  }
12249 
12250  friend constexpr bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12251  {
12252  return lhs.m_it == rhs.m_it;
12253  }
12254 
12255  friend constexpr bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12256  {
12257  return lhs.m_it < rhs.m_it;
12258  }
12259 
12260  primitive_iterator_t operator+(difference_type n) noexcept
12261  {
12262  auto result = *this;
12263  result += n;
12264  return result;
12265  }
12266 
12267  friend constexpr difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
12268  {
12269  return lhs.m_it - rhs.m_it;
12270  }
12271 
12273  {
12274  ++m_it;
12275  return *this;
12276  }
12277 
12278  primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
12279  {
12280  auto result = *this;
12281  ++m_it;
12282  return result;
12283  }
12284 
12286  {
12287  --m_it;
12288  return *this;
12289  }
12290 
12291  primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
12292  {
12293  auto result = *this;
12294  --m_it;
12295  return result;
12296  }
12297 
12298  primitive_iterator_t& operator+=(difference_type n) noexcept
12299  {
12300  m_it += n;
12301  return *this;
12302  }
12303 
12304  primitive_iterator_t& operator-=(difference_type n) noexcept
12305  {
12306  m_it -= n;
12307  return *this;
12308  }
12309 };
12310 } // namespace detail
12311 } // namespace nlohmann
12312 
12313 
12314 namespace nlohmann
12315 {
12316 namespace detail
12317 {
12324 template<typename BasicJsonType> struct internal_iterator
12325 {
12327  typename BasicJsonType::object_t::iterator object_iterator {};
12329  typename BasicJsonType::array_t::iterator array_iterator {};
12332 };
12333 } // namespace detail
12334 } // namespace nlohmann
12335 
12336 // #include <nlohmann/detail/iterators/iter_impl.hpp>
12337 
12338 
12339 #include <iterator> // iterator, random_access_iterator_tag, bidirectional_iterator_tag, advance, next
12340 #include <type_traits> // conditional, is_const, remove_const
12341 
12342 // #include <nlohmann/detail/exceptions.hpp>
12343 
12344 // #include <nlohmann/detail/iterators/internal_iterator.hpp>
12345 
12346 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
12347 
12348 // #include <nlohmann/detail/macro_scope.hpp>
12349 
12350 // #include <nlohmann/detail/meta/cpp_future.hpp>
12351 
12352 // #include <nlohmann/detail/meta/type_traits.hpp>
12353 
12354 // #include <nlohmann/detail/value_t.hpp>
12355 
12356 
12357 namespace nlohmann
12358 {
12359 namespace detail
12360 {
12361 // forward declare, to be able to friend it later on
12362 template<typename IteratorType> class iteration_proxy;
12363 template<typename IteratorType> class iteration_proxy_value;
12364 
12381 template<typename BasicJsonType>
12382 class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
12383 {
12387  friend other_iter_impl;
12388  friend BasicJsonType;
12391 
12392  using object_t = typename BasicJsonType::object_t;
12393  using array_t = typename BasicJsonType::array_t;
12394  // make sure BasicJsonType is basic_json or const basic_json
12396  "iter_impl only accepts (const) basic_json");
12397  // superficial check for the LegacyBidirectionalIterator named requirement
12398  static_assert(std::is_base_of<std::bidirectional_iterator_tag, std::bidirectional_iterator_tag>::value
12399  && std::is_base_of<std::bidirectional_iterator_tag, typename std::iterator_traits<typename array_t::iterator>::iterator_category>::value,
12400  "basic_json iterator assumes array and object type iterators satisfy the LegacyBidirectionalIterator named requirement.");
12401 
12402  public:
12408  using iterator_category = std::bidirectional_iterator_tag;
12409 
12411  using value_type = typename BasicJsonType::value_type;
12413  using difference_type = typename BasicJsonType::difference_type;
12415  using pointer = typename std::conditional<std::is_const<BasicJsonType>::value,
12416  typename BasicJsonType::const_pointer,
12417  typename BasicJsonType::pointer>::type;
12419  using reference =
12420  typename std::conditional<std::is_const<BasicJsonType>::value,
12421  typename BasicJsonType::const_reference,
12422  typename BasicJsonType::reference>::type;
12423 
12424  iter_impl() = default;
12425  ~iter_impl() = default;
12426  iter_impl(iter_impl&&) noexcept = default;
12427  iter_impl& operator=(iter_impl&&) noexcept = default;
12428 
12435  explicit iter_impl(pointer object) noexcept : m_object(object)
12436  {
12437  JSON_ASSERT(m_object != nullptr);
12438 
12439  switch (m_object->m_type)
12440  {
12441  case value_t::object:
12442  {
12443  m_it.object_iterator = typename object_t::iterator();
12444  break;
12445  }
12446 
12447  case value_t::array:
12448  {
12449  m_it.array_iterator = typename array_t::iterator();
12450  break;
12451  }
12452 
12453  case value_t::null:
12454  case value_t::string:
12455  case value_t::boolean:
12458  case value_t::number_float:
12459  case value_t::binary:
12460  case value_t::discarded:
12461  default:
12462  {
12464  break;
12465  }
12466  }
12467  }
12468 
12486  : m_object(other.m_object), m_it(other.m_it)
12487  {}
12488 
12496  {
12497  if (&other != this)
12498  {
12499  m_object = other.m_object;
12500  m_it = other.m_it;
12501  }
12502  return *this;
12503  }
12504 
12511  : m_object(other.m_object), m_it(other.m_it)
12512  {}
12513 
12520  iter_impl& operator=(const iter_impl<typename std::remove_const<BasicJsonType>::type>& other) noexcept // NOLINT(cert-oop54-cpp)
12521  {
12522  m_object = other.m_object;
12523  m_it = other.m_it;
12524  return *this;
12525  }
12526 
12532  void set_begin() noexcept
12533  {
12534  JSON_ASSERT(m_object != nullptr);
12535 
12536  switch (m_object->m_type)
12537  {
12538  case value_t::object:
12539  {
12540  m_it.object_iterator = m_object->m_value.object->begin();
12541  break;
12542  }
12543 
12544  case value_t::array:
12545  {
12546  m_it.array_iterator = m_object->m_value.array->begin();
12547  break;
12548  }
12549 
12550  case value_t::null:
12551  {
12552  // set to end so begin()==end() is true: null is empty
12554  break;
12555  }
12556 
12557  case value_t::string:
12558  case value_t::boolean:
12561  case value_t::number_float:
12562  case value_t::binary:
12563  case value_t::discarded:
12564  default:
12565  {
12567  break;
12568  }
12569  }
12570  }
12571 
12576  void set_end() noexcept
12577  {
12578  JSON_ASSERT(m_object != nullptr);
12579 
12580  switch (m_object->m_type)
12581  {
12582  case value_t::object:
12583  {
12584  m_it.object_iterator = m_object->m_value.object->end();
12585  break;
12586  }
12587 
12588  case value_t::array:
12589  {
12590  m_it.array_iterator = m_object->m_value.array->end();
12591  break;
12592  }
12593 
12594  case value_t::null:
12595  case value_t::string:
12596  case value_t::boolean:
12599  case value_t::number_float:
12600  case value_t::binary:
12601  case value_t::discarded:
12602  default:
12603  {
12605  break;
12606  }
12607  }
12608  }
12609 
12610  public:
12616  {
12617  JSON_ASSERT(m_object != nullptr);
12618 
12619  switch (m_object->m_type)
12620  {
12621  case value_t::object:
12622  {
12623  JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
12624  return m_it.object_iterator->second;
12625  }
12626 
12627  case value_t::array:
12628  {
12629  JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
12630  return *m_it.array_iterator;
12631  }
12632 
12633  case value_t::null:
12634  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12635 
12636  case value_t::string:
12637  case value_t::boolean:
12640  case value_t::number_float:
12641  case value_t::binary:
12642  case value_t::discarded:
12643  default:
12644  {
12646  {
12647  return *m_object;
12648  }
12649 
12650  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12651  }
12652  }
12653  }
12654 
12660  {
12661  JSON_ASSERT(m_object != nullptr);
12662 
12663  switch (m_object->m_type)
12664  {
12665  case value_t::object:
12666  {
12667  JSON_ASSERT(m_it.object_iterator != m_object->m_value.object->end());
12668  return &(m_it.object_iterator->second);
12669  }
12670 
12671  case value_t::array:
12672  {
12673  JSON_ASSERT(m_it.array_iterator != m_object->m_value.array->end());
12674  return &*m_it.array_iterator;
12675  }
12676 
12677  case value_t::null:
12678  case value_t::string:
12679  case value_t::boolean:
12682  case value_t::number_float:
12683  case value_t::binary:
12684  case value_t::discarded:
12685  default:
12686  {
12688  {
12689  return m_object;
12690  }
12691 
12692  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
12693  }
12694  }
12695  }
12696 
12701  iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
12702  {
12703  auto result = *this;
12704  ++(*this);
12705  return result;
12706  }
12707 
12713  {
12714  JSON_ASSERT(m_object != nullptr);
12715 
12716  switch (m_object->m_type)
12717  {
12718  case value_t::object:
12719  {
12720  std::advance(m_it.object_iterator, 1);
12721  break;
12722  }
12723 
12724  case value_t::array:
12725  {
12726  std::advance(m_it.array_iterator, 1);
12727  break;
12728  }
12729 
12730  case value_t::null:
12731  case value_t::string:
12732  case value_t::boolean:
12735  case value_t::number_float:
12736  case value_t::binary:
12737  case value_t::discarded:
12738  default:
12739  {
12741  break;
12742  }
12743  }
12744 
12745  return *this;
12746  }
12747 
12752  iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
12753  {
12754  auto result = *this;
12755  --(*this);
12756  return result;
12757  }
12758 
12764  {
12765  JSON_ASSERT(m_object != nullptr);
12766 
12767  switch (m_object->m_type)
12768  {
12769  case value_t::object:
12770  {
12771  std::advance(m_it.object_iterator, -1);
12772  break;
12773  }
12774 
12775  case value_t::array:
12776  {
12777  std::advance(m_it.array_iterator, -1);
12778  break;
12779  }
12780 
12781  case value_t::null:
12782  case value_t::string:
12783  case value_t::boolean:
12786  case value_t::number_float:
12787  case value_t::binary:
12788  case value_t::discarded:
12789  default:
12790  {
12792  break;
12793  }
12794  }
12795 
12796  return *this;
12797  }
12798 
12803  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 >
12804  bool operator==(const IterImpl& other) const
12805  {
12806  // if objects are not the same, the comparison is undefined
12807  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12808  {
12809  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
12810  }
12811 
12812  JSON_ASSERT(m_object != nullptr);
12813 
12814  switch (m_object->m_type)
12815  {
12816  case value_t::object:
12817  return (m_it.object_iterator == other.m_it.object_iterator);
12818 
12819  case value_t::array:
12820  return (m_it.array_iterator == other.m_it.array_iterator);
12821 
12822  case value_t::null:
12823  case value_t::string:
12824  case value_t::boolean:
12827  case value_t::number_float:
12828  case value_t::binary:
12829  case value_t::discarded:
12830  default:
12831  return (m_it.primitive_iterator == other.m_it.primitive_iterator);
12832  }
12833  }
12834 
12839  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 >
12840  bool operator!=(const IterImpl& other) const
12841  {
12842  return !operator==(other);
12843  }
12844 
12849  bool operator<(const iter_impl& other) const
12850  {
12851  // if objects are not the same, the comparison is undefined
12852  if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
12853  {
12854  JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
12855  }
12856 
12857  JSON_ASSERT(m_object != nullptr);
12858 
12859  switch (m_object->m_type)
12860  {
12861  case value_t::object:
12862  JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
12863 
12864  case value_t::array:
12865  return (m_it.array_iterator < other.m_it.array_iterator);
12866 
12867  case value_t::null:
12868  case value_t::string:
12869  case value_t::boolean:
12872  case value_t::number_float:
12873  case value_t::binary:
12874  case value_t::discarded:
12875  default:
12877  }
12878  }
12879 
12884  bool operator<=(const iter_impl& other) const
12885  {
12886  return !other.operator < (*this);
12887  }
12888 
12893  bool operator>(const iter_impl& other) const
12894  {
12895  return !operator<=(other);
12896  }
12897 
12902  bool operator>=(const iter_impl& other) const
12903  {
12904  return !operator<(other);
12905  }
12906 
12912  {
12913  JSON_ASSERT(m_object != nullptr);
12914 
12915  switch (m_object->m_type)
12916  {
12917  case value_t::object:
12918  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
12919 
12920  case value_t::array:
12921  {
12922  std::advance(m_it.array_iterator, i);
12923  break;
12924  }
12925 
12926  case value_t::null:
12927  case value_t::string:
12928  case value_t::boolean:
12931  case value_t::number_float:
12932  case value_t::binary:
12933  case value_t::discarded:
12934  default:
12935  {
12936  m_it.primitive_iterator += i;
12937  break;
12938  }
12939  }
12940 
12941  return *this;
12942  }
12943 
12949  {
12950  return operator+=(-i);
12951  }
12952 
12958  {
12959  auto result = *this;
12960  result += i;
12961  return result;
12962  }
12963 
12969  {
12970  auto result = it;
12971  result += i;
12972  return result;
12973  }
12974 
12980  {
12981  auto result = *this;
12982  result -= i;
12983  return result;
12984  }
12985 
12991  {
12992  JSON_ASSERT(m_object != nullptr);
12993 
12994  switch (m_object->m_type)
12995  {
12996  case value_t::object:
12997  JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
12998 
12999  case value_t::array:
13000  return m_it.array_iterator - other.m_it.array_iterator;
13001 
13002  case value_t::null:
13003  case value_t::string:
13004  case value_t::boolean:
13007  case value_t::number_float:
13008  case value_t::binary:
13009  case value_t::discarded:
13010  default:
13012  }
13013  }
13014 
13020  {
13021  JSON_ASSERT(m_object != nullptr);
13022 
13023  switch (m_object->m_type)
13024  {
13025  case value_t::object:
13026  JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
13027 
13028  case value_t::array:
13029  return *std::next(m_it.array_iterator, n);
13030 
13031  case value_t::null:
13032  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13033 
13034  case value_t::string:
13035  case value_t::boolean:
13038  case value_t::number_float:
13039  case value_t::binary:
13040  case value_t::discarded:
13041  default:
13042  {
13044  {
13045  return *m_object;
13046  }
13047 
13048  JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
13049  }
13050  }
13051  }
13052 
13057  const typename object_t::key_type& key() const
13058  {
13059  JSON_ASSERT(m_object != nullptr);
13060 
13061  if (JSON_HEDLEY_LIKELY(m_object->is_object()))
13062  {
13063  return m_it.object_iterator->first;
13064  }
13065 
13066  JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
13067  }
13068 
13074  {
13075  return operator*();
13076  }
13077 
13080  pointer m_object = nullptr;
13083 };
13084 } // namespace detail
13085 } // namespace nlohmann
13086 
13087 // #include <nlohmann/detail/iterators/iteration_proxy.hpp>
13088 
13089 // #include <nlohmann/detail/iterators/json_reverse_iterator.hpp>
13090 
13091 
13092 #include <cstddef> // ptrdiff_t
13093 #include <iterator> // reverse_iterator
13094 #include <utility> // declval
13095 
13096 namespace nlohmann
13097 {
13098 namespace detail
13099 {
13101 // reverse_iterator //
13103 
13122 template<typename Base>
13123 class json_reverse_iterator : public std::reverse_iterator<Base>
13124 {
13125  public:
13126  using difference_type = std::ptrdiff_t;
13128  using base_iterator = std::reverse_iterator<Base>;
13130  using reference = typename Base::reference;
13131 
13133  explicit json_reverse_iterator(const typename base_iterator::iterator_type& it) noexcept
13134  : base_iterator(it) {}
13135 
13137  explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
13138 
13140  json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
13141  {
13142  return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
13143  }
13144 
13147  {
13148  return static_cast<json_reverse_iterator&>(base_iterator::operator++());
13149  }
13150 
13152  json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
13153  {
13154  return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
13155  }
13156 
13159  {
13160  return static_cast<json_reverse_iterator&>(base_iterator::operator--());
13161  }
13162 
13165  {
13166  return static_cast<json_reverse_iterator&>(base_iterator::operator+=(i));
13167  }
13168 
13171  {
13172  return static_cast<json_reverse_iterator>(base_iterator::operator+(i));
13173  }
13174 
13177  {
13178  return static_cast<json_reverse_iterator>(base_iterator::operator-(i));
13179  }
13180 
13183  {
13184  return base_iterator(*this) - base_iterator(other);
13185  }
13186 
13189  {
13190  return *(this->operator+(n));
13191  }
13192 
13194  auto key() const -> decltype(std::declval<Base>().key())
13195  {
13196  auto it = --this->base();
13197  return it.key();
13198  }
13199 
13202  {
13203  auto it = --this->base();
13204  return it.operator * ();
13205  }
13206 };
13207 } // namespace detail
13208 } // namespace nlohmann
13209 
13210 // #include <nlohmann/detail/iterators/primitive_iterator.hpp>
13211 
13212 // #include <nlohmann/detail/json_pointer.hpp>
13213 
13214 
13215 #include <algorithm> // all_of
13216 #include <cctype> // isdigit
13217 #include <cerrno> // errno, ERANGE
13218 #include <cstdlib> // strtoull
13219 #include <limits> // max
13220 #include <numeric> // accumulate
13221 #include <string> // string
13222 #include <utility> // move
13223 #include <vector> // vector
13224 
13225 // #include <nlohmann/detail/exceptions.hpp>
13226 
13227 // #include <nlohmann/detail/macro_scope.hpp>
13228 
13229 // #include <nlohmann/detail/string_concat.hpp>
13230 
13231 // #include <nlohmann/detail/string_escape.hpp>
13232 
13233 // #include <nlohmann/detail/value_t.hpp>
13234 
13235 
13236 namespace nlohmann
13237 {
13238 
13241 template<typename RefStringType>
13243 {
13244  // allow basic_json to access private members
13246  friend class basic_json;
13247 
13248  template<typename>
13249  friend class json_pointer;
13250 
13251  template<typename T>
13252  struct string_t_helper
13253  {
13254  using type = T;
13255  };
13256 
13258  struct string_t_helper<NLOHMANN_BASIC_JSON_TPL>
13259  {
13260  using type = StringType;
13261  };
13262 
13263  public:
13264  // for backwards compatibility accept BasicJsonType
13265  using string_t = typename string_t_helper<RefStringType>::type;
13266 
13269  explicit json_pointer(const string_t& s = "")
13270  : reference_tokens(split(s))
13271  {}
13272 
13276  {
13277  return std::accumulate(reference_tokens.begin(), reference_tokens.end(),
13278  string_t{},
13279  [](const string_t& a, const string_t& b)
13280  {
13281  return detail::concat(a, '/', detail::escape(b));
13282  });
13283  }
13284 
13287  operator string_t() const
13288  {
13289  return to_string();
13290  }
13291 
13295  {
13296  reference_tokens.insert(reference_tokens.end(),
13297  ptr.reference_tokens.begin(),
13298  ptr.reference_tokens.end());
13299  return *this;
13300  }
13301 
13305  {
13306  push_back(std::move(token));
13307  return *this;
13308  }
13309 
13312  json_pointer& operator/=(std::size_t array_idx)
13313  {
13314  return *this /= std::to_string(array_idx);
13315  }
13316 
13320  const json_pointer& rhs)
13321  {
13322  return json_pointer(lhs) /= rhs;
13323  }
13324 
13327  friend json_pointer operator/(const json_pointer& lhs, string_t token) // NOLINT(performance-unnecessary-value-param)
13328  {
13329  return json_pointer(lhs) /= std::move(token);
13330  }
13331 
13334  friend json_pointer operator/(const json_pointer& lhs, std::size_t array_idx)
13335  {
13336  return json_pointer(lhs) /= array_idx;
13337  }
13338 
13342  {
13343  if (empty())
13344  {
13345  return *this;
13346  }
13347 
13348  json_pointer res = *this;
13349  res.pop_back();
13350  return res;
13351  }
13352 
13355  void pop_back()
13356  {
13357  if (JSON_HEDLEY_UNLIKELY(empty()))
13358  {
13359  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13360  }
13361 
13362  reference_tokens.pop_back();
13363  }
13364 
13367  const string_t& back() const
13368  {
13369  if (JSON_HEDLEY_UNLIKELY(empty()))
13370  {
13371  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13372  }
13373 
13374  return reference_tokens.back();
13375  }
13376 
13379  void push_back(const string_t& token)
13380  {
13381  reference_tokens.push_back(token);
13382  }
13383 
13386  void push_back(string_t&& token)
13387  {
13388  reference_tokens.push_back(std::move(token));
13389  }
13390 
13393  bool empty() const noexcept
13394  {
13395  return reference_tokens.empty();
13396  }
13397 
13398  private:
13409  template<typename BasicJsonType>
13410  static typename BasicJsonType::size_type array_index(const string_t& s)
13411  {
13412  using size_type = typename BasicJsonType::size_type;
13413 
13414  // error condition (cf. RFC 6901, Sect. 4)
13415  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && s[0] == '0'))
13416  {
13417  JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
13418  }
13419 
13420  // error condition (cf. RFC 6901, Sect. 4)
13421  if (JSON_HEDLEY_UNLIKELY(s.size() > 1 && !(s[0] >= '1' && s[0] <= '9')))
13422  {
13423  JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
13424  }
13425 
13426  const char* p = s.c_str();
13427  char* p_end = nullptr;
13428  errno = 0; // strtoull doesn't reset errno
13429  unsigned long long res = std::strtoull(p, &p_end, 10); // NOLINT(runtime/int)
13430  if (p == p_end // invalid input or empty string
13431  || errno == ERANGE // out of range
13432  || JSON_HEDLEY_UNLIKELY(static_cast<std::size_t>(p_end - p) != s.size())) // incomplete read
13433  {
13434  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr));
13435  }
13436 
13437  // only triggered on special platforms (like 32bit), see also
13438  // https://github.com/nlohmann/json/pull/2203
13439  if (res >= static_cast<unsigned long long>((std::numeric_limits<size_type>::max)())) // NOLINT(runtime/int)
13440  {
13441  JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE
13442  }
13443 
13444  return static_cast<size_type>(res);
13445  }
13446 
13448  json_pointer top() const
13449  {
13450  if (JSON_HEDLEY_UNLIKELY(empty()))
13451  {
13452  JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
13453  }
13454 
13455  json_pointer result = *this;
13456  result.reference_tokens = {reference_tokens[0]};
13457  return result;
13458  }
13459 
13460  private:
13469  template<typename BasicJsonType>
13470  BasicJsonType& get_and_create(BasicJsonType& j) const
13471  {
13472  auto* result = &j;
13473 
13474  // in case no reference tokens exist, return a reference to the JSON value
13475  // j which will be overwritten by a primitive value
13476  for (const auto& reference_token : reference_tokens)
13477  {
13478  switch (result->type())
13479  {
13480  case detail::value_t::null:
13481  {
13482  if (reference_token == "0")
13483  {
13484  // start a new array if reference token is 0
13485  result = &result->operator[](0);
13486  }
13487  else
13488  {
13489  // start a new object otherwise
13490  result = &result->operator[](reference_token);
13491  }
13492  break;
13493  }
13494 
13496  {
13497  // create an entry in the object
13498  result = &result->operator[](reference_token);
13499  break;
13500  }
13501 
13503  {
13504  // create an entry in the array
13505  result = &result->operator[](array_index<BasicJsonType>(reference_token));
13506  break;
13507  }
13508 
13509  /*
13510  The following code is only reached if there exists a reference
13511  token _and_ the current value is primitive. In this case, we have
13512  an error situation, because primitive values may only occur as
13513  single value; that is, with an empty list of reference tokens.
13514  */
13522  default:
13523  JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
13524  }
13525  }
13526 
13527  return *result;
13528  }
13529 
13549  template<typename BasicJsonType>
13550  BasicJsonType& get_unchecked(BasicJsonType* ptr) const
13551  {
13552  for (const auto& reference_token : reference_tokens)
13553  {
13554  // convert null values to arrays or objects before continuing
13555  if (ptr->is_null())
13556  {
13557  // check if reference token is a number
13558  const bool nums =
13559  std::all_of(reference_token.begin(), reference_token.end(),
13560  [](const unsigned char x)
13561  {
13562  return std::isdigit(x);
13563  });
13564 
13565  // change value to array for numbers or "-" or to object otherwise
13566  *ptr = (nums || reference_token == "-")
13569  }
13570 
13571  switch (ptr->type())
13572  {
13574  {
13575  // use unchecked object access
13576  ptr = &ptr->operator[](reference_token);
13577  break;
13578  }
13579 
13581  {
13582  if (reference_token == "-")
13583  {
13584  // explicitly treat "-" as index beyond the end
13585  ptr = &ptr->operator[](ptr->m_value.array->size());
13586  }
13587  else
13588  {
13589  // convert array index to number; unchecked access
13590  ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
13591  }
13592  break;
13593  }
13594 
13595  case detail::value_t::null:
13603  default:
13604  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13605  }
13606  }
13607 
13608  return *ptr;
13609  }
13610 
13617  template<typename BasicJsonType>
13618  BasicJsonType& get_checked(BasicJsonType* ptr) const
13619  {
13620  for (const auto& reference_token : reference_tokens)
13621  {
13622  switch (ptr->type())
13623  {
13625  {
13626  // note: at performs range check
13627  ptr = &ptr->at(reference_token);
13628  break;
13629  }
13630 
13632  {
13633  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13634  {
13635  // "-" always fails the range check
13637  "array index '-' (", std::to_string(ptr->m_value.array->size()),
13638  ") is out of range"), ptr));
13639  }
13640 
13641  // note: at performs range check
13642  ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
13643  break;
13644  }
13645 
13646  case detail::value_t::null:
13654  default:
13655  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13656  }
13657  }
13658 
13659  return *ptr;
13660  }
13661 
13675  template<typename BasicJsonType>
13676  const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
13677  {
13678  for (const auto& reference_token : reference_tokens)
13679  {
13680  switch (ptr->type())
13681  {
13683  {
13684  // use unchecked object access
13685  ptr = &ptr->operator[](reference_token);
13686  break;
13687  }
13688 
13690  {
13691  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13692  {
13693  // "-" cannot be used for const access
13694  JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_value.array->size()), ") is out of range"), ptr));
13695  }
13696 
13697  // use unchecked array access
13698  ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
13699  break;
13700  }
13701 
13702  case detail::value_t::null:
13710  default:
13711  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13712  }
13713  }
13714 
13715  return *ptr;
13716  }
13717 
13724  template<typename BasicJsonType>
13725  const BasicJsonType& get_checked(const BasicJsonType* ptr) const
13726  {
13727  for (const auto& reference_token : reference_tokens)
13728  {
13729  switch (ptr->type())
13730  {
13732  {
13733  // note: at performs range check
13734  ptr = &ptr->at(reference_token);
13735  break;
13736  }
13737 
13739  {
13740  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13741  {
13742  // "-" always fails the range check
13744  "array index '-' (", std::to_string(ptr->m_value.array->size()),
13745  ") is out of range"), ptr));
13746  }
13747 
13748  // note: at performs range check
13749  ptr = &ptr->at(array_index<BasicJsonType>(reference_token));
13750  break;
13751  }
13752 
13753  case detail::value_t::null:
13761  default:
13762  JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), ptr));
13763  }
13764  }
13765 
13766  return *ptr;
13767  }
13768 
13773  template<typename BasicJsonType>
13774  bool contains(const BasicJsonType* ptr) const
13775  {
13776  for (const auto& reference_token : reference_tokens)
13777  {
13778  switch (ptr->type())
13779  {
13781  {
13782  if (!ptr->contains(reference_token))
13783  {
13784  // we did not find the key in the object
13785  return false;
13786  }
13787 
13788  ptr = &ptr->operator[](reference_token);
13789  break;
13790  }
13791 
13793  {
13794  if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
13795  {
13796  // "-" always fails the range check
13797  return false;
13798  }
13799  if (JSON_HEDLEY_UNLIKELY(reference_token.size() == 1 && !("0" <= reference_token && reference_token <= "9")))
13800  {
13801  // invalid char
13802  return false;
13803  }
13804  if (JSON_HEDLEY_UNLIKELY(reference_token.size() > 1))
13805  {
13806  if (JSON_HEDLEY_UNLIKELY(!('1' <= reference_token[0] && reference_token[0] <= '9')))
13807  {
13808  // first char should be between '1' and '9'
13809  return false;
13810  }
13811  for (std::size_t i = 1; i < reference_token.size(); i++)
13812  {
13813  if (JSON_HEDLEY_UNLIKELY(!('0' <= reference_token[i] && reference_token[i] <= '9')))
13814  {
13815  // other char should be between '0' and '9'
13816  return false;
13817  }
13818  }
13819  }
13820 
13821  const auto idx = array_index<BasicJsonType>(reference_token);
13822  if (idx >= ptr->size())
13823  {
13824  // index out of range
13825  return false;
13826  }
13827 
13828  ptr = &ptr->operator[](idx);
13829  break;
13830  }
13831 
13832  case detail::value_t::null:
13840  default:
13841  {
13842  // we do not expect primitive values if there is still a
13843  // reference token to process
13844  return false;
13845  }
13846  }
13847  }
13848 
13849  // no reference token left means we found a primitive value
13850  return true;
13851  }
13852 
13862  static std::vector<string_t> split(const string_t& reference_string)
13863  {
13864  std::vector<string_t> result;
13865 
13866  // special case: empty reference string -> no reference tokens
13867  if (reference_string.empty())
13868  {
13869  return result;
13870  }
13871 
13872  // check if nonempty reference string begins with slash
13873  if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
13874  {
13875  JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
13876  }
13877 
13878  // extract the reference tokens:
13879  // - slash: position of the last read slash (or end of string)
13880  // - start: position after the previous slash
13881  for (
13882  // search for the first slash after the first character
13883  std::size_t slash = reference_string.find_first_of('/', 1),
13884  // set the beginning of the first reference token
13885  start = 1;
13886  // we can stop if start == 0 (if slash == string_t::npos)
13887  start != 0;
13888  // set the beginning of the next reference token
13889  // (will eventually be 0 if slash == string_t::npos)
13890  start = (slash == string_t::npos) ? 0 : slash + 1,
13891  // find next slash
13892  slash = reference_string.find_first_of('/', start))
13893  {
13894  // use the text between the beginning of the reference token
13895  // (start) and the last slash (slash).
13896  auto reference_token = reference_string.substr(start, slash - start);
13897 
13898  // check reference tokens are properly escaped
13899  for (std::size_t pos = reference_token.find_first_of('~');
13900  pos != string_t::npos;
13901  pos = reference_token.find_first_of('~', pos + 1))
13902  {
13903  JSON_ASSERT(reference_token[pos] == '~');
13904 
13905  // ~ must be followed by 0 or 1
13906  if (JSON_HEDLEY_UNLIKELY(pos == reference_token.size() - 1 ||
13907  (reference_token[pos + 1] != '0' &&
13908  reference_token[pos + 1] != '1')))
13909  {
13910  JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
13911  }
13912  }
13913 
13914  // finally, store the reference token
13915  detail::unescape(reference_token);
13916  result.push_back(reference_token);
13917  }
13918 
13919  return result;
13920  }
13921 
13922  private:
13930  template<typename BasicJsonType>
13931  static void flatten(const string_t& reference_string,
13932  const BasicJsonType& value,
13933  BasicJsonType& result)
13934  {
13935  switch (value.type())
13936  {
13938  {
13939  if (value.m_value.array->empty())
13940  {
13941  // flatten empty array as null
13942  result[reference_string] = nullptr;
13943  }
13944  else
13945  {
13946  // iterate array and use index as reference string
13947  for (std::size_t i = 0; i < value.m_value.array->size(); ++i)
13948  {
13949  flatten(detail::concat(reference_string, '/', std::to_string(i)),
13950  value.m_value.array->operator[](i), result);
13951  }
13952  }
13953  break;
13954  }
13955 
13957  {
13958  if (value.m_value.object->empty())
13959  {
13960  // flatten empty object as null
13961  result[reference_string] = nullptr;
13962  }
13963  else
13964  {
13965  // iterate object and use keys as reference string
13966  for (const auto& element : *value.m_value.object)
13967  {
13968  flatten(detail::concat(reference_string, '/', detail::escape(element.first)), element.second, result);
13969  }
13970  }
13971  break;
13972  }
13973 
13974  case detail::value_t::null:
13982  default:
13983  {
13984  // add primitive value with its reference string
13985  result[reference_string] = value;
13986  break;
13987  }
13988  }
13989  }
13990 
14001  template<typename BasicJsonType>
14002  static BasicJsonType
14003  unflatten(const BasicJsonType& value)
14004  {
14005  if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
14006  {
14007  JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
14008  }
14009 
14010  BasicJsonType result;
14011 
14012  // iterate the JSON object values
14013  for (const auto& element : *value.m_value.object)
14014  {
14015  if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
14016  {
14017  JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
14018  }
14019 
14020  // assign value to reference pointed to by JSON pointer; Note that if
14021  // the JSON pointer is "" (i.e., points to the whole value), function
14022  // get_and_create returns a reference to result itself. An assignment
14023  // will then create a primitive value.
14024  json_pointer(element.first).get_and_create(result) = element.second;
14025  }
14026 
14027  return result;
14028  }
14029 
14030  // can't use conversion operator because of ambiguity
14031  json_pointer<string_t> convert() const&
14032  {
14033  json_pointer<string_t> result;
14034  result.reference_tokens = reference_tokens;
14035  return result;
14036  }
14037 
14038  json_pointer<string_t> convert()&&
14039  {
14040  json_pointer<string_t> result;
14041  result.reference_tokens = std::move(reference_tokens);
14042  return result;
14043  }
14044 
14056  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14057  // NOLINTNEXTLINE(readability-redundant-declaration)
14058  friend bool operator==(json_pointer<RefStringTypeLhs> const& lhs,
14059  json_pointer<RefStringTypeRhs> const& rhs) noexcept;
14060 
14072  template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14073  // NOLINTNEXTLINE(readability-redundant-declaration)
14074  friend bool operator!=(json_pointer<RefStringTypeLhs> const& lhs,
14075  json_pointer<RefStringTypeRhs> const& rhs) noexcept;
14076 
14078  std::vector<string_t> reference_tokens;
14079 };
14080 
14081 // functions cannot be defined inside class due to ODR violations
14082 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14084  json_pointer<RefStringTypeRhs> const& rhs) noexcept
14085 {
14086  return lhs.reference_tokens == rhs.reference_tokens;
14087 }
14088 
14089 template<typename RefStringTypeLhs, typename RefStringTypeRhs>
14091  json_pointer<RefStringTypeRhs> const& rhs) noexcept
14092 {
14093  return !(lhs == rhs);
14094 }
14095 } // namespace nlohmann
14096 
14097 // #include <nlohmann/detail/json_ref.hpp>
14098 
14099 
14100 #include <initializer_list>
14101 #include <utility>
14102 
14103 // #include <nlohmann/detail/meta/type_traits.hpp>
14104 
14105 
14106 namespace nlohmann
14107 {
14108 namespace detail
14109 {
14110 template<typename BasicJsonType>
14112 {
14113  public:
14114  using value_type = BasicJsonType;
14115 
14117  : owned_value(std::move(value))
14118  {}
14119 
14120  json_ref(const value_type& value)
14121  : value_ref(&value)
14122  {}
14123 
14124  json_ref(std::initializer_list<json_ref> init)
14125  : owned_value(init)
14126  {}
14127 
14128  template <
14129  class... Args,
14130  enable_if_t<std::is_constructible<value_type, Args...>::value, int> = 0 >
14131  json_ref(Args && ... args)
14132  : owned_value(std::forward<Args>(args)...)
14133  {}
14134 
14135  // class should be movable only
14136  json_ref(json_ref&&) noexcept = default;
14137  json_ref(const json_ref&) = delete;
14138  json_ref& operator=(const json_ref&) = delete;
14139  json_ref& operator=(json_ref&&) = delete;
14140  ~json_ref() = default;
14141 
14143  {
14144  if (value_ref == nullptr)
14145  {
14146  return std::move(owned_value);
14147  }
14148  return *value_ref;
14149  }
14150 
14151  value_type const& operator*() const
14152  {
14153  return value_ref ? *value_ref : owned_value;
14154  }
14155 
14156  value_type const* operator->() const
14157  {
14158  return &** this;
14159  }
14160 
14161  private:
14162  mutable value_type owned_value = nullptr;
14163  value_type const* value_ref = nullptr;
14164 };
14165 } // namespace detail
14166 } // namespace nlohmann
14167 
14168 // #include <nlohmann/detail/macro_scope.hpp>
14169 
14170 // #include <nlohmann/detail/string_concat.hpp>
14171 
14172 // #include <nlohmann/detail/string_escape.hpp>
14173 
14174 // #include <nlohmann/detail/meta/cpp_future.hpp>
14175 
14176 // #include <nlohmann/detail/meta/type_traits.hpp>
14177 
14178 // #include <nlohmann/detail/output/binary_writer.hpp>
14179 
14180 
14181 #include <algorithm> // reverse
14182 #include <array> // array
14183 #include <map> // map
14184 #include <cmath> // isnan, isinf
14185 #include <cstdint> // uint8_t, uint16_t, uint32_t, uint64_t
14186 #include <cstring> // memcpy
14187 #include <limits> // numeric_limits
14188 #include <string> // string
14189 #include <utility> // move
14190 #include <vector> // vector
14191 
14192 // #include <nlohmann/detail/input/binary_reader.hpp>
14193 
14194 // #include <nlohmann/detail/macro_scope.hpp>
14195 
14196 // #include <nlohmann/detail/output/output_adapters.hpp>
14197 
14198 
14199 #include <algorithm> // copy
14200 #include <cstddef> // size_t
14201 #include <iterator> // back_inserter
14202 #include <memory> // shared_ptr, make_shared
14203 #include <string> // basic_string
14204 #include <vector> // vector
14205 
14206 #ifndef JSON_NO_IO
14207  #include <ios> // streamsize
14208  #include <ostream> // basic_ostream
14209 #endif // JSON_NO_IO
14210 
14211 // #include <nlohmann/detail/macro_scope.hpp>
14212 
14213 
14214 namespace nlohmann
14215 {
14216 namespace detail
14217 {
14219 template<typename CharType> struct output_adapter_protocol
14220 {
14221  virtual void write_character(CharType c) = 0;
14222  virtual void write_characters(const CharType* s, std::size_t length) = 0;
14223  virtual ~output_adapter_protocol() = default;
14224 
14228  output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
14229  output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
14230 };
14231 
14233 template<typename CharType>
14234 using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
14235 
14237 template<typename CharType, typename AllocatorType = std::allocator<CharType>>
14239 {
14240  public:
14241  explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
14242  : v(vec)
14243  {}
14244 
14245  void write_character(CharType c) override
14246  {
14247  v.push_back(c);
14248  }
14249 
14251  void write_characters(const CharType* s, std::size_t length) override
14252  {
14253  v.insert(v.end(), s, s + length);
14254  }
14255 
14256  private:
14257  std::vector<CharType, AllocatorType>& v;
14258 };
14259 
14260 #ifndef JSON_NO_IO
14262 template<typename CharType>
14264 {
14265  public:
14266  explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
14267  : stream(s)
14268  {}
14269 
14270  void write_character(CharType c) override
14271  {
14272  stream.put(c);
14273  }
14274 
14276  void write_characters(const CharType* s, std::size_t length) override
14277  {
14278  stream.write(s, static_cast<std::streamsize>(length));
14279  }
14280 
14281  private:
14282  std::basic_ostream<CharType>& stream;
14283 };
14284 #endif // JSON_NO_IO
14285 
14287 template<typename CharType, typename StringType = std::basic_string<CharType>>
14289 {
14290  public:
14291  explicit output_string_adapter(StringType& s) noexcept
14292  : str(s)
14293  {}
14294 
14295  void write_character(CharType c) override
14296  {
14297  str.push_back(c);
14298  }
14299 
14301  void write_characters(const CharType* s, std::size_t length) override
14302  {
14303  str.append(s, length);
14304  }
14305 
14306  private:
14307  StringType& str;
14308 };
14309 
14310 template<typename CharType, typename StringType = std::basic_string<CharType>>
14312 {
14313  public:
14314  template<typename AllocatorType = std::allocator<CharType>>
14315  output_adapter(std::vector<CharType, AllocatorType>& vec)
14316  : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
14317 
14318 #ifndef JSON_NO_IO
14319  output_adapter(std::basic_ostream<CharType>& s)
14320  : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
14321 #endif // JSON_NO_IO
14322 
14323  output_adapter(StringType& s)
14324  : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
14325 
14327  {
14328  return oa;
14329  }
14330 
14331  private:
14332  output_adapter_t<CharType> oa = nullptr;
14333 };
14334 } // namespace detail
14335 } // namespace nlohmann
14336 
14337 // #include <nlohmann/detail/string_concat.hpp>
14338 
14339 
14340 namespace nlohmann
14341 {
14342 namespace detail
14343 {
14345 // binary writer //
14347 
14351 template<typename BasicJsonType, typename CharType>
14353 {
14354  using string_t = typename BasicJsonType::string_t;
14355  using binary_t = typename BasicJsonType::binary_t;
14356  using number_float_t = typename BasicJsonType::number_float_t;
14357 
14358  public:
14364  explicit binary_writer(output_adapter_t<CharType> adapter) : oa(std::move(adapter))
14365  {
14366  JSON_ASSERT(oa);
14367  }
14368 
14373  void write_bson(const BasicJsonType& j)
14374  {
14375  switch (j.type())
14376  {
14377  case value_t::object:
14378  {
14379  write_bson_object(*j.m_value.object);
14380  break;
14381  }
14382 
14383  case value_t::null:
14384  case value_t::array:
14385  case value_t::string:
14386  case value_t::boolean:
14387  case value_t::number_integer:
14388  case value_t::number_unsigned:
14389  case value_t::number_float:
14390  case value_t::binary:
14391  case value_t::discarded:
14392  default:
14393  {
14394  JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
14395  }
14396  }
14397  }
14398 
14402  void write_cbor(const BasicJsonType& j)
14403  {
14404  switch (j.type())
14405  {
14406  case value_t::null:
14407  {
14408  oa->write_character(to_char_type(0xF6));
14409  break;
14410  }
14411 
14412  case value_t::boolean:
14413  {
14414  oa->write_character(j.m_value.boolean
14415  ? to_char_type(0xF5)
14416  : to_char_type(0xF4));
14417  break;
14418  }
14419 
14420  case value_t::number_integer:
14421  {
14422  if (j.m_value.number_integer >= 0)
14423  {
14424  // CBOR does not differentiate between positive signed
14425  // integers and unsigned integers. Therefore, we used the
14426  // code from the value_t::number_unsigned case here.
14427  if (j.m_value.number_integer <= 0x17)
14428  {
14429  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14430  }
14431  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint8_t>::max)())
14432  {
14433  oa->write_character(to_char_type(0x18));
14434  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14435  }
14436  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)())
14437  {
14438  oa->write_character(to_char_type(0x19));
14439  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14440  }
14441  else if (j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)())
14442  {
14443  oa->write_character(to_char_type(0x1A));
14444  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14445  }
14446  else
14447  {
14448  oa->write_character(to_char_type(0x1B));
14449  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14450  }
14451  }
14452  else
14453  {
14454  // The conversions below encode the sign in the first
14455  // byte, and the value is converted to a positive number.
14456  const auto positive_number = -1 - j.m_value.number_integer;
14457  if (j.m_value.number_integer >= -24)
14458  {
14459  write_number(static_cast<std::uint8_t>(0x20 + positive_number));
14460  }
14461  else if (positive_number <= (std::numeric_limits<std::uint8_t>::max)())
14462  {
14463  oa->write_character(to_char_type(0x38));
14464  write_number(static_cast<std::uint8_t>(positive_number));
14465  }
14466  else if (positive_number <= (std::numeric_limits<std::uint16_t>::max)())
14467  {
14468  oa->write_character(to_char_type(0x39));
14469  write_number(static_cast<std::uint16_t>(positive_number));
14470  }
14471  else if (positive_number <= (std::numeric_limits<std::uint32_t>::max)())
14472  {
14473  oa->write_character(to_char_type(0x3A));
14474  write_number(static_cast<std::uint32_t>(positive_number));
14475  }
14476  else
14477  {
14478  oa->write_character(to_char_type(0x3B));
14479  write_number(static_cast<std::uint64_t>(positive_number));
14480  }
14481  }
14482  break;
14483  }
14484 
14485  case value_t::number_unsigned:
14486  {
14487  if (j.m_value.number_unsigned <= 0x17)
14488  {
14489  write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
14490  }
14491  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14492  {
14493  oa->write_character(to_char_type(0x18));
14494  write_number(static_cast<std::uint8_t>(j.m_value.number_unsigned));
14495  }
14496  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14497  {
14498  oa->write_character(to_char_type(0x19));
14499  write_number(static_cast<std::uint16_t>(j.m_value.number_unsigned));
14500  }
14501  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14502  {
14503  oa->write_character(to_char_type(0x1A));
14504  write_number(static_cast<std::uint32_t>(j.m_value.number_unsigned));
14505  }
14506  else
14507  {
14508  oa->write_character(to_char_type(0x1B));
14509  write_number(static_cast<std::uint64_t>(j.m_value.number_unsigned));
14510  }
14511  break;
14512  }
14513 
14514  case value_t::number_float:
14515  {
14516  if (std::isnan(j.m_value.number_float))
14517  {
14518  // NaN is 0xf97e00 in CBOR
14519  oa->write_character(to_char_type(0xF9));
14520  oa->write_character(to_char_type(0x7E));
14521  oa->write_character(to_char_type(0x00));
14522  }
14523  else if (std::isinf(j.m_value.number_float))
14524  {
14525  // Infinity is 0xf97c00, -Infinity is 0xf9fc00
14526  oa->write_character(to_char_type(0xf9));
14527  oa->write_character(j.m_value.number_float > 0 ? to_char_type(0x7C) : to_char_type(0xFC));
14528  oa->write_character(to_char_type(0x00));
14529  }
14530  else
14531  {
14532  write_compact_float(j.m_value.number_float, detail::input_format_t::cbor);
14533  }
14534  break;
14535  }
14536 
14537  case value_t::string:
14538  {
14539  // step 1: write control byte and the string length
14540  const auto N = j.m_value.string->size();
14541  if (N <= 0x17)
14542  {
14543  write_number(static_cast<std::uint8_t>(0x60 + N));
14544  }
14545  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14546  {
14547  oa->write_character(to_char_type(0x78));
14548  write_number(static_cast<std::uint8_t>(N));
14549  }
14550  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14551  {
14552  oa->write_character(to_char_type(0x79));
14553  write_number(static_cast<std::uint16_t>(N));
14554  }
14555  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14556  {
14557  oa->write_character(to_char_type(0x7A));
14558  write_number(static_cast<std::uint32_t>(N));
14559  }
14560  // LCOV_EXCL_START
14561  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14562  {
14563  oa->write_character(to_char_type(0x7B));
14564  write_number(static_cast<std::uint64_t>(N));
14565  }
14566  // LCOV_EXCL_STOP
14567 
14568  // step 2: write the string
14569  oa->write_characters(
14570  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14571  j.m_value.string->size());
14572  break;
14573  }
14574 
14575  case value_t::array:
14576  {
14577  // step 1: write control byte and the array size
14578  const auto N = j.m_value.array->size();
14579  if (N <= 0x17)
14580  {
14581  write_number(static_cast<std::uint8_t>(0x80 + N));
14582  }
14583  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14584  {
14585  oa->write_character(to_char_type(0x98));
14586  write_number(static_cast<std::uint8_t>(N));
14587  }
14588  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14589  {
14590  oa->write_character(to_char_type(0x99));
14591  write_number(static_cast<std::uint16_t>(N));
14592  }
14593  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14594  {
14595  oa->write_character(to_char_type(0x9A));
14596  write_number(static_cast<std::uint32_t>(N));
14597  }
14598  // LCOV_EXCL_START
14599  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14600  {
14601  oa->write_character(to_char_type(0x9B));
14602  write_number(static_cast<std::uint64_t>(N));
14603  }
14604  // LCOV_EXCL_STOP
14605 
14606  // step 2: write each element
14607  for (const auto& el : *j.m_value.array)
14608  {
14609  write_cbor(el);
14610  }
14611  break;
14612  }
14613 
14614  case value_t::binary:
14615  {
14616  if (j.m_value.binary->has_subtype())
14617  {
14618  if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint8_t>::max)())
14619  {
14620  write_number(static_cast<std::uint8_t>(0xd8));
14621  write_number(static_cast<std::uint8_t>(j.m_value.binary->subtype()));
14622  }
14623  else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint16_t>::max)())
14624  {
14625  write_number(static_cast<std::uint8_t>(0xd9));
14626  write_number(static_cast<std::uint16_t>(j.m_value.binary->subtype()));
14627  }
14628  else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint32_t>::max)())
14629  {
14630  write_number(static_cast<std::uint8_t>(0xda));
14631  write_number(static_cast<std::uint32_t>(j.m_value.binary->subtype()));
14632  }
14633  else if (j.m_value.binary->subtype() <= (std::numeric_limits<std::uint64_t>::max)())
14634  {
14635  write_number(static_cast<std::uint8_t>(0xdb));
14636  write_number(static_cast<std::uint64_t>(j.m_value.binary->subtype()));
14637  }
14638  }
14639 
14640  // step 1: write control byte and the binary array size
14641  const auto N = j.m_value.binary->size();
14642  if (N <= 0x17)
14643  {
14644  write_number(static_cast<std::uint8_t>(0x40 + N));
14645  }
14646  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14647  {
14648  oa->write_character(to_char_type(0x58));
14649  write_number(static_cast<std::uint8_t>(N));
14650  }
14651  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14652  {
14653  oa->write_character(to_char_type(0x59));
14654  write_number(static_cast<std::uint16_t>(N));
14655  }
14656  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14657  {
14658  oa->write_character(to_char_type(0x5A));
14659  write_number(static_cast<std::uint32_t>(N));
14660  }
14661  // LCOV_EXCL_START
14662  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14663  {
14664  oa->write_character(to_char_type(0x5B));
14665  write_number(static_cast<std::uint64_t>(N));
14666  }
14667  // LCOV_EXCL_STOP
14668 
14669  // step 2: write each element
14670  oa->write_characters(
14671  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
14672  N);
14673 
14674  break;
14675  }
14676 
14677  case value_t::object:
14678  {
14679  // step 1: write control byte and the object size
14680  const auto N = j.m_value.object->size();
14681  if (N <= 0x17)
14682  {
14683  write_number(static_cast<std::uint8_t>(0xA0 + N));
14684  }
14685  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14686  {
14687  oa->write_character(to_char_type(0xB8));
14688  write_number(static_cast<std::uint8_t>(N));
14689  }
14690  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14691  {
14692  oa->write_character(to_char_type(0xB9));
14693  write_number(static_cast<std::uint16_t>(N));
14694  }
14695  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14696  {
14697  oa->write_character(to_char_type(0xBA));
14698  write_number(static_cast<std::uint32_t>(N));
14699  }
14700  // LCOV_EXCL_START
14701  else if (N <= (std::numeric_limits<std::uint64_t>::max)())
14702  {
14703  oa->write_character(to_char_type(0xBB));
14704  write_number(static_cast<std::uint64_t>(N));
14705  }
14706  // LCOV_EXCL_STOP
14707 
14708  // step 2: write each element
14709  for (const auto& el : *j.m_value.object)
14710  {
14711  write_cbor(el.first);
14712  write_cbor(el.second);
14713  }
14714  break;
14715  }
14716 
14717  case value_t::discarded:
14718  default:
14719  break;
14720  }
14721  }
14722 
14726  void write_msgpack(const BasicJsonType& j)
14727  {
14728  switch (j.type())
14729  {
14730  case value_t::null: // nil
14731  {
14732  oa->write_character(to_char_type(0xC0));
14733  break;
14734  }
14735 
14736  case value_t::boolean: // true and false
14737  {
14738  oa->write_character(j.m_value.boolean
14739  ? to_char_type(0xC3)
14740  : to_char_type(0xC2));
14741  break;
14742  }
14743 
14744  case value_t::number_integer:
14745  {
14746  if (j.m_value.number_integer >= 0)
14747  {
14748  // MessagePack does not differentiate between positive
14749  // signed integers and unsigned integers. Therefore, we used
14750  // the code from the value_t::number_unsigned case here.
14751  if (j.m_value.number_unsigned < 128)
14752  {
14753  // positive fixnum
14754  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14755  }
14756  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14757  {
14758  // uint 8
14759  oa->write_character(to_char_type(0xCC));
14760  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14761  }
14762  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14763  {
14764  // uint 16
14765  oa->write_character(to_char_type(0xCD));
14766  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14767  }
14768  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14769  {
14770  // uint 32
14771  oa->write_character(to_char_type(0xCE));
14772  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14773  }
14774  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14775  {
14776  // uint 64
14777  oa->write_character(to_char_type(0xCF));
14778  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14779  }
14780  }
14781  else
14782  {
14783  if (j.m_value.number_integer >= -32)
14784  {
14785  // negative fixnum
14786  write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14787  }
14788  else if (j.m_value.number_integer >= (std::numeric_limits<std::int8_t>::min)() &&
14789  j.m_value.number_integer <= (std::numeric_limits<std::int8_t>::max)())
14790  {
14791  // int 8
14792  oa->write_character(to_char_type(0xD0));
14793  write_number(static_cast<std::int8_t>(j.m_value.number_integer));
14794  }
14795  else if (j.m_value.number_integer >= (std::numeric_limits<std::int16_t>::min)() &&
14796  j.m_value.number_integer <= (std::numeric_limits<std::int16_t>::max)())
14797  {
14798  // int 16
14799  oa->write_character(to_char_type(0xD1));
14800  write_number(static_cast<std::int16_t>(j.m_value.number_integer));
14801  }
14802  else if (j.m_value.number_integer >= (std::numeric_limits<std::int32_t>::min)() &&
14803  j.m_value.number_integer <= (std::numeric_limits<std::int32_t>::max)())
14804  {
14805  // int 32
14806  oa->write_character(to_char_type(0xD2));
14807  write_number(static_cast<std::int32_t>(j.m_value.number_integer));
14808  }
14809  else if (j.m_value.number_integer >= (std::numeric_limits<std::int64_t>::min)() &&
14810  j.m_value.number_integer <= (std::numeric_limits<std::int64_t>::max)())
14811  {
14812  // int 64
14813  oa->write_character(to_char_type(0xD3));
14814  write_number(static_cast<std::int64_t>(j.m_value.number_integer));
14815  }
14816  }
14817  break;
14818  }
14819 
14820  case value_t::number_unsigned:
14821  {
14822  if (j.m_value.number_unsigned < 128)
14823  {
14824  // positive fixnum
14825  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14826  }
14827  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint8_t>::max)())
14828  {
14829  // uint 8
14830  oa->write_character(to_char_type(0xCC));
14831  write_number(static_cast<std::uint8_t>(j.m_value.number_integer));
14832  }
14833  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint16_t>::max)())
14834  {
14835  // uint 16
14836  oa->write_character(to_char_type(0xCD));
14837  write_number(static_cast<std::uint16_t>(j.m_value.number_integer));
14838  }
14839  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint32_t>::max)())
14840  {
14841  // uint 32
14842  oa->write_character(to_char_type(0xCE));
14843  write_number(static_cast<std::uint32_t>(j.m_value.number_integer));
14844  }
14845  else if (j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
14846  {
14847  // uint 64
14848  oa->write_character(to_char_type(0xCF));
14849  write_number(static_cast<std::uint64_t>(j.m_value.number_integer));
14850  }
14851  break;
14852  }
14853 
14854  case value_t::number_float:
14855  {
14856  write_compact_float(j.m_value.number_float, detail::input_format_t::msgpack);
14857  break;
14858  }
14859 
14860  case value_t::string:
14861  {
14862  // step 1: write control byte and the string length
14863  const auto N = j.m_value.string->size();
14864  if (N <= 31)
14865  {
14866  // fixstr
14867  write_number(static_cast<std::uint8_t>(0xA0 | N));
14868  }
14869  else if (N <= (std::numeric_limits<std::uint8_t>::max)())
14870  {
14871  // str 8
14872  oa->write_character(to_char_type(0xD9));
14873  write_number(static_cast<std::uint8_t>(N));
14874  }
14875  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14876  {
14877  // str 16
14878  oa->write_character(to_char_type(0xDA));
14879  write_number(static_cast<std::uint16_t>(N));
14880  }
14881  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14882  {
14883  // str 32
14884  oa->write_character(to_char_type(0xDB));
14885  write_number(static_cast<std::uint32_t>(N));
14886  }
14887 
14888  // step 2: write the string
14889  oa->write_characters(
14890  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
14891  j.m_value.string->size());
14892  break;
14893  }
14894 
14895  case value_t::array:
14896  {
14897  // step 1: write control byte and the array size
14898  const auto N = j.m_value.array->size();
14899  if (N <= 15)
14900  {
14901  // fixarray
14902  write_number(static_cast<std::uint8_t>(0x90 | N));
14903  }
14904  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14905  {
14906  // array 16
14907  oa->write_character(to_char_type(0xDC));
14908  write_number(static_cast<std::uint16_t>(N));
14909  }
14910  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14911  {
14912  // array 32
14913  oa->write_character(to_char_type(0xDD));
14914  write_number(static_cast<std::uint32_t>(N));
14915  }
14916 
14917  // step 2: write each element
14918  for (const auto& el : *j.m_value.array)
14919  {
14920  write_msgpack(el);
14921  }
14922  break;
14923  }
14924 
14925  case value_t::binary:
14926  {
14927  // step 0: determine if the binary type has a set subtype to
14928  // determine whether or not to use the ext or fixext types
14929  const bool use_ext = j.m_value.binary->has_subtype();
14930 
14931  // step 1: write control byte and the byte string length
14932  const auto N = j.m_value.binary->size();
14934  {
14935  std::uint8_t output_type{};
14936  bool fixed = true;
14937  if (use_ext)
14938  {
14939  switch (N)
14940  {
14941  case 1:
14942  output_type = 0xD4; // fixext 1
14943  break;
14944  case 2:
14945  output_type = 0xD5; // fixext 2
14946  break;
14947  case 4:
14948  output_type = 0xD6; // fixext 4
14949  break;
14950  case 8:
14951  output_type = 0xD7; // fixext 8
14952  break;
14953  case 16:
14954  output_type = 0xD8; // fixext 16
14955  break;
14956  default:
14957  output_type = 0xC7; // ext 8
14958  fixed = false;
14959  break;
14960  }
14961 
14962  }
14963  else
14964  {
14965  output_type = 0xC4; // bin 8
14966  fixed = false;
14967  }
14968 
14969  oa->write_character(to_char_type(output_type));
14970  if (!fixed)
14971  {
14972  write_number(static_cast<std::uint8_t>(N));
14973  }
14974  }
14975  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
14976  {
14977  std::uint8_t output_type = use_ext
14978  ? 0xC8 // ext 16
14979  : 0xC5; // bin 16
14980 
14981  oa->write_character(to_char_type(output_type));
14982  write_number(static_cast<std::uint16_t>(N));
14983  }
14984  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
14985  {
14986  std::uint8_t output_type = use_ext
14987  ? 0xC9 // ext 32
14988  : 0xC6; // bin 32
14989 
14990  oa->write_character(to_char_type(output_type));
14991  write_number(static_cast<std::uint32_t>(N));
14992  }
14993 
14994  // step 1.5: if this is an ext type, write the subtype
14995  if (use_ext)
14996  {
14997  write_number(static_cast<std::int8_t>(j.m_value.binary->subtype()));
14998  }
14999 
15000  // step 2: write the byte string
15001  oa->write_characters(
15002  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
15003  N);
15004 
15005  break;
15006  }
15007 
15008  case value_t::object:
15009  {
15010  // step 1: write control byte and the object size
15011  const auto N = j.m_value.object->size();
15012  if (N <= 15)
15013  {
15014  // fixmap
15015  write_number(static_cast<std::uint8_t>(0x80 | (N & 0xF)));
15016  }
15017  else if (N <= (std::numeric_limits<std::uint16_t>::max)())
15018  {
15019  // map 16
15020  oa->write_character(to_char_type(0xDE));
15021  write_number(static_cast<std::uint16_t>(N));
15022  }
15023  else if (N <= (std::numeric_limits<std::uint32_t>::max)())
15024  {
15025  // map 32
15026  oa->write_character(to_char_type(0xDF));
15027  write_number(static_cast<std::uint32_t>(N));
15028  }
15029 
15030  // step 2: write each element
15031  for (const auto& el : *j.m_value.object)
15032  {
15033  write_msgpack(el.first);
15034  write_msgpack(el.second);
15035  }
15036  break;
15037  }
15038 
15039  case value_t::discarded:
15040  default:
15041  break;
15042  }
15043  }
15044 
15052  void write_ubjson(const BasicJsonType& j, const bool use_count,
15053  const bool use_type, const bool add_prefix = true,
15054  const bool use_bjdata = false)
15055  {
15056  switch (j.type())
15057  {
15058  case value_t::null:
15059  {
15060  if (add_prefix)
15061  {
15062  oa->write_character(to_char_type('Z'));
15063  }
15064  break;
15065  }
15066 
15067  case value_t::boolean:
15068  {
15069  if (add_prefix)
15070  {
15071  oa->write_character(j.m_value.boolean
15072  ? to_char_type('T')
15073  : to_char_type('F'));
15074  }
15075  break;
15076  }
15077 
15078  case value_t::number_integer:
15079  {
15080  write_number_with_ubjson_prefix(j.m_value.number_integer, add_prefix, use_bjdata);
15081  break;
15082  }
15083 
15084  case value_t::number_unsigned:
15085  {
15086  write_number_with_ubjson_prefix(j.m_value.number_unsigned, add_prefix, use_bjdata);
15087  break;
15088  }
15089 
15090  case value_t::number_float:
15091  {
15092  write_number_with_ubjson_prefix(j.m_value.number_float, add_prefix, use_bjdata);
15093  break;
15094  }
15095 
15096  case value_t::string:
15097  {
15098  if (add_prefix)
15099  {
15100  oa->write_character(to_char_type('S'));
15101  }
15102  write_number_with_ubjson_prefix(j.m_value.string->size(), true, use_bjdata);
15103  oa->write_characters(
15104  reinterpret_cast<const CharType*>(j.m_value.string->c_str()),
15105  j.m_value.string->size());
15106  break;
15107  }
15108 
15109  case value_t::array:
15110  {
15111  if (add_prefix)
15112  {
15113  oa->write_character(to_char_type('['));
15114  }
15115 
15116  bool prefix_required = true;
15117  if (use_type && !j.m_value.array->empty())
15118  {
15119  JSON_ASSERT(use_count);
15120  const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15121  const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
15122  [this, first_prefix, use_bjdata](const BasicJsonType & v)
15123  {
15124  return ubjson_prefix(v, use_bjdata) == first_prefix;
15125  });
15126 
15127  std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
15128 
15129  if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15130  {
15131  prefix_required = false;
15132  oa->write_character(to_char_type('$'));
15133  oa->write_character(first_prefix);
15134  }
15135  }
15136 
15137  if (use_count)
15138  {
15139  oa->write_character(to_char_type('#'));
15140  write_number_with_ubjson_prefix(j.m_value.array->size(), true, use_bjdata);
15141  }
15142 
15143  for (const auto& el : *j.m_value.array)
15144  {
15145  write_ubjson(el, use_count, use_type, prefix_required, use_bjdata);
15146  }
15147 
15148  if (!use_count)
15149  {
15150  oa->write_character(to_char_type(']'));
15151  }
15152 
15153  break;
15154  }
15155 
15156  case value_t::binary:
15157  {
15158  if (add_prefix)
15159  {
15160  oa->write_character(to_char_type('['));
15161  }
15162 
15163  if (use_type && !j.m_value.binary->empty())
15164  {
15165  JSON_ASSERT(use_count);
15166  oa->write_character(to_char_type('$'));
15167  oa->write_character('U');
15168  }
15169 
15170  if (use_count)
15171  {
15172  oa->write_character(to_char_type('#'));
15173  write_number_with_ubjson_prefix(j.m_value.binary->size(), true, use_bjdata);
15174  }
15175 
15176  if (use_type)
15177  {
15178  oa->write_characters(
15179  reinterpret_cast<const CharType*>(j.m_value.binary->data()),
15180  j.m_value.binary->size());
15181  }
15182  else
15183  {
15184  for (size_t i = 0; i < j.m_value.binary->size(); ++i)
15185  {
15186  oa->write_character(to_char_type('U'));
15187  oa->write_character(j.m_value.binary->data()[i]);
15188  }
15189  }
15190 
15191  if (!use_count)
15192  {
15193  oa->write_character(to_char_type(']'));
15194  }
15195 
15196  break;
15197  }
15198 
15199  case value_t::object:
15200  {
15201  if (use_bjdata && j.m_value.object->size() == 3 && j.m_value.object->find("_ArrayType_") != j.m_value.object->end() && j.m_value.object->find("_ArraySize_") != j.m_value.object->end() && j.m_value.object->find("_ArrayData_") != j.m_value.object->end())
15202  {
15203  if (!write_bjdata_ndarray(*j.m_value.object, use_count, use_type)) // decode bjdata ndarray in the JData format (https://github.com/NeuroJSON/jdata)
15204  {
15205  break;
15206  }
15207  }
15208 
15209  if (add_prefix)
15210  {
15211  oa->write_character(to_char_type('{'));
15212  }
15213 
15214  bool prefix_required = true;
15215  if (use_type && !j.m_value.object->empty())
15216  {
15217  JSON_ASSERT(use_count);
15218  const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
15219  const bool same_prefix = std::all_of(j.begin(), j.end(),
15220  [this, first_prefix, use_bjdata](const BasicJsonType & v)
15221  {
15222  return ubjson_prefix(v, use_bjdata) == first_prefix;
15223  });
15224 
15225  std::vector<CharType> bjdx = {'[', '{', 'S', 'H', 'T', 'F', 'N', 'Z'}; // excluded markers in bjdata optimized type
15226 
15227  if (same_prefix && !(use_bjdata && std::find(bjdx.begin(), bjdx.end(), first_prefix) != bjdx.end()))
15228  {
15229  prefix_required = false;
15230  oa->write_character(to_char_type('$'));
15231  oa->write_character(first_prefix);
15232  }
15233  }
15234 
15235  if (use_count)
15236  {
15237  oa->write_character(to_char_type('#'));
15238  write_number_with_ubjson_prefix(j.m_value.object->size(), true, use_bjdata);
15239  }
15240 
15241  for (const auto& el : *j.m_value.object)
15242  {
15243  write_number_with_ubjson_prefix(el.first.size(), true, use_bjdata);
15244  oa->write_characters(
15245  reinterpret_cast<const CharType*>(el.first.c_str()),
15246  el.first.size());
15247  write_ubjson(el.second, use_count, use_type, prefix_required, use_bjdata);
15248  }
15249 
15250  if (!use_count)
15251  {
15252  oa->write_character(to_char_type('}'));
15253  }
15254 
15255  break;
15256  }
15257 
15258  case value_t::discarded:
15259  default:
15260  break;
15261  }
15262  }
15263 
15264  private:
15266  // BSON //
15268 
15273  static std::size_t calc_bson_entry_header_size(const string_t& name, const BasicJsonType& j)
15274  {
15275  const auto it = name.find(static_cast<typename string_t::value_type>(0));
15276  if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
15277  {
15278  JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
15279  static_cast<void>(j);
15280  }
15281 
15282  return /*id*/ 1ul + name.size() + /*zero-terminator*/1u;
15283  }
15284 
15288  void write_bson_entry_header(const string_t& name,
15289  const std::uint8_t element_type)
15290  {
15291  oa->write_character(to_char_type(element_type)); // boolean
15292  oa->write_characters(
15293  reinterpret_cast<const CharType*>(name.c_str()),
15294  name.size() + 1u);
15295  }
15296 
15300  void write_bson_boolean(const string_t& name,
15301  const bool value)
15302  {
15303  write_bson_entry_header(name, 0x08);
15304  oa->write_character(value ? to_char_type(0x01) : to_char_type(0x00));
15305  }
15306 
15310  void write_bson_double(const string_t& name,
15311  const double value)
15312  {
15313  write_bson_entry_header(name, 0x01);
15314  write_number<double>(value, true);
15315  }
15316 
15320  static std::size_t calc_bson_string_size(const string_t& value)
15321  {
15322  return sizeof(std::int32_t) + value.size() + 1ul;
15323  }
15324 
15328  void write_bson_string(const string_t& name,
15329  const string_t& value)
15330  {
15331  write_bson_entry_header(name, 0x02);
15332 
15333  write_number<std::int32_t>(static_cast<std::int32_t>(value.size() + 1ul), true);
15334  oa->write_characters(
15335  reinterpret_cast<const CharType*>(value.c_str()),
15336  value.size() + 1);
15337  }
15338 
15342  void write_bson_null(const string_t& name)
15343  {
15344  write_bson_entry_header(name, 0x0A);
15345  }
15346 
15350  static std::size_t calc_bson_integer_size(const std::int64_t value)
15351  {
15353  ? sizeof(std::int32_t)
15354  : sizeof(std::int64_t);
15355  }
15356 
15360  void write_bson_integer(const string_t& name,
15361  const std::int64_t value)
15362  {
15364  {
15365  write_bson_entry_header(name, 0x10); // int32
15366  write_number<std::int32_t>(static_cast<std::int32_t>(value), true);
15367  }
15368  else
15369  {
15370  write_bson_entry_header(name, 0x12); // int64
15371  write_number<std::int64_t>(static_cast<std::int64_t>(value), true);
15372  }
15373  }
15374 
15378  static constexpr std::size_t calc_bson_unsigned_size(const std::uint64_t value) noexcept
15379  {
15380  return (value <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15381  ? sizeof(std::int32_t)
15382  : sizeof(std::int64_t);
15383  }
15384 
15388  void write_bson_unsigned(const string_t& name,
15389  const BasicJsonType& j)
15390  {
15391  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15392  {
15393  write_bson_entry_header(name, 0x10 /* int32 */);
15394  write_number<std::int32_t>(static_cast<std::int32_t>(j.m_value.number_unsigned), true);
15395  }
15396  else if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15397  {
15398  write_bson_entry_header(name, 0x12 /* int64 */);
15399  write_number<std::int64_t>(static_cast<std::int64_t>(j.m_value.number_unsigned), true);
15400  }
15401  else
15402  {
15403  JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_value.number_unsigned), " cannot be represented by BSON as it does not fit int64"), &j));
15404  }
15405  }
15406 
15410  void write_bson_object_entry(const string_t& name,
15411  const typename BasicJsonType::object_t& value)
15412  {
15413  write_bson_entry_header(name, 0x03); // object
15414  write_bson_object(value);
15415  }
15416 
15420  static std::size_t calc_bson_array_size(const typename BasicJsonType::array_t& value)
15421  {
15422  std::size_t array_index = 0ul;
15423 
15424  const std::size_t embedded_document_size = std::accumulate(std::begin(value), std::end(value), static_cast<std::size_t>(0), [&array_index](std::size_t result, const typename BasicJsonType::array_t::value_type & el)
15425  {
15426  return result + calc_bson_element_size(std::to_string(array_index++), el);
15427  });
15428 
15429  return sizeof(std::int32_t) + embedded_document_size + 1ul;
15430  }
15431 
15435  static std::size_t calc_bson_binary_size(const typename BasicJsonType::binary_t& value)
15436  {
15437  return sizeof(std::int32_t) + value.size() + 1ul;
15438  }
15439 
15443  void write_bson_array(const string_t& name,
15444  const typename BasicJsonType::array_t& value)
15445  {
15446  write_bson_entry_header(name, 0x04); // array
15447  write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_array_size(value)), true);
15448 
15449  std::size_t array_index = 0ul;
15450 
15451  for (const auto& el : value)
15452  {
15453  write_bson_element(std::to_string(array_index++), el);
15454  }
15455 
15456  oa->write_character(to_char_type(0x00));
15457  }
15458 
15462  void write_bson_binary(const string_t& name,
15463  const binary_t& value)
15464  {
15465  write_bson_entry_header(name, 0x05);
15466 
15467  write_number<std::int32_t>(static_cast<std::int32_t>(value.size()), true);
15468  write_number(value.has_subtype() ? static_cast<std::uint8_t>(value.subtype()) : static_cast<std::uint8_t>(0x00));
15469 
15470  oa->write_characters(reinterpret_cast<const CharType*>(value.data()), value.size());
15471  }
15472 
15477  static std::size_t calc_bson_element_size(const string_t& name,
15478  const BasicJsonType& j)
15479  {
15480  const auto header_size = calc_bson_entry_header_size(name, j);
15481  switch (j.type())
15482  {
15483  case value_t::object:
15484  return header_size + calc_bson_object_size(*j.m_value.object);
15485 
15486  case value_t::array:
15487  return header_size + calc_bson_array_size(*j.m_value.array);
15488 
15489  case value_t::binary:
15490  return header_size + calc_bson_binary_size(*j.m_value.binary);
15491 
15492  case value_t::boolean:
15493  return header_size + 1ul;
15494 
15495  case value_t::number_float:
15496  return header_size + 8ul;
15497 
15498  case value_t::number_integer:
15499  return header_size + calc_bson_integer_size(j.m_value.number_integer);
15500 
15501  case value_t::number_unsigned:
15502  return header_size + calc_bson_unsigned_size(j.m_value.number_unsigned);
15503 
15504  case value_t::string:
15505  return header_size + calc_bson_string_size(*j.m_value.string);
15506 
15507  case value_t::null:
15508  return header_size + 0ul;
15509 
15510  // LCOV_EXCL_START
15511  case value_t::discarded:
15512  default:
15513  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
15514  return 0ul;
15515  // LCOV_EXCL_STOP
15516  }
15517  }
15518 
15525  void write_bson_element(const string_t& name,
15526  const BasicJsonType& j)
15527  {
15528  switch (j.type())
15529  {
15530  case value_t::object:
15531  return write_bson_object_entry(name, *j.m_value.object);
15532 
15533  case value_t::array:
15534  return write_bson_array(name, *j.m_value.array);
15535 
15536  case value_t::binary:
15537  return write_bson_binary(name, *j.m_value.binary);
15538 
15539  case value_t::boolean:
15540  return write_bson_boolean(name, j.m_value.boolean);
15541 
15542  case value_t::number_float:
15543  return write_bson_double(name, j.m_value.number_float);
15544 
15545  case value_t::number_integer:
15546  return write_bson_integer(name, j.m_value.number_integer);
15547 
15548  case value_t::number_unsigned:
15549  return write_bson_unsigned(name, j);
15550 
15551  case value_t::string:
15552  return write_bson_string(name, *j.m_value.string);
15553 
15554  case value_t::null:
15555  return write_bson_null(name);
15556 
15557  // LCOV_EXCL_START
15558  case value_t::discarded:
15559  default:
15560  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert)
15561  return;
15562  // LCOV_EXCL_STOP
15563  }
15564  }
15565 
15572  static std::size_t calc_bson_object_size(const typename BasicJsonType::object_t& value)
15573  {
15574  std::size_t document_size = std::accumulate(value.begin(), value.end(), static_cast<std::size_t>(0),
15575  [](size_t result, const typename BasicJsonType::object_t::value_type & el)
15576  {
15577  return result += calc_bson_element_size(el.first, el.second);
15578  });
15579 
15580  return sizeof(std::int32_t) + document_size + 1ul;
15581  }
15582 
15587  void write_bson_object(const typename BasicJsonType::object_t& value)
15588  {
15589  write_number<std::int32_t>(static_cast<std::int32_t>(calc_bson_object_size(value)), true);
15590 
15591  for (const auto& el : value)
15592  {
15593  write_bson_element(el.first, el.second);
15594  }
15595 
15596  oa->write_character(to_char_type(0x00));
15597  }
15598 
15600  // CBOR //
15602 
15603  static constexpr CharType get_cbor_float_prefix(float /*unused*/)
15604  {
15605  return to_char_type(0xFA); // Single-Precision Float
15606  }
15607 
15608  static constexpr CharType get_cbor_float_prefix(double /*unused*/)
15609  {
15610  return to_char_type(0xFB); // Double-Precision Float
15611  }
15612 
15614  // MsgPack //
15616 
15617  static constexpr CharType get_msgpack_float_prefix(float /*unused*/)
15618  {
15619  return to_char_type(0xCA); // float 32
15620  }
15621 
15622  static constexpr CharType get_msgpack_float_prefix(double /*unused*/)
15623  {
15624  return to_char_type(0xCB); // float 64
15625  }
15626 
15628  // UBJSON //
15630 
15631  // UBJSON: write number (floating point)
15632  template<typename NumberType, typename std::enable_if<
15633  std::is_floating_point<NumberType>::value, int>::type = 0>
15634  void write_number_with_ubjson_prefix(const NumberType n,
15635  const bool add_prefix,
15636  const bool use_bjdata)
15637  {
15638  if (add_prefix)
15639  {
15640  oa->write_character(get_ubjson_float_prefix(n));
15641  }
15642  write_number(n, use_bjdata);
15643  }
15644 
15645  // UBJSON: write number (unsigned integer)
15646  template<typename NumberType, typename std::enable_if<
15647  std::is_unsigned<NumberType>::value, int>::type = 0>
15648  void write_number_with_ubjson_prefix(const NumberType n,
15649  const bool add_prefix,
15650  const bool use_bjdata)
15651  {
15652  if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15653  {
15654  if (add_prefix)
15655  {
15656  oa->write_character(to_char_type('i')); // int8
15657  }
15658  write_number(static_cast<std::uint8_t>(n), use_bjdata);
15659  }
15660  else if (n <= (std::numeric_limits<std::uint8_t>::max)())
15661  {
15662  if (add_prefix)
15663  {
15664  oa->write_character(to_char_type('U')); // uint8
15665  }
15666  write_number(static_cast<std::uint8_t>(n), use_bjdata);
15667  }
15668  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15669  {
15670  if (add_prefix)
15671  {
15672  oa->write_character(to_char_type('I')); // int16
15673  }
15674  write_number(static_cast<std::int16_t>(n), use_bjdata);
15675  }
15676  else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint16_t>::max)()))
15677  {
15678  if (add_prefix)
15679  {
15680  oa->write_character(to_char_type('u')); // uint16 - bjdata only
15681  }
15682  write_number(static_cast<std::uint16_t>(n), use_bjdata);
15683  }
15684  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15685  {
15686  if (add_prefix)
15687  {
15688  oa->write_character(to_char_type('l')); // int32
15689  }
15690  write_number(static_cast<std::int32_t>(n), use_bjdata);
15691  }
15692  else if (use_bjdata && n <= static_cast<uint64_t>((std::numeric_limits<uint32_t>::max)()))
15693  {
15694  if (add_prefix)
15695  {
15696  oa->write_character(to_char_type('m')); // uint32 - bjdata only
15697  }
15698  write_number(static_cast<std::uint32_t>(n), use_bjdata);
15699  }
15700  else if (n <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15701  {
15702  if (add_prefix)
15703  {
15704  oa->write_character(to_char_type('L')); // int64
15705  }
15706  write_number(static_cast<std::int64_t>(n), use_bjdata);
15707  }
15708  else if (use_bjdata && n <= (std::numeric_limits<uint64_t>::max)())
15709  {
15710  if (add_prefix)
15711  {
15712  oa->write_character(to_char_type('M')); // uint64 - bjdata only
15713  }
15714  write_number(static_cast<std::uint64_t>(n), use_bjdata);
15715  }
15716  else
15717  {
15718  if (add_prefix)
15719  {
15720  oa->write_character(to_char_type('H')); // high-precision number
15721  }
15722 
15723  const auto number = BasicJsonType(n).dump();
15724  write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
15725  for (std::size_t i = 0; i < number.size(); ++i)
15726  {
15727  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15728  }
15729  }
15730  }
15731 
15732  // UBJSON: write number (signed integer)
15733  template < typename NumberType, typename std::enable_if <
15734  std::is_signed<NumberType>::value&&
15735  !std::is_floating_point<NumberType>::value, int >::type = 0 >
15736  void write_number_with_ubjson_prefix(const NumberType n,
15737  const bool add_prefix,
15738  const bool use_bjdata)
15739  {
15741  {
15742  if (add_prefix)
15743  {
15744  oa->write_character(to_char_type('i')); // int8
15745  }
15746  write_number(static_cast<std::int8_t>(n), use_bjdata);
15747  }
15748  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)()))
15749  {
15750  if (add_prefix)
15751  {
15752  oa->write_character(to_char_type('U')); // uint8
15753  }
15754  write_number(static_cast<std::uint8_t>(n), use_bjdata);
15755  }
15757  {
15758  if (add_prefix)
15759  {
15760  oa->write_character(to_char_type('I')); // int16
15761  }
15762  write_number(static_cast<std::int16_t>(n), use_bjdata);
15763  }
15764  else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint16_t>::max)())))
15765  {
15766  if (add_prefix)
15767  {
15768  oa->write_character(to_char_type('u')); // uint16 - bjdata only
15769  }
15770  write_number(static_cast<uint16_t>(n), use_bjdata);
15771  }
15773  {
15774  if (add_prefix)
15775  {
15776  oa->write_character(to_char_type('l')); // int32
15777  }
15778  write_number(static_cast<std::int32_t>(n), use_bjdata);
15779  }
15780  else if (use_bjdata && (static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::min)()) <= n && n <= static_cast<std::int64_t>((std::numeric_limits<std::uint32_t>::max)())))
15781  {
15782  if (add_prefix)
15783  {
15784  oa->write_character(to_char_type('m')); // uint32 - bjdata only
15785  }
15786  write_number(static_cast<uint32_t>(n), use_bjdata);
15787  }
15789  {
15790  if (add_prefix)
15791  {
15792  oa->write_character(to_char_type('L')); // int64
15793  }
15794  write_number(static_cast<std::int64_t>(n), use_bjdata);
15795  }
15796  // LCOV_EXCL_START
15797  else
15798  {
15799  if (add_prefix)
15800  {
15801  oa->write_character(to_char_type('H')); // high-precision number
15802  }
15803 
15804  const auto number = BasicJsonType(n).dump();
15805  write_number_with_ubjson_prefix(number.size(), true, use_bjdata);
15806  for (std::size_t i = 0; i < number.size(); ++i)
15807  {
15808  oa->write_character(to_char_type(static_cast<std::uint8_t>(number[i])));
15809  }
15810  }
15811  // LCOV_EXCL_STOP
15812  }
15813 
15817  CharType ubjson_prefix(const BasicJsonType& j, const bool use_bjdata) const noexcept
15818  {
15819  switch (j.type())
15820  {
15821  case value_t::null:
15822  return 'Z';
15823 
15824  case value_t::boolean:
15825  return j.m_value.boolean ? 'T' : 'F';
15826 
15827  case value_t::number_integer:
15828  {
15829  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)())
15830  {
15831  return 'i';
15832  }
15833  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)())
15834  {
15835  return 'U';
15836  }
15837  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)())
15838  {
15839  return 'I';
15840  }
15841  if (use_bjdata && ((std::numeric_limits<std::uint16_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint16_t>::max)()))
15842  {
15843  return 'u';
15844  }
15845  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)())
15846  {
15847  return 'l';
15848  }
15849  if (use_bjdata && ((std::numeric_limits<std::uint32_t>::min)() <= j.m_value.number_integer && j.m_value.number_integer <= (std::numeric_limits<std::uint32_t>::max)()))
15850  {
15851  return 'm';
15852  }
15853  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)())
15854  {
15855  return 'L';
15856  }
15857  // anything else is treated as high-precision number
15858  return 'H'; // LCOV_EXCL_LINE
15859  }
15860 
15861  case value_t::number_unsigned:
15862  {
15863  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int8_t>::max)()))
15864  {
15865  return 'i';
15866  }
15867  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint8_t>::max)()))
15868  {
15869  return 'U';
15870  }
15871  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int16_t>::max)()))
15872  {
15873  return 'I';
15874  }
15875  if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint16_t>::max)()))
15876  {
15877  return 'u';
15878  }
15879  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int32_t>::max)()))
15880  {
15881  return 'l';
15882  }
15883  if (use_bjdata && j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::uint32_t>::max)()))
15884  {
15885  return 'm';
15886  }
15887  if (j.m_value.number_unsigned <= static_cast<std::uint64_t>((std::numeric_limits<std::int64_t>::max)()))
15888  {
15889  return 'L';
15890  }
15891  if (use_bjdata && j.m_value.number_unsigned <= (std::numeric_limits<std::uint64_t>::max)())
15892  {
15893  return 'M';
15894  }
15895  // anything else is treated as high-precision number
15896  return 'H'; // LCOV_EXCL_LINE
15897  }
15898 
15899  case value_t::number_float:
15900  return get_ubjson_float_prefix(j.m_value.number_float);
15901 
15902  case value_t::string:
15903  return 'S';
15904 
15905  case value_t::array: // fallthrough
15906  case value_t::binary:
15907  return '[';
15908 
15909  case value_t::object:
15910  return '{';
15911 
15912  case value_t::discarded:
15913  default: // discarded values
15914  return 'N';
15915  }
15916  }
15917 
15918  static constexpr CharType get_ubjson_float_prefix(float /*unused*/)
15919  {
15920  return 'd'; // float 32
15921  }
15922 
15923  static constexpr CharType get_ubjson_float_prefix(double /*unused*/)
15924  {
15925  return 'D'; // float 64
15926  }
15927 
15931  bool write_bjdata_ndarray(const typename BasicJsonType::object_t& value, const bool use_count, const bool use_type)
15932  {
15933  std::map<string_t, CharType> bjdtype = {{"uint8", 'U'}, {"int8", 'i'}, {"uint16", 'u'}, {"int16", 'I'},
15934  {"uint32", 'm'}, {"int32", 'l'}, {"uint64", 'M'}, {"int64", 'L'}, {"single", 'd'}, {"double", 'D'}, {"char", 'C'}
15935  };
15936 
15937  string_t key = "_ArrayType_";
15938  auto it = bjdtype.find(static_cast<string_t>(value.at(key)));
15939  if (it == bjdtype.end())
15940  {
15941  return true;
15942  }
15943  CharType dtype = it->second;
15944 
15945  key = "_ArraySize_";
15946  std::size_t len = (value.at(key).empty() ? 0 : 1);
15947  for (const auto& el : value.at(key))
15948  {
15949  len *= static_cast<std::size_t>(el.m_value.number_unsigned);
15950  }
15951 
15952  key = "_ArrayData_";
15953  if (value.at(key).size() != len)
15954  {
15955  return true;
15956  }
15957 
15958  oa->write_character('[');
15959  oa->write_character('$');
15960  oa->write_character(dtype);
15961  oa->write_character('#');
15962 
15963  key = "_ArraySize_";
15964  write_ubjson(value.at(key), use_count, use_type, true, true);
15965 
15966  key = "_ArrayData_";
15967  if (dtype == 'U' || dtype == 'C')
15968  {
15969  for (const auto& el : value.at(key))
15970  {
15971  write_number(static_cast<std::uint8_t>(el.m_value.number_unsigned), true);
15972  }
15973  }
15974  else if (dtype == 'i')
15975  {
15976  for (const auto& el : value.at(key))
15977  {
15978  write_number(static_cast<std::int8_t>(el.m_value.number_integer), true);
15979  }
15980  }
15981  else if (dtype == 'u')
15982  {
15983  for (const auto& el : value.at(key))
15984  {
15985  write_number(static_cast<std::uint16_t>(el.m_value.number_unsigned), true);
15986  }
15987  }
15988  else if (dtype == 'I')
15989  {
15990  for (const auto& el : value.at(key))
15991  {
15992  write_number(static_cast<std::int16_t>(el.m_value.number_integer), true);
15993  }
15994  }
15995  else if (dtype == 'm')
15996  {
15997  for (const auto& el : value.at(key))
15998  {
15999  write_number(static_cast<std::uint32_t>(el.m_value.number_unsigned), true);
16000  }
16001  }
16002  else if (dtype == 'l')
16003  {
16004  for (const auto& el : value.at(key))
16005  {
16006  write_number(static_cast<std::int32_t>(el.m_value.number_integer), true);
16007  }
16008  }
16009  else if (dtype == 'M')
16010  {
16011  for (const auto& el : value.at(key))
16012  {
16013  write_number(static_cast<std::uint64_t>(el.m_value.number_unsigned), true);
16014  }
16015  }
16016  else if (dtype == 'L')
16017  {
16018  for (const auto& el : value.at(key))
16019  {
16020  write_number(static_cast<std::int64_t>(el.m_value.number_integer), true);
16021  }
16022  }
16023  else if (dtype == 'd')
16024  {
16025  for (const auto& el : value.at(key))
16026  {
16027  write_number(static_cast<float>(el.m_value.number_float), true);
16028  }
16029  }
16030  else if (dtype == 'D')
16031  {
16032  for (const auto& el : value.at(key))
16033  {
16034  write_number(static_cast<double>(el.m_value.number_float), true);
16035  }
16036  }
16037  return false;
16038  }
16039 
16041  // Utility functions //
16043 
16044  /*
16045  @brief write a number to output input
16046  @param[in] n number of type @a NumberType
16047  @param[in] OutputIsLittleEndian Set to true if output data is
16048  required to be little endian
16049  @tparam NumberType the type of the number
16050 
16051  @note This function needs to respect the system's endianness, because bytes
16052  in CBOR, MessagePack, and UBJSON are stored in network order (big
16053  endian) and therefore need reordering on little endian systems.
16054  On the other hand, BSON and BJData use little endian and should reorder
16055  on big endian systems.
16056  */
16057  template<typename NumberType>
16058  void write_number(const NumberType n, const bool OutputIsLittleEndian = false)
16059  {
16060  // step 1: write number to array of length NumberType
16061  std::array<CharType, sizeof(NumberType)> vec{};
16062  std::memcpy(vec.data(), &n, sizeof(NumberType));
16063 
16064  // step 2: write array to output (with possible reordering)
16065  if (is_little_endian != OutputIsLittleEndian)
16066  {
16067  // reverse byte order prior to conversion if necessary
16068  std::reverse(vec.begin(), vec.end());
16069  }
16070 
16071  oa->write_characters(vec.data(), sizeof(NumberType));
16072  }
16073 
16074  void write_compact_float(const number_float_t n, detail::input_format_t format)
16075  {
16076 #ifdef __GNUC__
16077 #pragma GCC diagnostic push
16078 #pragma GCC diagnostic ignored "-Wfloat-equal"
16079 #endif
16080  if (static_cast<double>(n) >= static_cast<double>(std::numeric_limits<float>::lowest()) &&
16081  static_cast<double>(n) <= static_cast<double>((std::numeric_limits<float>::max)()) &&
16082  static_cast<double>(static_cast<float>(n)) == static_cast<double>(n))
16083  {
16084  oa->write_character(format == detail::input_format_t::cbor
16085  ? get_cbor_float_prefix(static_cast<float>(n))
16086  : get_msgpack_float_prefix(static_cast<float>(n)));
16087  write_number(static_cast<float>(n));
16088  }
16089  else
16090  {
16091  oa->write_character(format == detail::input_format_t::cbor
16092  ? get_cbor_float_prefix(n)
16093  : get_msgpack_float_prefix(n));
16094  write_number(n);
16095  }
16096 #ifdef __GNUC__
16097 #pragma GCC diagnostic pop
16098 #endif
16099  }
16100 
16101  public:
16102  // The following to_char_type functions are implement the conversion
16103  // between uint8_t and CharType. In case CharType is not unsigned,
16104  // such a conversion is required to allow values greater than 128.
16105  // See <https://github.com/nlohmann/json/issues/1286> for a discussion.
16106  template < typename C = CharType,
16107  enable_if_t < std::is_signed<C>::value && std::is_signed<char>::value > * = nullptr >
16108  static constexpr CharType to_char_type(std::uint8_t x) noexcept
16109  {
16110  return *reinterpret_cast<char*>(&x);
16111  }
16112 
16113  template < typename C = CharType,
16114  enable_if_t < std::is_signed<C>::value && std::is_unsigned<char>::value > * = nullptr >
16115  static CharType to_char_type(std::uint8_t x) noexcept
16116  {
16117  static_assert(sizeof(std::uint8_t) == sizeof(CharType), "size of CharType must be equal to std::uint8_t");
16118  static_assert(std::is_trivial<CharType>::value, "CharType must be trivial");
16119  CharType result;
16120  std::memcpy(&result, &x, sizeof(x));
16121  return result;
16122  }
16123 
16124  template<typename C = CharType,
16126  static constexpr CharType to_char_type(std::uint8_t x) noexcept
16127  {
16128  return x;
16129  }
16130 
16131  template < typename InputCharType, typename C = CharType,
16132  enable_if_t <
16133  std::is_signed<C>::value &&
16134  std::is_signed<char>::value &&
16136  > * = nullptr >
16137  static constexpr CharType to_char_type(InputCharType x) noexcept
16138  {
16139  return x;
16140  }
16141 
16142  private:
16144  const bool is_little_endian = little_endianness();
16145 
16147  output_adapter_t<CharType> oa = nullptr;
16148 };
16149 } // namespace detail
16150 } // namespace nlohmann
16151 
16152 // #include <nlohmann/detail/output/output_adapters.hpp>
16153 
16154 // #include <nlohmann/detail/output/serializer.hpp>
16155 
16156 
16157 #include <algorithm> // reverse, remove, fill, find, none_of
16158 #include <array> // array
16159 #include <clocale> // localeconv, lconv
16160 #include <cmath> // labs, isfinite, isnan, signbit
16161 #include <cstddef> // size_t, ptrdiff_t
16162 #include <cstdint> // uint8_t
16163 #include <cstdio> // snprintf
16164 #include <limits> // numeric_limits
16165 #include <string> // string, char_traits
16166 #include <iomanip> // setfill, setw
16167 #include <type_traits> // is_same
16168 #include <utility> // move
16169 
16170 // #include <nlohmann/detail/conversions/to_chars.hpp>
16171 
16172 
16173 #include <array> // array
16174 #include <cmath> // signbit, isfinite
16175 #include <cstdint> // intN_t, uintN_t
16176 #include <cstring> // memcpy, memmove
16177 #include <limits> // numeric_limits
16178 #include <type_traits> // conditional
16179 
16180 // #include <nlohmann/detail/macro_scope.hpp>
16181 
16182 
16183 namespace nlohmann
16184 {
16185 namespace detail
16186 {
16187 
16207 namespace dtoa_impl
16208 {
16209 
16210 template<typename Target, typename Source>
16211 Target reinterpret_bits(const Source source)
16212 {
16213  static_assert(sizeof(Target) == sizeof(Source), "size mismatch");
16214 
16215  Target target;
16216  std::memcpy(&target, &source, sizeof(Source));
16217  return target;
16218 }
16219 
16220 struct diyfp // f * 2^e
16221 {
16222  static constexpr int kPrecision = 64; // = q
16223 
16224  std::uint64_t f = 0;
16225  int e = 0;
16226 
16227  constexpr diyfp(std::uint64_t f_, int e_) noexcept : f(f_), e(e_) {}
16228 
16233  static diyfp sub(const diyfp& x, const diyfp& y) noexcept
16234  {
16235  JSON_ASSERT(x.e == y.e);
16236  JSON_ASSERT(x.f >= y.f);
16237 
16238  return {x.f - y.f, x.e};
16239  }
16240 
16245  static diyfp mul(const diyfp& x, const diyfp& y) noexcept
16246  {
16247  static_assert(kPrecision == 64, "internal error");
16248 
16249  // Computes:
16250  // f = round((x.f * y.f) / 2^q)
16251  // e = x.e + y.e + q
16252 
16253  // Emulate the 64-bit * 64-bit multiplication:
16254  //
16255  // p = u * v
16256  // = (u_lo + 2^32 u_hi) (v_lo + 2^32 v_hi)
16257  // = (u_lo v_lo ) + 2^32 ((u_lo v_hi ) + (u_hi v_lo )) + 2^64 (u_hi v_hi )
16258  // = (p0 ) + 2^32 ((p1 ) + (p2 )) + 2^64 (p3 )
16259  // = (p0_lo + 2^32 p0_hi) + 2^32 ((p1_lo + 2^32 p1_hi) + (p2_lo + 2^32 p2_hi)) + 2^64 (p3 )
16260  // = (p0_lo ) + 2^32 (p0_hi + p1_lo + p2_lo ) + 2^64 (p1_hi + p2_hi + p3)
16261  // = (p0_lo ) + 2^32 (Q ) + 2^64 (H )
16262  // = (p0_lo ) + 2^32 (Q_lo + 2^32 Q_hi ) + 2^64 (H )
16263  //
16264  // (Since Q might be larger than 2^32 - 1)
16265  //
16266  // = (p0_lo + 2^32 Q_lo) + 2^64 (Q_hi + H)
16267  //
16268  // (Q_hi + H does not overflow a 64-bit int)
16269  //
16270  // = p_lo + 2^64 p_hi
16271 
16272  const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
16273  const std::uint64_t u_hi = x.f >> 32u;
16274  const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
16275  const std::uint64_t v_hi = y.f >> 32u;
16276 
16277  const std::uint64_t p0 = u_lo * v_lo;
16278  const std::uint64_t p1 = u_lo * v_hi;
16279  const std::uint64_t p2 = u_hi * v_lo;
16280  const std::uint64_t p3 = u_hi * v_hi;
16281 
16282  const std::uint64_t p0_hi = p0 >> 32u;
16283  const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
16284  const std::uint64_t p1_hi = p1 >> 32u;
16285  const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
16286  const std::uint64_t p2_hi = p2 >> 32u;
16287 
16288  std::uint64_t Q = p0_hi + p1_lo + p2_lo;
16289 
16290  // The full product might now be computed as
16291  //
16292  // p_hi = p3 + p2_hi + p1_hi + (Q >> 32)
16293  // p_lo = p0_lo + (Q << 32)
16294  //
16295  // But in this particular case here, the full p_lo is not required.
16296  // Effectively we only need to add the highest bit in p_lo to p_hi (and
16297  // Q_hi + 1 does not overflow).
16298 
16299  Q += std::uint64_t{1} << (64u - 32u - 1u); // round, ties up
16300 
16301  const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
16302 
16303  return {h, x.e + y.e + 64};
16304  }
16305 
16310  static diyfp normalize(diyfp x) noexcept
16311  {
16312  JSON_ASSERT(x.f != 0);
16313 
16314  while ((x.f >> 63u) == 0)
16315  {
16316  x.f <<= 1u;
16317  x.e--;
16318  }
16319 
16320  return x;
16321  }
16322 
16327  static diyfp normalize_to(const diyfp& x, const int target_exponent) noexcept
16328  {
16329  const int delta = x.e - target_exponent;
16330 
16331  JSON_ASSERT(delta >= 0);
16332  JSON_ASSERT(((x.f << delta) >> delta) == x.f);
16333 
16334  return {x.f << delta, target_exponent};
16335  }
16336 };
16337 
16339 {
16343 };
16344 
16351 template<typename FloatType>
16353 {
16354  JSON_ASSERT(std::isfinite(value));
16355  JSON_ASSERT(value > 0);
16356 
16357  // Convert the IEEE representation into a diyfp.
16358  //
16359  // If v is denormal:
16360  // value = 0.F * 2^(1 - bias) = ( F) * 2^(1 - bias - (p-1))
16361  // If v is normalized:
16362  // value = 1.F * 2^(E - bias) = (2^(p-1) + F) * 2^(E - bias - (p-1))
16363 
16364  static_assert(std::numeric_limits<FloatType>::is_iec559,
16365  "internal error: dtoa_short requires an IEEE-754 floating-point implementation");
16366 
16367  constexpr int kPrecision = std::numeric_limits<FloatType>::digits; // = p (includes the hidden bit)
16368  constexpr int kBias = std::numeric_limits<FloatType>::max_exponent - 1 + (kPrecision - 1);
16369  constexpr int kMinExp = 1 - kBias;
16370  constexpr std::uint64_t kHiddenBit = std::uint64_t{1} << (kPrecision - 1); // = 2^(p-1)
16371 
16373 
16374  const auto bits = static_cast<std::uint64_t>(reinterpret_bits<bits_type>(value));
16375  const std::uint64_t E = bits >> (kPrecision - 1);
16376  const std::uint64_t F = bits & (kHiddenBit - 1);
16377 
16378  const bool is_denormal = E == 0;
16379  const diyfp v = is_denormal
16380  ? diyfp(F, kMinExp)
16381  : diyfp(F + kHiddenBit, static_cast<int>(E) - kBias);
16382 
16383  // Compute the boundaries m- and m+ of the floating-point value
16384  // v = f * 2^e.
16385  //
16386  // Determine v- and v+, the floating-point predecessor and successor if v,
16387  // respectively.
16388  //
16389  // v- = v - 2^e if f != 2^(p-1) or e == e_min (A)
16390  // = v - 2^(e-1) if f == 2^(p-1) and e > e_min (B)
16391  //
16392  // v+ = v + 2^e
16393  //
16394  // Let m- = (v- + v) / 2 and m+ = (v + v+) / 2. All real numbers _strictly_
16395  // between m- and m+ round to v, regardless of how the input rounding
16396  // algorithm breaks ties.
16397  //
16398  // ---+-------------+-------------+-------------+-------------+--- (A)
16399  // v- m- v m+ v+
16400  //
16401  // -----------------+------+------+-------------+-------------+--- (B)
16402  // v- m- v m+ v+
16403 
16404  const bool lower_boundary_is_closer = F == 0 && E > 1;
16405  const diyfp m_plus = diyfp(2 * v.f + 1, v.e - 1);
16406  const diyfp m_minus = lower_boundary_is_closer
16407  ? diyfp(4 * v.f - 1, v.e - 2) // (B)
16408  : diyfp(2 * v.f - 1, v.e - 1); // (A)
16409 
16410  // Determine the normalized w+ = m+.
16411  const diyfp w_plus = diyfp::normalize(m_plus);
16412 
16413  // Determine w- = m- such that e_(w-) = e_(w+).
16414  const diyfp w_minus = diyfp::normalize_to(m_minus, w_plus.e);
16415 
16416  return {diyfp::normalize(v), w_minus, w_plus};
16417 }
16418 
16419 // Given normalized diyfp w, Grisu needs to find a (normalized) cached
16420 // power-of-ten c, such that the exponent of the product c * w = f * 2^e lies
16421 // within a certain range [alpha, gamma] (Definition 3.2 from [1])
16422 //
16423 // alpha <= e = e_c + e_w + q <= gamma
16424 //
16425 // or
16426 //
16427 // f_c * f_w * 2^alpha <= f_c 2^(e_c) * f_w 2^(e_w) * 2^q
16428 // <= f_c * f_w * 2^gamma
16429 //
16430 // Since c and w are normalized, i.e. 2^(q-1) <= f < 2^q, this implies
16431 //
16432 // 2^(q-1) * 2^(q-1) * 2^alpha <= c * w * 2^q < 2^q * 2^q * 2^gamma
16433 //
16434 // or
16435 //
16436 // 2^(q - 2 + alpha) <= c * w < 2^(q + gamma)
16437 //
16438 // The choice of (alpha,gamma) determines the size of the table and the form of
16439 // the digit generation procedure. Using (alpha,gamma)=(-60,-32) works out well
16440 // in practice:
16441 //
16442 // The idea is to cut the number c * w = f * 2^e into two parts, which can be
16443 // processed independently: An integral part p1, and a fractional part p2:
16444 //
16445 // f * 2^e = ( (f div 2^-e) * 2^-e + (f mod 2^-e) ) * 2^e
16446 // = (f div 2^-e) + (f mod 2^-e) * 2^e
16447 // = p1 + p2 * 2^e
16448 //
16449 // The conversion of p1 into decimal form requires a series of divisions and
16450 // modulos by (a power of) 10. These operations are faster for 32-bit than for
16451 // 64-bit integers, so p1 should ideally fit into a 32-bit integer. This can be
16452 // achieved by choosing
16453 //
16454 // -e >= 32 or e <= -32 := gamma
16455 //
16456 // In order to convert the fractional part
16457 //
16458 // p2 * 2^e = p2 / 2^-e = d[-1] / 10^1 + d[-2] / 10^2 + ...
16459 //
16460 // into decimal form, the fraction is repeatedly multiplied by 10 and the digits
16461 // d[-i] are extracted in order:
16462 //
16463 // (10 * p2) div 2^-e = d[-1]
16464 // (10 * p2) mod 2^-e = d[-2] / 10^1 + ...
16465 //
16466 // The multiplication by 10 must not overflow. It is sufficient to choose
16467 //
16468 // 10 * p2 < 16 * p2 = 2^4 * p2 <= 2^64.
16469 //
16470 // Since p2 = f mod 2^-e < 2^-e,
16471 //
16472 // -e <= 60 or e >= -60 := alpha
16473 
16474 constexpr int kAlpha = -60;
16475 constexpr int kGamma = -32;
16476 
16477 struct cached_power // c = f * 2^e ~= 10^k
16478 {
16479  std::uint64_t f;
16480  int e;
16481  int k;
16482 };
16483 
16492 {
16493  // Now
16494  //
16495  // alpha <= e_c + e + q <= gamma (1)
16496  // ==> f_c * 2^alpha <= c * 2^e * 2^q
16497  //
16498  // and since the c's are normalized, 2^(q-1) <= f_c,
16499  //
16500  // ==> 2^(q - 1 + alpha) <= c * 2^(e + q)
16501  // ==> 2^(alpha - e - 1) <= c
16502  //
16503  // If c were an exact power of ten, i.e. c = 10^k, one may determine k as
16504  //
16505  // k = ceil( log_10( 2^(alpha - e - 1) ) )
16506  // = ceil( (alpha - e - 1) * log_10(2) )
16507  //
16508  // From the paper:
16509  // "In theory the result of the procedure could be wrong since c is rounded,
16510  // and the computation itself is approximated [...]. In practice, however,
16511  // this simple function is sufficient."
16512  //
16513  // For IEEE double precision floating-point numbers converted into
16514  // normalized diyfp's w = f * 2^e, with q = 64,
16515  //
16516  // e >= -1022 (min IEEE exponent)
16517  // -52 (p - 1)
16518  // -52 (p - 1, possibly normalize denormal IEEE numbers)
16519  // -11 (normalize the diyfp)
16520  // = -1137
16521  //
16522  // and
16523  //
16524  // e <= +1023 (max IEEE exponent)
16525  // -52 (p - 1)
16526  // -11 (normalize the diyfp)
16527  // = 960
16528  //
16529  // This binary exponent range [-1137,960] results in a decimal exponent
16530  // range [-307,324]. One does not need to store a cached power for each
16531  // k in this range. For each such k it suffices to find a cached power
16532  // such that the exponent of the product lies in [alpha,gamma].
16533  // This implies that the difference of the decimal exponents of adjacent
16534  // table entries must be less than or equal to
16535  //
16536  // floor( (gamma - alpha) * log_10(2) ) = 8.
16537  //
16538  // (A smaller distance gamma-alpha would require a larger table.)
16539 
16540  // NB:
16541  // Actually this function returns c, such that -60 <= e_c + e + 64 <= -34.
16542 
16543  constexpr int kCachedPowersMinDecExp = -300;
16544  constexpr int kCachedPowersDecStep = 8;
16545 
16546  static constexpr std::array<cached_power, 79> kCachedPowers =
16547  {
16548  {
16549  { 0xAB70FE17C79AC6CA, -1060, -300 },
16550  { 0xFF77B1FCBEBCDC4F, -1034, -292 },
16551  { 0xBE5691EF416BD60C, -1007, -284 },
16552  { 0x8DD01FAD907FFC3C, -980, -276 },
16553  { 0xD3515C2831559A83, -954, -268 },
16554  { 0x9D71AC8FADA6C9B5, -927, -260 },
16555  { 0xEA9C227723EE8BCB, -901, -252 },
16556  { 0xAECC49914078536D, -874, -244 },
16557  { 0x823C12795DB6CE57, -847, -236 },
16558  { 0xC21094364DFB5637, -821, -228 },
16559  { 0x9096EA6F3848984F, -794, -220 },
16560  { 0xD77485CB25823AC7, -768, -212 },
16561  { 0xA086CFCD97BF97F4, -741, -204 },
16562  { 0xEF340A98172AACE5, -715, -196 },
16563  { 0xB23867FB2A35B28E, -688, -188 },
16564  { 0x84C8D4DFD2C63F3B, -661, -180 },
16565  { 0xC5DD44271AD3CDBA, -635, -172 },
16566  { 0x936B9FCEBB25C996, -608, -164 },
16567  { 0xDBAC6C247D62A584, -582, -156 },
16568  { 0xA3AB66580D5FDAF6, -555, -148 },
16569  { 0xF3E2F893DEC3F126, -529, -140 },
16570  { 0xB5B5ADA8AAFF80B8, -502, -132 },
16571  { 0x87625F056C7C4A8B, -475, -124 },
16572  { 0xC9BCFF6034C13053, -449, -116 },
16573  { 0x964E858C91BA2655, -422, -108 },
16574  { 0xDFF9772470297EBD, -396, -100 },
16575  { 0xA6DFBD9FB8E5B88F, -369, -92 },
16576  { 0xF8A95FCF88747D94, -343, -84 },
16577  { 0xB94470938FA89BCF, -316, -76 },
16578  { 0x8A08F0F8BF0F156B, -289, -68 },
16579  { 0xCDB02555653131B6, -263, -60 },
16580  { 0x993FE2C6D07B7FAC, -236, -52 },
16581  { 0xE45C10C42A2B3B06, -210, -44 },
16582  { 0xAA242499697392D3, -183, -36 },
16583  { 0xFD87B5F28300CA0E, -157, -28 },
16584  { 0xBCE5086492111AEB, -130, -20 },
16585  { 0x8CBCCC096F5088CC, -103, -12 },
16586  { 0xD1B71758E219652C, -77, -4 },
16587  { 0x9C40000000000000, -50, 4 },
16588  { 0xE8D4A51000000000, -24, 12 },
16589  { 0xAD78EBC5AC620000, 3, 20 },
16590  { 0x813F3978F8940984, 30, 28 },
16591  { 0xC097CE7BC90715B3, 56, 36 },
16592  { 0x8F7E32CE7BEA5C70, 83, 44 },
16593  { 0xD5D238A4ABE98068, 109, 52 },
16594  { 0x9F4F2726179A2245, 136, 60 },
16595  { 0xED63A231D4C4FB27, 162, 68 },
16596  { 0xB0DE65388CC8ADA8, 189, 76 },
16597  { 0x83C7088E1AAB65DB, 216, 84 },
16598  { 0xC45D1DF942711D9A, 242, 92 },
16599  { 0x924D692CA61BE758, 269, 100 },
16600  { 0xDA01EE641A708DEA, 295, 108 },
16601  { 0xA26DA3999AEF774A, 322, 116 },
16602  { 0xF209787BB47D6B85, 348, 124 },
16603  { 0xB454E4A179DD1877, 375, 132 },
16604  { 0x865B86925B9BC5C2, 402, 140 },
16605  { 0xC83553C5C8965D3D, 428, 148 },
16606  { 0x952AB45CFA97A0B3, 455, 156 },
16607  { 0xDE469FBD99A05FE3, 481, 164 },
16608  { 0xA59BC234DB398C25, 508, 172 },
16609  { 0xF6C69A72A3989F5C, 534, 180 },
16610  { 0xB7DCBF5354E9BECE, 561, 188 },
16611  { 0x88FCF317F22241E2, 588, 196 },
16612  { 0xCC20CE9BD35C78A5, 614, 204 },
16613  { 0x98165AF37B2153DF, 641, 212 },
16614  { 0xE2A0B5DC971F303A, 667, 220 },
16615  { 0xA8D9D1535CE3B396, 694, 228 },
16616  { 0xFB9B7CD9A4A7443C, 720, 236 },
16617  { 0xBB764C4CA7A44410, 747, 244 },
16618  { 0x8BAB8EEFB6409C1A, 774, 252 },
16619  { 0xD01FEF10A657842C, 800, 260 },
16620  { 0x9B10A4E5E9913129, 827, 268 },
16621  { 0xE7109BFBA19C0C9D, 853, 276 },
16622  { 0xAC2820D9623BF429, 880, 284 },
16623  { 0x80444B5E7AA7CF85, 907, 292 },
16624  { 0xBF21E44003ACDD2D, 933, 300 },
16625  { 0x8E679C2F5E44FF8F, 960, 308 },
16626  { 0xD433179D9C8CB841, 986, 316 },
16627  { 0x9E19DB92B4E31BA9, 1013, 324 },
16628  }
16629  };
16630 
16631  // This computation gives exactly the same results for k as
16632  // k = ceil((kAlpha - e - 1) * 0.30102999566398114)
16633  // for |e| <= 1500, but doesn't require floating-point operations.
16634  // NB: log_10(2) ~= 78913 / 2^18
16635  JSON_ASSERT(e >= -1500);
16636  JSON_ASSERT(e <= 1500);
16637  const int f = kAlpha - e - 1;
16638  const int k = (f * 78913) / (1 << 18) + static_cast<int>(f > 0);
16639 
16640  const int index = (-kCachedPowersMinDecExp + k + (kCachedPowersDecStep - 1)) / kCachedPowersDecStep;
16641  JSON_ASSERT(index >= 0);
16642  JSON_ASSERT(static_cast<std::size_t>(index) < kCachedPowers.size());
16643 
16644  const cached_power cached = kCachedPowers[static_cast<std::size_t>(index)];
16645  JSON_ASSERT(kAlpha <= cached.e + e + 64);
16646  JSON_ASSERT(kGamma >= cached.e + e + 64);
16647 
16648  return cached;
16649 }
16650 
16655 inline int find_largest_pow10(const std::uint32_t n, std::uint32_t& pow10)
16656 {
16657  // LCOV_EXCL_START
16658  if (n >= 1000000000)
16659  {
16660  pow10 = 1000000000;
16661  return 10;
16662  }
16663  // LCOV_EXCL_STOP
16664  if (n >= 100000000)
16665  {
16666  pow10 = 100000000;
16667  return 9;
16668  }
16669  if (n >= 10000000)
16670  {
16671  pow10 = 10000000;
16672  return 8;
16673  }
16674  if (n >= 1000000)
16675  {
16676  pow10 = 1000000;
16677  return 7;
16678  }
16679  if (n >= 100000)
16680  {
16681  pow10 = 100000;
16682  return 6;
16683  }
16684  if (n >= 10000)
16685  {
16686  pow10 = 10000;
16687  return 5;
16688  }
16689  if (n >= 1000)
16690  {
16691  pow10 = 1000;
16692  return 4;
16693  }
16694  if (n >= 100)
16695  {
16696  pow10 = 100;
16697  return 3;
16698  }
16699  if (n >= 10)
16700  {
16701  pow10 = 10;
16702  return 2;
16703  }
16704 
16705  pow10 = 1;
16706  return 1;
16707 }
16708 
16709 inline void grisu2_round(char* buf, int len, std::uint64_t dist, std::uint64_t delta,
16710  std::uint64_t rest, std::uint64_t ten_k)
16711 {
16712  JSON_ASSERT(len >= 1);
16713  JSON_ASSERT(dist <= delta);
16714  JSON_ASSERT(rest <= delta);
16715  JSON_ASSERT(ten_k > 0);
16716 
16717  // <--------------------------- delta ---->
16718  // <---- dist --------->
16719  // --------------[------------------+-------------------]--------------
16720  // M- w M+
16721  //
16722  // ten_k
16723  // <------>
16724  // <---- rest ---->
16725  // --------------[------------------+----+--------------]--------------
16726  // w V
16727  // = buf * 10^k
16728  //
16729  // ten_k represents a unit-in-the-last-place in the decimal representation
16730  // stored in buf.
16731  // Decrement buf by ten_k while this takes buf closer to w.
16732 
16733  // The tests are written in this order to avoid overflow in unsigned
16734  // integer arithmetic.
16735 
16736  while (rest < dist
16737  && delta - rest >= ten_k
16738  && (rest + ten_k < dist || dist - rest > rest + ten_k - dist))
16739  {
16740  JSON_ASSERT(buf[len - 1] != '0');
16741  buf[len - 1]--;
16742  rest += ten_k;
16743  }
16744 }
16745 
16750 inline void grisu2_digit_gen(char* buffer, int& length, int& decimal_exponent,
16751  diyfp M_minus, diyfp w, diyfp M_plus)
16752 {
16753  static_assert(kAlpha >= -60, "internal error");
16754  static_assert(kGamma <= -32, "internal error");
16755 
16756  // Generates the digits (and the exponent) of a decimal floating-point
16757  // number V = buffer * 10^decimal_exponent in the range [M-, M+]. The diyfp's
16758  // w, M- and M+ share the same exponent e, which satisfies alpha <= e <= gamma.
16759  //
16760  // <--------------------------- delta ---->
16761  // <---- dist --------->
16762  // --------------[------------------+-------------------]--------------
16763  // M- w M+
16764  //
16765  // Grisu2 generates the digits of M+ from left to right and stops as soon as
16766  // V is in [M-,M+].
16767 
16768  JSON_ASSERT(M_plus.e >= kAlpha);
16769  JSON_ASSERT(M_plus.e <= kGamma);
16770 
16771  std::uint64_t delta = diyfp::sub(M_plus, M_minus).f; // (significand of (M+ - M-), implicit exponent is e)
16772  std::uint64_t dist = diyfp::sub(M_plus, w ).f; // (significand of (M+ - w ), implicit exponent is e)
16773 
16774  // Split M+ = f * 2^e into two parts p1 and p2 (note: e < 0):
16775  //
16776  // M+ = f * 2^e
16777  // = ((f div 2^-e) * 2^-e + (f mod 2^-e)) * 2^e
16778  // = ((p1 ) * 2^-e + (p2 )) * 2^e
16779  // = p1 + p2 * 2^e
16780 
16781  const diyfp one(std::uint64_t{1} << -M_plus.e, M_plus.e);
16782 
16783  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.)
16784  std::uint64_t p2 = M_plus.f & (one.f - 1); // p2 = f mod 2^-e
16785 
16786  // 1)
16787  //
16788  // Generate the digits of the integral part p1 = d[n-1]...d[1]d[0]
16789 
16790  JSON_ASSERT(p1 > 0);
16791 
16792  std::uint32_t pow10{};
16793  const int k = find_largest_pow10(p1, pow10);
16794 
16795  // 10^(k-1) <= p1 < 10^k, pow10 = 10^(k-1)
16796  //
16797  // p1 = (p1 div 10^(k-1)) * 10^(k-1) + (p1 mod 10^(k-1))
16798  // = (d[k-1] ) * 10^(k-1) + (p1 mod 10^(k-1))
16799  //
16800  // M+ = p1 + p2 * 2^e
16801  // = d[k-1] * 10^(k-1) + (p1 mod 10^(k-1)) + p2 * 2^e
16802  // = d[k-1] * 10^(k-1) + ((p1 mod 10^(k-1)) * 2^-e + p2) * 2^e
16803  // = d[k-1] * 10^(k-1) + ( rest) * 2^e
16804  //
16805  // Now generate the digits d[n] of p1 from left to right (n = k-1,...,0)
16806  //
16807  // p1 = d[k-1]...d[n] * 10^n + d[n-1]...d[0]
16808  //
16809  // but stop as soon as
16810  //
16811  // rest * 2^e = (d[n-1]...d[0] * 2^-e + p2) * 2^e <= delta * 2^e
16812 
16813  int n = k;
16814  while (n > 0)
16815  {
16816  // Invariants:
16817  // M+ = buffer * 10^n + (p1 + p2 * 2^e) (buffer = 0 for n = k)
16818  // pow10 = 10^(n-1) <= p1 < 10^n
16819  //
16820  const std::uint32_t d = p1 / pow10; // d = p1 div 10^(n-1)
16821  const std::uint32_t r = p1 % pow10; // r = p1 mod 10^(n-1)
16822  //
16823  // M+ = buffer * 10^n + (d * 10^(n-1) + r) + p2 * 2^e
16824  // = (buffer * 10 + d) * 10^(n-1) + (r + p2 * 2^e)
16825  //
16826  JSON_ASSERT(d <= 9);
16827  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16828  //
16829  // M+ = buffer * 10^(n-1) + (r + p2 * 2^e)
16830  //
16831  p1 = r;
16832  n--;
16833  //
16834  // M+ = buffer * 10^n + (p1 + p2 * 2^e)
16835  // pow10 = 10^n
16836  //
16837 
16838  // Now check if enough digits have been generated.
16839  // Compute
16840  //
16841  // p1 + p2 * 2^e = (p1 * 2^-e + p2) * 2^e = rest * 2^e
16842  //
16843  // Note:
16844  // Since rest and delta share the same exponent e, it suffices to
16845  // compare the significands.
16846  const std::uint64_t rest = (std::uint64_t{p1} << -one.e) + p2;
16847  if (rest <= delta)
16848  {
16849  // V = buffer * 10^n, with M- <= V <= M+.
16850 
16851  decimal_exponent += n;
16852 
16853  // We may now just stop. But instead look if the buffer could be
16854  // decremented to bring V closer to w.
16855  //
16856  // pow10 = 10^n is now 1 ulp in the decimal representation V.
16857  // The rounding procedure works with diyfp's with an implicit
16858  // exponent of e.
16859  //
16860  // 10^n = (10^n * 2^-e) * 2^e = ulp * 2^e
16861  //
16862  const std::uint64_t ten_n = std::uint64_t{pow10} << -one.e;
16863  grisu2_round(buffer, length, dist, delta, rest, ten_n);
16864 
16865  return;
16866  }
16867 
16868  pow10 /= 10;
16869  //
16870  // pow10 = 10^(n-1) <= p1 < 10^n
16871  // Invariants restored.
16872  }
16873 
16874  // 2)
16875  //
16876  // The digits of the integral part have been generated:
16877  //
16878  // M+ = d[k-1]...d[1]d[0] + p2 * 2^e
16879  // = buffer + p2 * 2^e
16880  //
16881  // Now generate the digits of the fractional part p2 * 2^e.
16882  //
16883  // Note:
16884  // No decimal point is generated: the exponent is adjusted instead.
16885  //
16886  // p2 actually represents the fraction
16887  //
16888  // p2 * 2^e
16889  // = p2 / 2^-e
16890  // = d[-1] / 10^1 + d[-2] / 10^2 + ...
16891  //
16892  // Now generate the digits d[-m] of p1 from left to right (m = 1,2,...)
16893  //
16894  // p2 * 2^e = d[-1]d[-2]...d[-m] * 10^-m
16895  // + 10^-m * (d[-m-1] / 10^1 + d[-m-2] / 10^2 + ...)
16896  //
16897  // using
16898  //
16899  // 10^m * p2 = ((10^m * p2) div 2^-e) * 2^-e + ((10^m * p2) mod 2^-e)
16900  // = ( d) * 2^-e + ( r)
16901  //
16902  // or
16903  // 10^m * p2 * 2^e = d + r * 2^e
16904  //
16905  // i.e.
16906  //
16907  // M+ = buffer + p2 * 2^e
16908  // = buffer + 10^-m * (d + r * 2^e)
16909  // = (buffer * 10^m + d) * 10^-m + 10^-m * r * 2^e
16910  //
16911  // and stop as soon as 10^-m * r * 2^e <= delta * 2^e
16912 
16913  JSON_ASSERT(p2 > delta);
16914 
16915  int m = 0;
16916  for (;;)
16917  {
16918  // Invariant:
16919  // M+ = buffer * 10^-m + 10^-m * (d[-m-1] / 10 + d[-m-2] / 10^2 + ...) * 2^e
16920  // = buffer * 10^-m + 10^-m * (p2 ) * 2^e
16921  // = buffer * 10^-m + 10^-m * (1/10 * (10 * p2) ) * 2^e
16922  // = buffer * 10^-m + 10^-m * (1/10 * ((10*p2 div 2^-e) * 2^-e + (10*p2 mod 2^-e)) * 2^e
16923  //
16925  p2 *= 10;
16926  const std::uint64_t d = p2 >> -one.e; // d = (10 * p2) div 2^-e
16927  const std::uint64_t r = p2 & (one.f - 1); // r = (10 * p2) mod 2^-e
16928  //
16929  // M+ = buffer * 10^-m + 10^-m * (1/10 * (d * 2^-e + r) * 2^e
16930  // = buffer * 10^-m + 10^-m * (1/10 * (d + r * 2^e))
16931  // = (buffer * 10 + d) * 10^(-m-1) + 10^(-m-1) * r * 2^e
16932  //
16933  JSON_ASSERT(d <= 9);
16934  buffer[length++] = static_cast<char>('0' + d); // buffer := buffer * 10 + d
16935  //
16936  // M+ = buffer * 10^(-m-1) + 10^(-m-1) * r * 2^e
16937  //
16938  p2 = r;
16939  m++;
16940  //
16941  // M+ = buffer * 10^-m + 10^-m * p2 * 2^e
16942  // Invariant restored.
16943 
16944  // Check if enough digits have been generated.
16945  //
16946  // 10^-m * p2 * 2^e <= delta * 2^e
16947  // p2 * 2^e <= 10^m * delta * 2^e
16948  // p2 <= 10^m * delta
16949  delta *= 10;
16950  dist *= 10;
16951  if (p2 <= delta)
16952  {
16953  break;
16954  }
16955  }
16956 
16957  // V = buffer * 10^-m, with M- <= V <= M+.
16958 
16959  decimal_exponent -= m;
16960 
16961  // 1 ulp in the decimal representation is now 10^-m.
16962  // Since delta and dist are now scaled by 10^m, we need to do the
16963  // same with ulp in order to keep the units in sync.
16964  //
16965  // 10^m * 10^-m = 1 = 2^-e * 2^e = ten_m * 2^e
16966  //
16967  const std::uint64_t ten_m = one.f;
16968  grisu2_round(buffer, length, dist, delta, p2, ten_m);
16969 
16970  // By construction this algorithm generates the shortest possible decimal
16971  // number (Loitsch, Theorem 6.2) which rounds back to w.
16972  // For an input number of precision p, at least
16973  //
16974  // N = 1 + ceil(p * log_10(2))
16975  //
16976  // decimal digits are sufficient to identify all binary floating-point
16977  // numbers (Matula, "In-and-Out conversions").
16978  // This implies that the algorithm does not produce more than N decimal
16979  // digits.
16980  //
16981  // N = 17 for p = 53 (IEEE double precision)
16982  // N = 9 for p = 24 (IEEE single precision)
16983 }
16984 
16991 inline void grisu2(char* buf, int& len, int& decimal_exponent,
16992  diyfp m_minus, diyfp v, diyfp m_plus)
16993 {
16994  JSON_ASSERT(m_plus.e == m_minus.e);
16995  JSON_ASSERT(m_plus.e == v.e);
16996 
16997  // --------(-----------------------+-----------------------)-------- (A)
16998  // m- v m+
16999  //
17000  // --------------------(-----------+-----------------------)-------- (B)
17001  // m- v m+
17002  //
17003  // First scale v (and m- and m+) such that the exponent is in the range
17004  // [alpha, gamma].
17005 
17006  const cached_power cached = get_cached_power_for_binary_exponent(m_plus.e);
17007 
17008  const diyfp c_minus_k(cached.f, cached.e); // = c ~= 10^-k
17009 
17010  // The exponent of the products is = v.e + c_minus_k.e + q and is in the range [alpha,gamma]
17011  const diyfp w = diyfp::mul(v, c_minus_k);
17012  const diyfp w_minus = diyfp::mul(m_minus, c_minus_k);
17013  const diyfp w_plus = diyfp::mul(m_plus, c_minus_k);
17014 
17015  // ----(---+---)---------------(---+---)---------------(---+---)----
17016  // w- w w+
17017  // = c*m- = c*v = c*m+
17018  //
17019  // diyfp::mul rounds its result and c_minus_k is approximated too. w, w- and
17020  // w+ are now off by a small amount.
17021  // In fact:
17022  //
17023  // w - v * 10^k < 1 ulp
17024  //
17025  // To account for this inaccuracy, add resp. subtract 1 ulp.
17026  //
17027  // --------+---[---------------(---+---)---------------]---+--------
17028  // w- M- w M+ w+
17029  //
17030  // Now any number in [M-, M+] (bounds included) will round to w when input,
17031  // regardless of how the input rounding algorithm breaks ties.
17032  //
17033  // And digit_gen generates the shortest possible such number in [M-, M+].
17034  // Note that this does not mean that Grisu2 always generates the shortest
17035  // possible number in the interval (m-, m+).
17036  const diyfp M_minus(w_minus.f + 1, w_minus.e);
17037  const diyfp M_plus (w_plus.f - 1, w_plus.e );
17038 
17039  decimal_exponent = -cached.k; // = -(-k) = k
17040 
17041  grisu2_digit_gen(buf, len, decimal_exponent, M_minus, w, M_plus);
17042 }
17043 
17049 template<typename FloatType>
17051 void grisu2(char* buf, int& len, int& decimal_exponent, FloatType value)
17052 {
17053  static_assert(diyfp::kPrecision >= std::numeric_limits<FloatType>::digits + 3,
17054  "internal error: not enough precision");
17055 
17056  JSON_ASSERT(std::isfinite(value));
17057  JSON_ASSERT(value > 0);
17058 
17059  // If the neighbors (and boundaries) of 'value' are always computed for double-precision
17060  // numbers, all float's can be recovered using strtod (and strtof). However, the resulting
17061  // decimal representations are not exactly "short".
17062  //
17063  // The documentation for 'std::to_chars' (https://en.cppreference.com/w/cpp/utility/to_chars)
17064  // says "value is converted to a string as if by std::sprintf in the default ("C") locale"
17065  // and since sprintf promotes floats to doubles, I think this is exactly what 'std::to_chars'
17066  // does.
17067  // On the other hand, the documentation for 'std::to_chars' requires that "parsing the
17068  // representation using the corresponding std::from_chars function recovers value exactly". That
17069  // indicates that single precision floating-point numbers should be recovered using
17070  // 'std::strtof'.
17071  //
17072  // NB: If the neighbors are computed for single-precision numbers, there is a single float
17073  // (7.0385307e-26f) which can't be recovered using strtod. The resulting double precision
17074  // value is off by 1 ulp.
17075 #if 0
17076  const boundaries w = compute_boundaries(static_cast<double>(value));
17077 #else
17078  const boundaries w = compute_boundaries(value);
17079 #endif
17080 
17081  grisu2(buf, len, decimal_exponent, w.minus, w.w, w.plus);
17082 }
17083 
17091 inline char* append_exponent(char* buf, int e)
17092 {
17093  JSON_ASSERT(e > -1000);
17094  JSON_ASSERT(e < 1000);
17095 
17096  if (e < 0)
17097  {
17098  e = -e;
17099  *buf++ = '-';
17100  }
17101  else
17102  {
17103  *buf++ = '+';
17104  }
17105 
17106  auto k = static_cast<std::uint32_t>(e);
17107  if (k < 10)
17108  {
17109  // Always print at least two digits in the exponent.
17110  // This is for compatibility with printf("%g").
17111  *buf++ = '0';
17112  *buf++ = static_cast<char>('0' + k);
17113  }
17114  else if (k < 100)
17115  {
17116  *buf++ = static_cast<char>('0' + k / 10);
17117  k %= 10;
17118  *buf++ = static_cast<char>('0' + k);
17119  }
17120  else
17121  {
17122  *buf++ = static_cast<char>('0' + k / 100);
17123  k %= 100;
17124  *buf++ = static_cast<char>('0' + k / 10);
17125  k %= 10;
17126  *buf++ = static_cast<char>('0' + k);
17127  }
17128 
17129  return buf;
17130 }
17131 
17143 inline char* format_buffer(char* buf, int len, int decimal_exponent,
17144  int min_exp, int max_exp)
17145 {
17146  JSON_ASSERT(min_exp < 0);
17147  JSON_ASSERT(max_exp > 0);
17148 
17149  const int k = len;
17150  const int n = len + decimal_exponent;
17151 
17152  // v = buf * 10^(n-k)
17153  // k is the length of the buffer (number of decimal digits)
17154  // n is the position of the decimal point relative to the start of the buffer.
17155 
17156  if (k <= n && n <= max_exp)
17157  {
17158  // digits[000]
17159  // len <= max_exp + 2
17160 
17161  std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
17162  // Make it look like a floating-point number (#362, #378)
17163  buf[n + 0] = '.';
17164  buf[n + 1] = '0';
17165  return buf + (static_cast<size_t>(n) + 2);
17166  }
17167 
17168  if (0 < n && n <= max_exp)
17169  {
17170  // dig.its
17171  // len <= max_digits10 + 1
17172 
17173  JSON_ASSERT(k > n);
17174 
17175  std::memmove(buf + (static_cast<size_t>(n) + 1), buf + n, static_cast<size_t>(k) - static_cast<size_t>(n));
17176  buf[n] = '.';
17177  return buf + (static_cast<size_t>(k) + 1U);
17178  }
17179 
17180  if (min_exp < n && n <= 0)
17181  {
17182  // 0.[000]digits
17183  // len <= 2 + (-min_exp - 1) + max_digits10
17184 
17185  std::memmove(buf + (2 + static_cast<size_t>(-n)), buf, static_cast<size_t>(k));
17186  buf[0] = '0';
17187  buf[1] = '.';
17188  std::memset(buf + 2, '0', static_cast<size_t>(-n));
17189  return buf + (2U + static_cast<size_t>(-n) + static_cast<size_t>(k));
17190  }
17191 
17192  if (k == 1)
17193  {
17194  // dE+123
17195  // len <= 1 + 5
17196 
17197  buf += 1;
17198  }
17199  else
17200  {
17201  // d.igitsE+123
17202  // len <= max_digits10 + 1 + 5
17203 
17204  std::memmove(buf + 2, buf + 1, static_cast<size_t>(k) - 1);
17205  buf[1] = '.';
17206  buf += 1 + static_cast<size_t>(k);
17207  }
17208 
17209  *buf++ = 'e';
17210  return append_exponent(buf, n - 1);
17211 }
17212 
17213 } // namespace dtoa_impl
17214 
17225 template<typename FloatType>
17228 char* to_chars(char* first, const char* last, FloatType value)
17229 {
17230  static_cast<void>(last); // maybe unused - fix warning
17231  JSON_ASSERT(std::isfinite(value));
17232 
17233  // Use signbit(value) instead of (value < 0) since signbit works for -0.
17234  if (std::signbit(value))
17235  {
17236  value = -value;
17237  *first++ = '-';
17238  }
17239 
17240 #ifdef __GNUC__
17241 #pragma GCC diagnostic push
17242 #pragma GCC diagnostic ignored "-Wfloat-equal"
17243 #endif
17244  if (value == 0) // +-0
17245  {
17246  *first++ = '0';
17247  // Make it look like a floating-point number (#362, #378)
17248  *first++ = '.';
17249  *first++ = '0';
17250  return first;
17251  }
17252 #ifdef __GNUC__
17253 #pragma GCC diagnostic pop
17254 #endif
17255 
17256  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10);
17257 
17258  // Compute v = buffer * 10^decimal_exponent.
17259  // The decimal digits are stored in the buffer, which needs to be interpreted
17260  // as an unsigned decimal integer.
17261  // len is the length of the buffer, i.e. the number of decimal digits.
17262  int len = 0;
17263  int decimal_exponent = 0;
17264  dtoa_impl::grisu2(first, len, decimal_exponent, value);
17265 
17266  JSON_ASSERT(len <= std::numeric_limits<FloatType>::max_digits10);
17267 
17268  // Format the buffer like printf("%.*g", prec, value)
17269  constexpr int kMinExp = -4;
17270  // Use digits10 here to increase compatibility with version 2.
17271  constexpr int kMaxExp = std::numeric_limits<FloatType>::digits10;
17272 
17273  JSON_ASSERT(last - first >= kMaxExp + 2);
17274  JSON_ASSERT(last - first >= 2 + (-kMinExp - 1) + std::numeric_limits<FloatType>::max_digits10);
17275  JSON_ASSERT(last - first >= std::numeric_limits<FloatType>::max_digits10 + 6);
17276 
17277  return dtoa_impl::format_buffer(first, len, decimal_exponent, kMinExp, kMaxExp);
17278 }
17279 
17280 } // namespace detail
17281 } // namespace nlohmann
17282 
17283 // #include <nlohmann/detail/exceptions.hpp>
17284 
17285 // #include <nlohmann/detail/macro_scope.hpp>
17286 
17287 // #include <nlohmann/detail/meta/cpp_future.hpp>
17288 
17289 // #include <nlohmann/detail/output/binary_writer.hpp>
17290 
17291 // #include <nlohmann/detail/output/output_adapters.hpp>
17292 
17293 // #include <nlohmann/detail/string_concat.hpp>
17294 
17295 // #include <nlohmann/detail/value_t.hpp>
17296 
17297 
17298 namespace nlohmann
17299 {
17300 namespace detail
17301 {
17303 // serialization //
17305 
17308 {
17309  strict,
17310  replace,
17311  ignore
17312 };
17313 
17314 template<typename BasicJsonType>
17316 {
17317  using string_t = typename BasicJsonType::string_t;
17318  using number_float_t = typename BasicJsonType::number_float_t;
17319  using number_integer_t = typename BasicJsonType::number_integer_t;
17320  using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
17321  using binary_char_t = typename BasicJsonType::binary_t::value_type;
17322  static constexpr std::uint8_t UTF8_ACCEPT = 0;
17323  static constexpr std::uint8_t UTF8_REJECT = 1;
17324 
17325  public:
17331  serializer(output_adapter_t<char> s, const char ichar,
17332  error_handler_t error_handler_ = error_handler_t::strict)
17333  : o(std::move(s))
17334  , loc(std::localeconv())
17335  , thousands_sep(loc->thousands_sep == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->thousands_sep)))
17336  , decimal_point(loc->decimal_point == nullptr ? '\0' : std::char_traits<char>::to_char_type(* (loc->decimal_point)))
17337  , indent_char(ichar)
17338  , indent_string(512, indent_char)
17339  , error_handler(error_handler_)
17340  {}
17341 
17342  // delete because of pointer members
17343  serializer(const serializer&) = delete;
17344  serializer& operator=(const serializer&) = delete;
17345  serializer(serializer&&) = delete;
17347  ~serializer() = default;
17348 
17371  void dump(const BasicJsonType& val,
17372  const bool pretty_print,
17373  const bool ensure_ascii,
17374  const unsigned int indent_step,
17375  const unsigned int current_indent = 0)
17376  {
17377  switch (val.m_type)
17378  {
17379  case value_t::object:
17380  {
17381  if (val.m_value.object->empty())
17382  {
17383  o->write_characters("{}", 2);
17384  return;
17385  }
17386 
17387  if (pretty_print)
17388  {
17389  o->write_characters("{\n", 2);
17390 
17391  // variable to hold indentation for recursive calls
17392  const auto new_indent = current_indent + indent_step;
17393  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17394  {
17395  indent_string.resize(indent_string.size() * 2, ' ');
17396  }
17397 
17398  // first n-1 elements
17399  auto i = val.m_value.object->cbegin();
17400  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
17401  {
17402  o->write_characters(indent_string.c_str(), new_indent);
17403  o->write_character('\"');
17404  dump_escaped(i->first, ensure_ascii);
17405  o->write_characters("\": ", 3);
17406  dump(i->second, true, ensure_ascii, indent_step, new_indent);
17407  o->write_characters(",\n", 2);
17408  }
17409 
17410  // last element
17411  JSON_ASSERT(i != val.m_value.object->cend());
17412  JSON_ASSERT(std::next(i) == val.m_value.object->cend());
17413  o->write_characters(indent_string.c_str(), new_indent);
17414  o->write_character('\"');
17415  dump_escaped(i->first, ensure_ascii);
17416  o->write_characters("\": ", 3);
17417  dump(i->second, true, ensure_ascii, indent_step, new_indent);
17418 
17419  o->write_character('\n');
17420  o->write_characters(indent_string.c_str(), current_indent);
17421  o->write_character('}');
17422  }
17423  else
17424  {
17425  o->write_character('{');
17426 
17427  // first n-1 elements
17428  auto i = val.m_value.object->cbegin();
17429  for (std::size_t cnt = 0; cnt < val.m_value.object->size() - 1; ++cnt, ++i)
17430  {
17431  o->write_character('\"');
17432  dump_escaped(i->first, ensure_ascii);
17433  o->write_characters("\":", 2);
17434  dump(i->second, false, ensure_ascii, indent_step, current_indent);
17435  o->write_character(',');
17436  }
17437 
17438  // last element
17439  JSON_ASSERT(i != val.m_value.object->cend());
17440  JSON_ASSERT(std::next(i) == val.m_value.object->cend());
17441  o->write_character('\"');
17442  dump_escaped(i->first, ensure_ascii);
17443  o->write_characters("\":", 2);
17444  dump(i->second, false, ensure_ascii, indent_step, current_indent);
17445 
17446  o->write_character('}');
17447  }
17448 
17449  return;
17450  }
17451 
17452  case value_t::array:
17453  {
17454  if (val.m_value.array->empty())
17455  {
17456  o->write_characters("[]", 2);
17457  return;
17458  }
17459 
17460  if (pretty_print)
17461  {
17462  o->write_characters("[\n", 2);
17463 
17464  // variable to hold indentation for recursive calls
17465  const auto new_indent = current_indent + indent_step;
17466  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17467  {
17468  indent_string.resize(indent_string.size() * 2, ' ');
17469  }
17470 
17471  // first n-1 elements
17472  for (auto i = val.m_value.array->cbegin();
17473  i != val.m_value.array->cend() - 1; ++i)
17474  {
17475  o->write_characters(indent_string.c_str(), new_indent);
17476  dump(*i, true, ensure_ascii, indent_step, new_indent);
17477  o->write_characters(",\n", 2);
17478  }
17479 
17480  // last element
17481  JSON_ASSERT(!val.m_value.array->empty());
17482  o->write_characters(indent_string.c_str(), new_indent);
17483  dump(val.m_value.array->back(), true, ensure_ascii, indent_step, new_indent);
17484 
17485  o->write_character('\n');
17486  o->write_characters(indent_string.c_str(), current_indent);
17487  o->write_character(']');
17488  }
17489  else
17490  {
17491  o->write_character('[');
17492 
17493  // first n-1 elements
17494  for (auto i = val.m_value.array->cbegin();
17495  i != val.m_value.array->cend() - 1; ++i)
17496  {
17497  dump(*i, false, ensure_ascii, indent_step, current_indent);
17498  o->write_character(',');
17499  }
17500 
17501  // last element
17502  JSON_ASSERT(!val.m_value.array->empty());
17503  dump(val.m_value.array->back(), false, ensure_ascii, indent_step, current_indent);
17504 
17505  o->write_character(']');
17506  }
17507 
17508  return;
17509  }
17510 
17511  case value_t::string:
17512  {
17513  o->write_character('\"');
17514  dump_escaped(*val.m_value.string, ensure_ascii);
17515  o->write_character('\"');
17516  return;
17517  }
17518 
17519  case value_t::binary:
17520  {
17521  if (pretty_print)
17522  {
17523  o->write_characters("{\n", 2);
17524 
17525  // variable to hold indentation for recursive calls
17526  const auto new_indent = current_indent + indent_step;
17527  if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent))
17528  {
17529  indent_string.resize(indent_string.size() * 2, ' ');
17530  }
17531 
17532  o->write_characters(indent_string.c_str(), new_indent);
17533 
17534  o->write_characters("\"bytes\": [", 10);
17535 
17536  if (!val.m_value.binary->empty())
17537  {
17538  for (auto i = val.m_value.binary->cbegin();
17539  i != val.m_value.binary->cend() - 1; ++i)
17540  {
17541  dump_integer(*i);
17542  o->write_characters(", ", 2);
17543  }
17544  dump_integer(val.m_value.binary->back());
17545  }
17546 
17547  o->write_characters("],\n", 3);
17548  o->write_characters(indent_string.c_str(), new_indent);
17549 
17550  o->write_characters("\"subtype\": ", 11);
17551  if (val.m_value.binary->has_subtype())
17552  {
17553  dump_integer(val.m_value.binary->subtype());
17554  }
17555  else
17556  {
17557  o->write_characters("null", 4);
17558  }
17559  o->write_character('\n');
17560  o->write_characters(indent_string.c_str(), current_indent);
17561  o->write_character('}');
17562  }
17563  else
17564  {
17565  o->write_characters("{\"bytes\":[", 10);
17566 
17567  if (!val.m_value.binary->empty())
17568  {
17569  for (auto i = val.m_value.binary->cbegin();
17570  i != val.m_value.binary->cend() - 1; ++i)
17571  {
17572  dump_integer(*i);
17573  o->write_character(',');
17574  }
17575  dump_integer(val.m_value.binary->back());
17576  }
17577 
17578  o->write_characters("],\"subtype\":", 12);
17579  if (val.m_value.binary->has_subtype())
17580  {
17581  dump_integer(val.m_value.binary->subtype());
17582  o->write_character('}');
17583  }
17584  else
17585  {
17586  o->write_characters("null}", 5);
17587  }
17588  }
17589  return;
17590  }
17591 
17592  case value_t::boolean:
17593  {
17594  if (val.m_value.boolean)
17595  {
17596  o->write_characters("true", 4);
17597  }
17598  else
17599  {
17600  o->write_characters("false", 5);
17601  }
17602  return;
17603  }
17604 
17606  {
17607  dump_integer(val.m_value.number_integer);
17608  return;
17609  }
17610 
17612  {
17613  dump_integer(val.m_value.number_unsigned);
17614  return;
17615  }
17616 
17617  case value_t::number_float:
17618  {
17619  dump_float(val.m_value.number_float);
17620  return;
17621  }
17622 
17623  case value_t::discarded:
17624  {
17625  o->write_characters("<discarded>", 11);
17626  return;
17627  }
17628 
17629  case value_t::null:
17630  {
17631  o->write_characters("null", 4);
17632  return;
17633  }
17634 
17635  default: // LCOV_EXCL_LINE
17636  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17637  }
17638  }
17639 
17655  void dump_escaped(const string_t& s, const bool ensure_ascii)
17656  {
17657  std::uint32_t codepoint{};
17658  std::uint8_t state = UTF8_ACCEPT;
17659  std::size_t bytes = 0; // number of bytes written to string_buffer
17660 
17661  // number of bytes written at the point of the last valid byte
17662  std::size_t bytes_after_last_accept = 0;
17663  std::size_t undumped_chars = 0;
17664 
17665  for (std::size_t i = 0; i < s.size(); ++i)
17666  {
17667  const auto byte = static_cast<std::uint8_t>(s[i]);
17668 
17669  switch (decode(state, codepoint, byte))
17670  {
17671  case UTF8_ACCEPT: // decode found a new code point
17672  {
17673  switch (codepoint)
17674  {
17675  case 0x08: // backspace
17676  {
17677  string_buffer[bytes++] = '\\';
17678  string_buffer[bytes++] = 'b';
17679  break;
17680  }
17681 
17682  case 0x09: // horizontal tab
17683  {
17684  string_buffer[bytes++] = '\\';
17685  string_buffer[bytes++] = 't';
17686  break;
17687  }
17688 
17689  case 0x0A: // newline
17690  {
17691  string_buffer[bytes++] = '\\';
17692  string_buffer[bytes++] = 'n';
17693  break;
17694  }
17695 
17696  case 0x0C: // formfeed
17697  {
17698  string_buffer[bytes++] = '\\';
17699  string_buffer[bytes++] = 'f';
17700  break;
17701  }
17702 
17703  case 0x0D: // carriage return
17704  {
17705  string_buffer[bytes++] = '\\';
17706  string_buffer[bytes++] = 'r';
17707  break;
17708  }
17709 
17710  case 0x22: // quotation mark
17711  {
17712  string_buffer[bytes++] = '\\';
17713  string_buffer[bytes++] = '\"';
17714  break;
17715  }
17716 
17717  case 0x5C: // reverse solidus
17718  {
17719  string_buffer[bytes++] = '\\';
17720  string_buffer[bytes++] = '\\';
17721  break;
17722  }
17723 
17724  default:
17725  {
17726  // escape control characters (0x00..0x1F) or, if
17727  // ensure_ascii parameter is used, non-ASCII characters
17728  if ((codepoint <= 0x1F) || (ensure_ascii && (codepoint >= 0x7F)))
17729  {
17730  if (codepoint <= 0xFFFF)
17731  {
17732  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17733  static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 7, "\\u%04x",
17734  static_cast<std::uint16_t>(codepoint)));
17735  bytes += 6;
17736  }
17737  else
17738  {
17739  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
17740  static_cast<void>((std::snprintf)(string_buffer.data() + bytes, 13, "\\u%04x\\u%04x",
17741  static_cast<std::uint16_t>(0xD7C0u + (codepoint >> 10u)),
17742  static_cast<std::uint16_t>(0xDC00u + (codepoint & 0x3FFu))));
17743  bytes += 12;
17744  }
17745  }
17746  else
17747  {
17748  // copy byte to buffer (all previous bytes
17749  // been copied have in default case above)
17750  string_buffer[bytes++] = s[i];
17751  }
17752  break;
17753  }
17754  }
17755 
17756  // write buffer and reset index; there must be 13 bytes
17757  // left, as this is the maximal number of bytes to be
17758  // written ("\uxxxx\uxxxx\0") for one code point
17759  if (string_buffer.size() - bytes < 13)
17760  {
17761  o->write_characters(string_buffer.data(), bytes);
17762  bytes = 0;
17763  }
17764 
17765  // remember the byte position of this accept
17767  undumped_chars = 0;
17768  break;
17769  }
17770 
17771  case UTF8_REJECT: // decode found invalid UTF-8 byte
17772  {
17773  switch (error_handler)
17774  {
17776  {
17777  JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_bytes(byte | 0)), nullptr));
17778  }
17779 
17782  {
17783  // in case we saw this character the first time, we
17784  // would like to read it again, because the byte
17785  // may be OK for itself, but just not OK for the
17786  // previous sequence
17787  if (undumped_chars > 0)
17788  {
17789  --i;
17790  }
17791 
17792  // reset length buffer to the last accepted index;
17793  // thus removing/ignoring the invalid characters
17795 
17797  {
17798  // add a replacement character
17799  if (ensure_ascii)
17800  {
17801  string_buffer[bytes++] = '\\';
17802  string_buffer[bytes++] = 'u';
17803  string_buffer[bytes++] = 'f';
17804  string_buffer[bytes++] = 'f';
17805  string_buffer[bytes++] = 'f';
17806  string_buffer[bytes++] = 'd';
17807  }
17808  else
17809  {
17813  }
17814 
17815  // write buffer and reset index; there must be 13 bytes
17816  // left, as this is the maximal number of bytes to be
17817  // written ("\uxxxx\uxxxx\0") for one code point
17818  if (string_buffer.size() - bytes < 13)
17819  {
17820  o->write_characters(string_buffer.data(), bytes);
17821  bytes = 0;
17822  }
17823 
17825  }
17826 
17827  undumped_chars = 0;
17828 
17829  // continue processing the string
17830  state = UTF8_ACCEPT;
17831  break;
17832  }
17833 
17834  default: // LCOV_EXCL_LINE
17835  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17836  }
17837  break;
17838  }
17839 
17840  default: // decode found yet incomplete multi-byte code point
17841  {
17842  if (!ensure_ascii)
17843  {
17844  // code point will not be escaped - copy byte to buffer
17845  string_buffer[bytes++] = s[i];
17846  }
17847  ++undumped_chars;
17848  break;
17849  }
17850  }
17851  }
17852 
17853  // we finished processing the string
17854  if (JSON_HEDLEY_LIKELY(state == UTF8_ACCEPT))
17855  {
17856  // write buffer
17857  if (bytes > 0)
17858  {
17859  o->write_characters(string_buffer.data(), bytes);
17860  }
17861  }
17862  else
17863  {
17864  // we finish reading, but do not accept: string was incomplete
17865  switch (error_handler)
17866  {
17868  {
17869  JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", hex_bytes(static_cast<std::uint8_t>(s.back() | 0))), nullptr));
17870  }
17871 
17873  {
17874  // write all accepted bytes
17875  o->write_characters(string_buffer.data(), bytes_after_last_accept);
17876  break;
17877  }
17878 
17880  {
17881  // write all accepted bytes
17882  o->write_characters(string_buffer.data(), bytes_after_last_accept);
17883  // add a replacement character
17884  if (ensure_ascii)
17885  {
17886  o->write_characters("\\ufffd", 6);
17887  }
17888  else
17889  {
17890  o->write_characters("\xEF\xBF\xBD", 3);
17891  }
17892  break;
17893  }
17894 
17895  default: // LCOV_EXCL_LINE
17896  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
17897  }
17898  }
17899  }
17900 
17901  private:
17910  inline unsigned int count_digits(number_unsigned_t x) noexcept
17911  {
17912  unsigned int n_digits = 1;
17913  for (;;)
17914  {
17915  if (x < 10)
17916  {
17917  return n_digits;
17918  }
17919  if (x < 100)
17920  {
17921  return n_digits + 1;
17922  }
17923  if (x < 1000)
17924  {
17925  return n_digits + 2;
17926  }
17927  if (x < 10000)
17928  {
17929  return n_digits + 3;
17930  }
17931  x = x / 10000u;
17932  n_digits += 4;
17933  }
17934  }
17935 
17941  static std::string hex_bytes(std::uint8_t byte)
17942  {
17943  std::string result = "FF";
17944  constexpr const char* nibble_to_hex = "0123456789ABCDEF";
17945  result[0] = nibble_to_hex[byte / 16];
17946  result[1] = nibble_to_hex[byte % 16];
17947  return result;
17948  }
17949 
17950  // templates to avoid warnings about useless casts
17951  template <typename NumberType, enable_if_t<std::is_signed<NumberType>::value, int> = 0>
17952  bool is_negative_number(NumberType x)
17953  {
17954  return x < 0;
17955  }
17956 
17957  template < typename NumberType, enable_if_t <std::is_unsigned<NumberType>::value, int > = 0 >
17958  bool is_negative_number(NumberType /*unused*/)
17959  {
17960  return false;
17961  }
17962 
17972  template < typename NumberType, detail::enable_if_t <
17973  std::is_integral<NumberType>::value ||
17974  std::is_same<NumberType, number_unsigned_t>::value ||
17975  std::is_same<NumberType, number_integer_t>::value ||
17976  std::is_same<NumberType, binary_char_t>::value,
17977  int > = 0 >
17978  void dump_integer(NumberType x)
17979  {
17980  static constexpr std::array<std::array<char, 2>, 100> digits_to_99
17981  {
17982  {
17983  {{'0', '0'}}, {{'0', '1'}}, {{'0', '2'}}, {{'0', '3'}}, {{'0', '4'}}, {{'0', '5'}}, {{'0', '6'}}, {{'0', '7'}}, {{'0', '8'}}, {{'0', '9'}},
17984  {{'1', '0'}}, {{'1', '1'}}, {{'1', '2'}}, {{'1', '3'}}, {{'1', '4'}}, {{'1', '5'}}, {{'1', '6'}}, {{'1', '7'}}, {{'1', '8'}}, {{'1', '9'}},
17985  {{'2', '0'}}, {{'2', '1'}}, {{'2', '2'}}, {{'2', '3'}}, {{'2', '4'}}, {{'2', '5'}}, {{'2', '6'}}, {{'2', '7'}}, {{'2', '8'}}, {{'2', '9'}},
17986  {{'3', '0'}}, {{'3', '1'}}, {{'3', '2'}}, {{'3', '3'}}, {{'3', '4'}}, {{'3', '5'}}, {{'3', '6'}}, {{'3', '7'}}, {{'3', '8'}}, {{'3', '9'}},
17987  {{'4', '0'}}, {{'4', '1'}}, {{'4', '2'}}, {{'4', '3'}}, {{'4', '4'}}, {{'4', '5'}}, {{'4', '6'}}, {{'4', '7'}}, {{'4', '8'}}, {{'4', '9'}},
17988  {{'5', '0'}}, {{'5', '1'}}, {{'5', '2'}}, {{'5', '3'}}, {{'5', '4'}}, {{'5', '5'}}, {{'5', '6'}}, {{'5', '7'}}, {{'5', '8'}}, {{'5', '9'}},
17989  {{'6', '0'}}, {{'6', '1'}}, {{'6', '2'}}, {{'6', '3'}}, {{'6', '4'}}, {{'6', '5'}}, {{'6', '6'}}, {{'6', '7'}}, {{'6', '8'}}, {{'6', '9'}},
17990  {{'7', '0'}}, {{'7', '1'}}, {{'7', '2'}}, {{'7', '3'}}, {{'7', '4'}}, {{'7', '5'}}, {{'7', '6'}}, {{'7', '7'}}, {{'7', '8'}}, {{'7', '9'}},
17991  {{'8', '0'}}, {{'8', '1'}}, {{'8', '2'}}, {{'8', '3'}}, {{'8', '4'}}, {{'8', '5'}}, {{'8', '6'}}, {{'8', '7'}}, {{'8', '8'}}, {{'8', '9'}},
17992  {{'9', '0'}}, {{'9', '1'}}, {{'9', '2'}}, {{'9', '3'}}, {{'9', '4'}}, {{'9', '5'}}, {{'9', '6'}}, {{'9', '7'}}, {{'9', '8'}}, {{'9', '9'}},
17993  }
17994  };
17995 
17996  // special case for "0"
17997  if (x == 0)
17998  {
17999  o->write_character('0');
18000  return;
18001  }
18002 
18003  // use a pointer to fill the buffer
18004  auto buffer_ptr = number_buffer.begin(); // NOLINT(llvm-qualified-auto,readability-qualified-auto,cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18005 
18006  number_unsigned_t abs_value;
18007 
18008  unsigned int n_chars{};
18009 
18010  if (is_negative_number(x))
18011  {
18012  *buffer_ptr = '-';
18013  abs_value = remove_sign(static_cast<number_integer_t>(x));
18014 
18015  // account one more byte for the minus sign
18016  n_chars = 1 + count_digits(abs_value);
18017  }
18018  else
18019  {
18020  abs_value = static_cast<number_unsigned_t>(x);
18021  n_chars = count_digits(abs_value);
18022  }
18023 
18024  // spare 1 byte for '\0'
18025  JSON_ASSERT(n_chars < number_buffer.size() - 1);
18026 
18027  // jump to the end to generate the string from backward,
18028  // so we later avoid reversing the result
18029  buffer_ptr += n_chars;
18030 
18031  // Fast int2ascii implementation inspired by "Fastware" talk by Andrei Alexandrescu
18032  // See: https://www.youtube.com/watch?v=o4-CwDo2zpg
18033  while (abs_value >= 100)
18034  {
18035  const auto digits_index = static_cast<unsigned>((abs_value % 100));
18036  abs_value /= 100;
18037  *(--buffer_ptr) = digits_to_99[digits_index][1];
18038  *(--buffer_ptr) = digits_to_99[digits_index][0];
18039  }
18040 
18041  if (abs_value >= 10)
18042  {
18043  const auto digits_index = static_cast<unsigned>(abs_value);
18044  *(--buffer_ptr) = digits_to_99[digits_index][1];
18045  *(--buffer_ptr) = digits_to_99[digits_index][0];
18046  }
18047  else
18048  {
18049  *(--buffer_ptr) = static_cast<char>('0' + abs_value);
18050  }
18051 
18052  o->write_characters(number_buffer.data(), n_chars);
18053  }
18054 
18063  void dump_float(number_float_t x)
18064  {
18065  // NaN / inf
18066  if (!std::isfinite(x))
18067  {
18068  o->write_characters("null", 4);
18069  return;
18070  }
18071 
18072  // If number_float_t is an IEEE-754 single or double precision number,
18073  // use the Grisu2 algorithm to produce short numbers which are
18074  // guaranteed to round-trip, using strtof and strtod, resp.
18075  //
18076  // NB: The test below works if <long double> == <double>.
18077  static constexpr bool is_ieee_single_or_double
18078  = (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) ||
18079  (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);
18080 
18081  dump_float(x, std::integral_constant<bool, is_ieee_single_or_double>());
18082  }
18083 
18084  void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/)
18085  {
18086  auto* begin = number_buffer.data();
18087  auto* end = ::nlohmann::detail::to_chars(begin, begin + number_buffer.size(), x);
18088 
18089  o->write_characters(begin, static_cast<size_t>(end - begin));
18090  }
18091 
18092  void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/)
18093  {
18094  // get number of digits for a float -> text -> float round-trip
18095  static constexpr auto d = std::numeric_limits<number_float_t>::max_digits10;
18096 
18097  // the actual conversion
18098  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
18099  std::ptrdiff_t len = (std::snprintf)(number_buffer.data(), number_buffer.size(), "%.*g", d, x);
18100 
18101  // negative value indicates an error
18102  JSON_ASSERT(len > 0);
18103  // check if buffer was large enough
18104  JSON_ASSERT(static_cast<std::size_t>(len) < number_buffer.size());
18105 
18106  // erase thousands separator
18107  if (thousands_sep != '\0')
18108  {
18109  // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::remove returns an iterator, see https://github.com/nlohmann/json/issues/3081
18110  const auto end = std::remove(number_buffer.begin(), number_buffer.begin() + len, thousands_sep);
18111  std::fill(end, number_buffer.end(), '\0');
18112  JSON_ASSERT((end - number_buffer.begin()) <= len);
18113  len = (end - number_buffer.begin());
18114  }
18115 
18116  // convert decimal point to '.'
18117  if (decimal_point != '\0' && decimal_point != '.')
18118  {
18119  // NOLINTNEXTLINE(readability-qualified-auto,llvm-qualified-auto): std::find returns an iterator, see https://github.com/nlohmann/json/issues/3081
18120  const auto dec_pos = std::find(number_buffer.begin(), number_buffer.end(), decimal_point);
18121  if (dec_pos != number_buffer.end())
18122  {
18123  *dec_pos = '.';
18124  }
18125  }
18126 
18127  o->write_characters(number_buffer.data(), static_cast<std::size_t>(len));
18128 
18129  // determine if we need to append ".0"
18130  const bool value_is_int_like =
18131  std::none_of(number_buffer.begin(), number_buffer.begin() + len + 1,
18132  [](char c)
18133  {
18134  return c == '.' || c == 'e';
18135  });
18136 
18137  if (value_is_int_like)
18138  {
18139  o->write_characters(".0", 2);
18140  }
18141  }
18142 
18164  static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, const std::uint8_t byte) noexcept
18165  {
18166  static const std::array<std::uint8_t, 400> utf8d =
18167  {
18168  {
18169  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
18170  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
18171  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
18172  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
18173  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
18174  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
18175  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
18176  0xA, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, // E0..EF
18177  0xB, 0x6, 0x6, 0x6, 0x5, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, // F0..FF
18178  0x0, 0x1, 0x2, 0x3, 0x5, 0x8, 0x7, 0x1, 0x1, 0x1, 0x4, 0x6, 0x1, 0x1, 0x1, 0x1, // s0..s0
18179  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
18180  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
18181  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
18182  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
18183  }
18184  };
18185 
18186  JSON_ASSERT(byte < utf8d.size());
18187  const std::uint8_t type = utf8d[byte];
18188 
18189  codep = (state != UTF8_ACCEPT)
18190  ? (byte & 0x3fu) | (codep << 6u)
18191  : (0xFFu >> type) & (byte);
18192 
18193  std::size_t index = 256u + static_cast<size_t>(state) * 16u + static_cast<size_t>(type);
18194  JSON_ASSERT(index < 400);
18195  state = utf8d[index];
18196  return state;
18197  }
18198 
18199  /*
18200  * Overload to make the compiler happy while it is instantiating
18201  * dump_integer for number_unsigned_t.
18202  * Must never be called.
18203  */
18204  number_unsigned_t remove_sign(number_unsigned_t x)
18205  {
18206  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
18207  return x; // LCOV_EXCL_LINE
18208  }
18209 
18210  /*
18211  * Helper function for dump_integer
18212  *
18213  * This function takes a negative signed integer and returns its absolute
18214  * value as unsigned integer. The plus/minus shuffling is necessary as we can
18215  * not directly remove the sign of an arbitrary signed integer as the
18216  * absolute values of INT_MIN and INT_MAX are usually not the same. See
18217  * #1708 for details.
18218  */
18219  inline number_unsigned_t remove_sign(number_integer_t x) noexcept
18220  {
18221  JSON_ASSERT(x < 0 && x < (std::numeric_limits<number_integer_t>::max)()); // NOLINT(misc-redundant-expression)
18222  return static_cast<number_unsigned_t>(-(x + 1)) + 1;
18223  }
18224 
18225  private:
18227  output_adapter_t<char> o = nullptr;
18228 
18230  std::array<char, 64> number_buffer{{}};
18231 
18233  const std::lconv* loc = nullptr;
18235  const char thousands_sep = '\0';
18237  const char decimal_point = '\0';
18238 
18240  std::array<char, 512> string_buffer{{}};
18241 
18243  const char indent_char;
18245  string_t indent_string;
18246 
18249 };
18250 } // namespace detail
18251 } // namespace nlohmann
18252 
18253 // #include <nlohmann/detail/value_t.hpp>
18254 
18255 // #include <nlohmann/json_fwd.hpp>
18256 
18257 // #include <nlohmann/ordered_map.hpp>
18258 
18259 
18260 #include <functional> // equal_to, less
18261 #include <initializer_list> // initializer_list
18262 #include <iterator> // input_iterator_tag, iterator_traits
18263 #include <memory> // allocator
18264 #include <stdexcept> // for out_of_range
18265 #include <type_traits> // enable_if, is_convertible
18266 #include <utility> // pair
18267 #include <vector> // vector
18268 
18269 // #include <nlohmann/detail/macro_scope.hpp>
18270 
18271 // #include <nlohmann/detail/meta/type_traits.hpp>
18272 
18273 
18274 namespace nlohmann
18275 {
18276 
18279 template <class Key, class T, class IgnoredLess = std::less<Key>,
18280  class Allocator = std::allocator<std::pair<const Key, T>>>
18281  struct ordered_map : std::vector<std::pair<const Key, T>, Allocator>
18282 {
18283  using key_type = Key;
18284  using mapped_type = T;
18285  using Container = std::vector<std::pair<const Key, T>, Allocator>;
18286  using iterator = typename Container::iterator;
18287  using const_iterator = typename Container::const_iterator;
18288  using size_type = typename Container::size_type;
18289  using value_type = typename Container::value_type;
18290 #ifdef JSON_HAS_CPP_14
18291  using key_compare = std::equal_to<>;
18292 #else
18293  using key_compare = std::equal_to<Key>;
18294 #endif
18295 
18296  // Explicit constructors instead of `using Container::Container`
18297  // otherwise older compilers choke on it (GCC <= 5.5, xcode <= 9.4)
18298  ordered_map() noexcept(noexcept(Container())) : Container{} {}
18299  explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container(alloc))) : Container{alloc} {}
18300  template <class It>
18301  ordered_map(It first, It last, const Allocator& alloc = Allocator())
18302  : Container{first, last, alloc} {}
18303  ordered_map(std::initializer_list<value_type> init, const Allocator& alloc = Allocator() )
18304  : Container{init, alloc} {}
18305 
18306  std::pair<iterator, bool> emplace(const key_type& key, T&& t)
18307  {
18308  for (auto it = this->begin(); it != this->end(); ++it)
18309  {
18310  if (m_compare(it->first, key))
18311  {
18312  return {it, false};
18313  }
18314  }
18315  Container::emplace_back(key, std::forward<T>(t));
18316  return {std::prev(this->end()), true};
18317  }
18318 
18319  template<class KeyType, detail::enable_if_t<
18321  std::pair<iterator, bool> emplace(KeyType && key, T && t)
18322  {
18323  for (auto it = this->begin(); it != this->end(); ++it)
18324  {
18325  if (m_compare(it->first, key))
18326  {
18327  return {it, false};
18328  }
18329  }
18330  Container::emplace_back(std::forward<KeyType>(key), std::forward<T>(t));
18331  return {std::prev(this->end()), true};
18332  }
18333 
18334  T& operator[](const key_type& key)
18335  {
18336  return emplace(key, T{}).first->second;
18337  }
18338 
18339  template<class KeyType, detail::enable_if_t<
18341  T & operator[](KeyType && key)
18342  {
18343  return emplace(std::forward<KeyType>(key), T{}).first->second;
18344  }
18345 
18346  const T& operator[](const key_type& key) const
18347  {
18348  return at(key);
18349  }
18350 
18351  template<class KeyType, detail::enable_if_t<
18353  const T & operator[](KeyType && key) const
18354  {
18355  return at(std::forward<KeyType>(key));
18356  }
18357 
18358  T& at(const key_type& key)
18359  {
18360  for (auto it = this->begin(); it != this->end(); ++it)
18361  {
18362  if (m_compare(it->first, key))
18363  {
18364  return it->second;
18365  }
18366  }
18367 
18368  JSON_THROW(std::out_of_range("key not found"));
18369  }
18370 
18371  template<class KeyType, detail::enable_if_t<
18373  T & at(KeyType && key)
18374  {
18375  for (auto it = this->begin(); it != this->end(); ++it)
18376  {
18377  if (m_compare(it->first, key))
18378  {
18379  return it->second;
18380  }
18381  }
18382 
18383  JSON_THROW(std::out_of_range("key not found"));
18384  }
18385 
18386  const T& at(const key_type& key) const
18387  {
18388  for (auto it = this->begin(); it != this->end(); ++it)
18389  {
18390  if (m_compare(it->first, key))
18391  {
18392  return it->second;
18393  }
18394  }
18395 
18396  JSON_THROW(std::out_of_range("key not found"));
18397  }
18398 
18399  template<class KeyType, detail::enable_if_t<
18401  const T & at(KeyType && key) const
18402  {
18403  for (auto it = this->begin(); it != this->end(); ++it)
18404  {
18405  if (m_compare(it->first, key))
18406  {
18407  return it->second;
18408  }
18409  }
18410 
18411  JSON_THROW(std::out_of_range("key not found"));
18412  }
18413 
18415  {
18416  for (auto it = this->begin(); it != this->end(); ++it)
18417  {
18418  if (m_compare(it->first, key))
18419  {
18420  // Since we cannot move const Keys, re-construct them in place
18421  for (auto next = it; ++next != this->end(); ++it)
18422  {
18423  it->~value_type(); // Destroy but keep allocation
18424  new (&*it) value_type{std::move(*next)};
18425  }
18426  Container::pop_back();
18427  return 1;
18428  }
18429  }
18430  return 0;
18431  }
18432 
18433  template<class KeyType, detail::enable_if_t<
18435  size_type erase(KeyType && key)
18436  {
18437  for (auto it = this->begin(); it != this->end(); ++it)
18438  {
18439  if (m_compare(it->first, key))
18440  {
18441  // Since we cannot move const Keys, re-construct them in place
18442  for (auto next = it; ++next != this->end(); ++it)
18443  {
18444  it->~value_type(); // Destroy but keep allocation
18445  new (&*it) value_type{std::move(*next)};
18446  }
18447  Container::pop_back();
18448  return 1;
18449  }
18450  }
18451  return 0;
18452  }
18453 
18455  {
18456  return erase(pos, std::next(pos));
18457  }
18458 
18460  {
18461  if (first == last)
18462  {
18463  return first;
18464  }
18465 
18466  const auto elements_affected = std::distance(first, last);
18467  const auto offset = std::distance(Container::begin(), first);
18468 
18469  // This is the start situation. We need to delete elements_affected
18470  // elements (3 in this example: e, f, g), and need to return an
18471  // iterator past the last deleted element (h in this example).
18472  // Note that offset is the distance from the start of the vector
18473  // to first. We will need this later.
18474 
18475  // [ a, b, c, d, e, f, g, h, i, j ]
18476  // ^ ^
18477  // first last
18478 
18479  // Since we cannot move const Keys, we re-construct them in place.
18480  // We start at first and re-construct (viz. copy) the elements from
18481  // the back of the vector. Example for first iteration:
18482 
18483  // ,--------.
18484  // v | destroy e and re-construct with h
18485  // [ a, b, c, d, e, f, g, h, i, j ]
18486  // ^ ^
18487  // it it + elements_affected
18488 
18489  for (auto it = first; std::next(it, elements_affected) != Container::end(); ++it)
18490  {
18491  it->~value_type(); // destroy but keep allocation
18492  new (&*it) value_type{std::move(*std::next(it, elements_affected))}; // "move" next element to it
18493  }
18494 
18495  // [ a, b, c, d, h, i, j, h, i, j ]
18496  // ^ ^
18497  // first last
18498 
18499  // remove the unneeded elements at the end of the vector
18500  Container::resize(this->size() - static_cast<size_type>(elements_affected));
18501 
18502  // [ a, b, c, d, h, i, j ]
18503  // ^ ^
18504  // first last
18505 
18506  // first is now pointing past the last deleted element, but we cannot
18507  // use this iterator, because it may have been invalidated by the
18508  // resize call. Instead, we can return begin() + offset.
18509  return Container::begin() + offset;
18510  }
18511 
18512  size_type count(const key_type& key) const
18513  {
18514  for (auto it = this->begin(); it != this->end(); ++it)
18515  {
18516  if (m_compare(it->first, key))
18517  {
18518  return 1;
18519  }
18520  }
18521  return 0;
18522  }
18523 
18524  template<class KeyType, detail::enable_if_t<
18526  size_type count(KeyType && key) const
18527  {
18528  for (auto it = this->begin(); it != this->end(); ++it)
18529  {
18530  if (m_compare(it->first, key))
18531  {
18532  return 1;
18533  }
18534  }
18535  return 0;
18536  }
18537 
18538  iterator find(const key_type& key)
18539  {
18540  for (auto it = this->begin(); it != this->end(); ++it)
18541  {
18542  if (m_compare(it->first, key))
18543  {
18544  return it;
18545  }
18546  }
18547  return Container::end();
18548  }
18549 
18550  template<class KeyType, detail::enable_if_t<
18552  iterator find(KeyType && key)
18553  {
18554  for (auto it = this->begin(); it != this->end(); ++it)
18555  {
18556  if (m_compare(it->first, key))
18557  {
18558  return it;
18559  }
18560  }
18561  return Container::end();
18562  }
18563 
18564  const_iterator find(const key_type& key) const
18565  {
18566  for (auto it = this->begin(); it != this->end(); ++it)
18567  {
18568  if (m_compare(it->first, key))
18569  {
18570  return it;
18571  }
18572  }
18573  return Container::end();
18574  }
18575 
18576  std::pair<iterator, bool> insert( value_type&& value )
18577  {
18578  return emplace(value.first, std::move(value.second));
18579  }
18580 
18581  std::pair<iterator, bool> insert( const value_type& value )
18582  {
18583  for (auto it = this->begin(); it != this->end(); ++it)
18584  {
18585  if (m_compare(it->first, value.first))
18586  {
18587  return {it, false};
18588  }
18589  }
18590  Container::push_back(value);
18591  return {--this->end(), true};
18592  }
18593 
18594  template<typename InputIt>
18595  using require_input_iter = typename std::enable_if<std::is_convertible<typename std::iterator_traits<InputIt>::iterator_category,
18596  std::input_iterator_tag>::value>::type;
18597 
18598  template<typename InputIt, typename = require_input_iter<InputIt>>
18599  void insert(InputIt first, InputIt last)
18600  {
18601  for (auto it = first; it != last; ++it)
18602  {
18603  insert(*it);
18604  }
18605  }
18606 
18607 private:
18609 };
18610 
18611 } // namespace nlohmann
18612 
18613 
18614 #if defined(JSON_HAS_CPP_17)
18615  #include <any>
18616  #include <string_view>
18617 #endif
18618 
18624 namespace nlohmann
18625 {
18626 
18646 class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
18647 {
18648  private:
18649  template<detail::value_t> friend struct detail::external_constructor;
18650 
18651  template<typename>
18652  friend class ::nlohmann::json_pointer;
18653  // can be restored when json_pointer backwards compatibility is removed
18654  // friend ::nlohmann::json_pointer<StringType>;
18655 
18656  template<typename BasicJsonType, typename InputType>
18657  friend class ::nlohmann::detail::parser;
18658  friend ::nlohmann::detail::serializer<basic_json>;
18659  template<typename BasicJsonType>
18660  friend class ::nlohmann::detail::iter_impl;
18661  template<typename BasicJsonType, typename CharType>
18662  friend class ::nlohmann::detail::binary_writer;
18663  template<typename BasicJsonType, typename InputType, typename SAX>
18664  friend class ::nlohmann::detail::binary_reader;
18665  template<typename BasicJsonType>
18666  friend class ::nlohmann::detail::json_sax_dom_parser;
18667  template<typename BasicJsonType>
18668  friend class ::nlohmann::detail::json_sax_dom_callback_parser;
18669  friend class ::nlohmann::detail::exception;
18670 
18672  using basic_json_t = NLOHMANN_BASIC_JSON_TPL;
18673 
18675  // convenience aliases for types residing in namespace detail;
18677 
18678  template<typename InputAdapterType>
18679  static ::nlohmann::detail::parser<basic_json, InputAdapterType> parser(
18680  InputAdapterType adapter,
18682  const bool allow_exceptions = true,
18683  const bool ignore_comments = false
18684  )
18685  {
18686  return ::nlohmann::detail::parser<basic_json, InputAdapterType>(std::move(adapter),
18687  std::move(cb), allow_exceptions, ignore_comments);
18688  }
18689 
18690  private:
18691  using primitive_iterator_t = ::nlohmann::detail::primitive_iterator_t;
18692  template<typename BasicJsonType>
18693  using internal_iterator = ::nlohmann::detail::internal_iterator<BasicJsonType>;
18694  template<typename BasicJsonType>
18696  template<typename Iterator>
18697  using iteration_proxy = ::nlohmann::detail::iteration_proxy<Iterator>;
18698  template<typename Base> using json_reverse_iterator = ::nlohmann::detail::json_reverse_iterator<Base>;
18699 
18700  template<typename CharType>
18702 
18703  template<typename InputType>
18705  template<typename CharType> using binary_writer = ::nlohmann::detail::binary_writer<basic_json, CharType>;
18706 
18708  using serializer = ::nlohmann::detail::serializer<basic_json>;
18709 
18710  public:
18714  template<typename T, typename SFINAE>
18715  using json_serializer = JSONSerializer<T, SFINAE>;
18721  using initializer_list_t = std::initializer_list<detail::json_ref<basic_json>>;
18722 
18726 
18728  // exceptions //
18730 
18734 
18741 
18743 
18744 
18746  // container types //
18748 
18753 
18756 
18760  using const_reference = const value_type&;
18761 
18763  using difference_type = std::ptrdiff_t;
18765  using size_type = std::size_t;
18766 
18768  using allocator_type = AllocatorType<basic_json>;
18769 
18771  using pointer = typename std::allocator_traits<allocator_type>::pointer;
18773  using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
18774 
18783 
18785 
18786 
18790  {
18791  return allocator_type();
18792  }
18793 
18797  static basic_json meta()
18798  {
18799  basic_json result;
18800 
18801  result["copyright"] = "(C) 2013-2022 Niels Lohmann";
18802  result["name"] = "JSON for Modern C++";
18803  result["url"] = "https://github.com/nlohmann/json";
18804  result["version"]["string"] =
18808  result["version"]["major"] = NLOHMANN_JSON_VERSION_MAJOR;
18809  result["version"]["minor"] = NLOHMANN_JSON_VERSION_MINOR;
18810  result["version"]["patch"] = NLOHMANN_JSON_VERSION_PATCH;
18811 
18812 #ifdef _WIN32
18813  result["platform"] = "win32";
18814 #elif defined __linux__
18815  result["platform"] = "linux";
18816 #elif defined __APPLE__
18817  result["platform"] = "apple";
18818 #elif defined __unix__
18819  result["platform"] = "unix";
18820 #else
18821  result["platform"] = "unknown";
18822 #endif
18823 
18824 #if defined(__ICC) || defined(__INTEL_COMPILER)
18825  result["compiler"] = {{"family", "icc"}, {"version", __INTEL_COMPILER}};
18826 #elif defined(__clang__)
18827  result["compiler"] = {{"family", "clang"}, {"version", __clang_version__}};
18828 #elif defined(__GNUC__) || defined(__GNUG__)
18829  result["compiler"] = {{"family", "gcc"}, {"version", detail::concat(
18830  std::to_string(__GNUC__), '.',
18831  std::to_string(__GNUC_MINOR__), '.',
18832  std::to_string(__GNUC_PATCHLEVEL__))
18833  }
18834  };
18835 #elif defined(__HP_cc) || defined(__HP_aCC)
18836  result["compiler"] = "hp"
18837 #elif defined(__IBMCPP__)
18838  result["compiler"] = {{"family", "ilecpp"}, {"version", __IBMCPP__}};
18839 #elif defined(_MSC_VER)
18840  result["compiler"] = {{"family", "msvc"}, {"version", _MSC_VER}};
18841 #elif defined(__PGI)
18842  result["compiler"] = {{"family", "pgcpp"}, {"version", __PGI}};
18843 #elif defined(__SUNPRO_CC)
18844  result["compiler"] = {{"family", "sunpro"}, {"version", __SUNPRO_CC}};
18845 #else
18846  result["compiler"] = {{"family", "unknown"}, {"version", "unknown"}};
18847 #endif
18848 
18849 
18850 #if defined(_MSVC_LANG)
18851  result["compiler"]["c++"] = std::to_string(_MSVC_LANG);
18852 #elif defined(__cplusplus)
18853  result["compiler"]["c++"] = std::to_string(__cplusplus);
18854 #else
18855  result["compiler"]["c++"] = "unknown";
18856 #endif
18857  return result;
18858  }
18859 
18860 
18862  // JSON value data types //
18864 
18869 
18874 #if defined(JSON_HAS_CPP_14)
18875  // use of transparent comparator avoids unnecessary repeated construction of temporaries
18876  // in functions involving lookup by key with types other than object_t::key_type (aka. StringType)
18877  using default_object_comparator_t = std::less<>;
18878 #else
18879  using default_object_comparator_t = std::less<StringType>;
18880 #endif
18881 
18884  using object_t = ObjectType<StringType,
18885  basic_json,
18887  AllocatorType<std::pair<const StringType,
18888  basic_json>>>;
18889 
18892  using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
18893 
18896  using string_t = StringType;
18897 
18900  using boolean_t = BooleanType;
18901 
18904  using number_integer_t = NumberIntegerType;
18905 
18908  using number_unsigned_t = NumberUnsignedType;
18909 
18912  using number_float_t = NumberFloatType;
18913 
18917 
18921 
18923 
18924  private:
18925 
18927  template<typename T, typename... Args>
18929  static T* create(Args&& ... args)
18930  {
18931  AllocatorType<T> alloc;
18932  using AllocatorTraits = std::allocator_traits<AllocatorType<T>>;
18933 
18934  auto deleter = [&](T * obj)
18935  {
18936  AllocatorTraits::deallocate(alloc, obj, 1);
18937  };
18938  std::unique_ptr<T, decltype(deleter)> obj(AllocatorTraits::allocate(alloc, 1), deleter);
18939  AllocatorTraits::construct(alloc, obj.get(), std::forward<Args>(args)...);
18940  JSON_ASSERT(obj != nullptr);
18941  return obj.release();
18942  }
18943 
18945  // JSON value storage //
18947 
18974  union json_value
18975  {
18977  object_t* object;
18979  array_t* array;
18981  string_t* string;
18983  binary_t* binary;
18985  boolean_t boolean;
18987  number_integer_t number_integer;
18989  number_unsigned_t number_unsigned;
18991  number_float_t number_float;
18992 
18994  json_value() = default;
18996  json_value(boolean_t v) noexcept : boolean(v) {}
18998  json_value(number_integer_t v) noexcept : number_integer(v) {}
19000  json_value(number_unsigned_t v) noexcept : number_unsigned(v) {}
19002  json_value(number_float_t v) noexcept : number_float(v) {}
19004  json_value(value_t t)
19005  {
19006  switch (t)
19007  {
19008  case value_t::object:
19009  {
19010  object = create<object_t>();
19011  break;
19012  }
19013 
19014  case value_t::array:
19015  {
19016  array = create<array_t>();
19017  break;
19018  }
19019 
19020  case value_t::string:
19021  {
19022  string = create<string_t>("");
19023  break;
19024  }
19025 
19026  case value_t::binary:
19027  {
19028  binary = create<binary_t>();
19029  break;
19030  }
19031 
19032  case value_t::boolean:
19033  {
19034  boolean = static_cast<boolean_t>(false);
19035  break;
19036  }
19037 
19039  {
19040  number_integer = static_cast<number_integer_t>(0);
19041  break;
19042  }
19043 
19045  {
19046  number_unsigned = static_cast<number_unsigned_t>(0);
19047  break;
19048  }
19049 
19050  case value_t::number_float:
19051  {
19052  number_float = static_cast<number_float_t>(0.0);
19053  break;
19054  }
19055 
19056  case value_t::null:
19057  {
19058  object = nullptr; // silence warning, see #821
19059  break;
19060  }
19061 
19062  case value_t::discarded:
19063  default:
19064  {
19065  object = nullptr; // silence warning, see #821
19067  {
19068  JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.10.5", nullptr)); // LCOV_EXCL_LINE
19069  }
19070  break;
19071  }
19072  }
19073  }
19074 
19076  json_value(const string_t& value) : string(create<string_t>(value)) {}
19077 
19079  json_value(string_t&& value) : string(create<string_t>(std::move(value))) {}
19080 
19082  json_value(const object_t& value) : object(create<object_t>(value)) {}
19083 
19085  json_value(object_t&& value) : object(create<object_t>(std::move(value))) {}
19086 
19088  json_value(const array_t& value) : array(create<array_t>(value)) {}
19089 
19091  json_value(array_t&& value) : array(create<array_t>(std::move(value))) {}
19092 
19094  json_value(const typename binary_t::container_type& value) : binary(create<binary_t>(value)) {}
19095 
19097  json_value(typename binary_t::container_type&& value) : binary(create<binary_t>(std::move(value))) {}
19098 
19100  json_value(const binary_t& value) : binary(create<binary_t>(value)) {}
19101 
19103  json_value(binary_t&& value) : binary(create<binary_t>(std::move(value))) {}
19104 
19105  void destroy(value_t t)
19106  {
19107  if (t == value_t::array || t == value_t::object)
19108  {
19109  // flatten the current json_value to a heap-allocated stack
19110  std::vector<basic_json> stack;
19111 
19112  // move the top-level items to stack
19113  if (t == value_t::array)
19114  {
19115  stack.reserve(array->size());
19116  std::move(array->begin(), array->end(), std::back_inserter(stack));
19117  }
19118  else
19119  {
19120  stack.reserve(object->size());
19121  for (auto&& it : *object)
19122  {
19123  stack.push_back(std::move(it.second));
19124  }
19125  }
19126 
19127  while (!stack.empty())
19128  {
19129  // move the last item to local variable to be processed
19130  basic_json current_item(std::move(stack.back()));
19131  stack.pop_back();
19132 
19133  // if current_item is array/object, move
19134  // its children to the stack to be processed later
19135  if (current_item.is_array())
19136  {
19137  std::move(current_item.m_value.array->begin(), current_item.m_value.array->end(), std::back_inserter(stack));
19138 
19139  current_item.m_value.array->clear();
19140  }
19141  else if (current_item.is_object())
19142  {
19143  for (auto&& it : *current_item.m_value.object)
19144  {
19145  stack.push_back(std::move(it.second));
19146  }
19147 
19148  current_item.m_value.object->clear();
19149  }
19150 
19151  // it's now safe that current_item get destructed
19152  // since it doesn't have any children
19153  }
19154  }
19155 
19156  switch (t)
19157  {
19158  case value_t::object:
19159  {
19160  AllocatorType<object_t> alloc;
19161  std::allocator_traits<decltype(alloc)>::destroy(alloc, object);
19162  std::allocator_traits<decltype(alloc)>::deallocate(alloc, object, 1);
19163  break;
19164  }
19165 
19166  case value_t::array:
19167  {
19168  AllocatorType<array_t> alloc;
19169  std::allocator_traits<decltype(alloc)>::destroy(alloc, array);
19170  std::allocator_traits<decltype(alloc)>::deallocate(alloc, array, 1);
19171  break;
19172  }
19173 
19174  case value_t::string:
19175  {
19176  AllocatorType<string_t> alloc;
19177  std::allocator_traits<decltype(alloc)>::destroy(alloc, string);
19178  std::allocator_traits<decltype(alloc)>::deallocate(alloc, string, 1);
19179  break;
19180  }
19181 
19182  case value_t::binary:
19183  {
19184  AllocatorType<binary_t> alloc;
19185  std::allocator_traits<decltype(alloc)>::destroy(alloc, binary);
19186  std::allocator_traits<decltype(alloc)>::deallocate(alloc, binary, 1);
19187  break;
19188  }
19189 
19190  case value_t::null:
19191  case value_t::boolean:
19194  case value_t::number_float:
19195  case value_t::discarded:
19196  default:
19197  {
19198  break;
19199  }
19200  }
19201  }
19202  };
19203 
19204  private:
19223  void assert_invariant(bool check_parents = true) const noexcept
19224  {
19225  JSON_ASSERT(m_type != value_t::object || m_value.object != nullptr);
19226  JSON_ASSERT(m_type != value_t::array || m_value.array != nullptr);
19227  JSON_ASSERT(m_type != value_t::string || m_value.string != nullptr);
19228  JSON_ASSERT(m_type != value_t::binary || m_value.binary != nullptr);
19229 
19230 #if JSON_DIAGNOSTICS
19231  JSON_TRY
19232  {
19233  // cppcheck-suppress assertWithSideEffect
19234  JSON_ASSERT(!check_parents || !is_structured() || std::all_of(begin(), end(), [this](const basic_json & j)
19235  {
19236  return j.m_parent == this;
19237  }));
19238  }
19239  JSON_CATCH(...) {} // LCOV_EXCL_LINE
19240 #endif
19241  static_cast<void>(check_parents);
19242  }
19243 
19244  void set_parents()
19245  {
19246 #if JSON_DIAGNOSTICS
19247  switch (m_type)
19248  {
19249  case value_t::array:
19250  {
19251  for (auto& element : *m_value.array)
19252  {
19253  element.m_parent = this;
19254  }
19255  break;
19256  }
19257 
19258  case value_t::object:
19259  {
19260  for (auto& element : *m_value.object)
19261  {
19262  element.second.m_parent = this;
19263  }
19264  break;
19265  }
19266 
19267  case value_t::null:
19268  case value_t::string:
19269  case value_t::boolean:
19272  case value_t::number_float:
19273  case value_t::binary:
19274  case value_t::discarded:
19275  default:
19276  break;
19277  }
19278 #endif
19279  }
19280 
19281  iterator set_parents(iterator it, typename iterator::difference_type count_set_parents)
19282  {
19283 #if JSON_DIAGNOSTICS
19284  for (typename iterator::difference_type i = 0; i < count_set_parents; ++i)
19285  {
19286  (it + i)->m_parent = this;
19287  }
19288 #else
19289  static_cast<void>(count_set_parents);
19290 #endif
19291  return it;
19292  }
19293 
19294  reference set_parent(reference j, std::size_t old_capacity = static_cast<std::size_t>(-1))
19295  {
19296 #if JSON_DIAGNOSTICS
19297  if (old_capacity != static_cast<std::size_t>(-1))
19298  {
19299  // see https://github.com/nlohmann/json/issues/2838
19301  if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
19302  {
19303  // capacity has changed: update all parents
19304  set_parents();
19305  return j;
19306  }
19307  }
19308 
19309  // ordered_json uses a vector internally, so pointers could have
19310  // been invalidated; see https://github.com/nlohmann/json/issues/2962
19311 #ifdef JSON_HEDLEY_MSVC_VERSION
19312 #pragma warning(push )
19313 #pragma warning(disable : 4127) // ignore warning to replace if with if constexpr
19314 #endif
19316  {
19317  set_parents();
19318  return j;
19319  }
19320 #ifdef JSON_HEDLEY_MSVC_VERSION
19321 #pragma warning( pop )
19322 #endif
19323 
19324  j.m_parent = this;
19325 #else
19326  static_cast<void>(j);
19327  static_cast<void>(old_capacity);
19328 #endif
19329  return j;
19330  }
19331 
19332  public:
19334  // JSON parser callback //
19336 
19340 
19344 
19346  // constructors //
19348 
19353 
19357  : m_type(v), m_value(v)
19358  {
19359  assert_invariant();
19360  }
19361 
19364  basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-exception-escape)
19365  : basic_json(value_t::null)
19366  {
19367  assert_invariant();
19368  }
19369 
19372  template < typename CompatibleType,
19373  typename U = detail::uncvref_t<CompatibleType>,
19376  basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-forwarding-reference-overload,bugprone-exception-escape)
19377  JSONSerializer<U>::to_json(std::declval<basic_json_t&>(),
19378  std::forward<CompatibleType>(val))))
19379  {
19380  JSONSerializer<U>::to_json(*this, std::forward<CompatibleType>(val));
19381  set_parents();
19382  assert_invariant();
19383  }
19384 
19387  template < typename BasicJsonType,
19389  detail::is_basic_json<BasicJsonType>::value&& !std::is_same<basic_json, BasicJsonType>::value, int > = 0 >
19390  basic_json(const BasicJsonType& val)
19391  {
19392  using other_boolean_t = typename BasicJsonType::boolean_t;
19393  using other_number_float_t = typename BasicJsonType::number_float_t;
19394  using other_number_integer_t = typename BasicJsonType::number_integer_t;
19395  using other_number_unsigned_t = typename BasicJsonType::number_unsigned_t;
19396  using other_string_t = typename BasicJsonType::string_t;
19397  using other_object_t = typename BasicJsonType::object_t;
19398  using other_array_t = typename BasicJsonType::array_t;
19399  using other_binary_t = typename BasicJsonType::binary_t;
19400 
19401  switch (val.type())
19402  {
19403  case value_t::boolean:
19404  JSONSerializer<other_boolean_t>::to_json(*this, val.template get<other_boolean_t>());
19405  break;
19406  case value_t::number_float:
19407  JSONSerializer<other_number_float_t>::to_json(*this, val.template get<other_number_float_t>());
19408  break;
19410  JSONSerializer<other_number_integer_t>::to_json(*this, val.template get<other_number_integer_t>());
19411  break;
19413  JSONSerializer<other_number_unsigned_t>::to_json(*this, val.template get<other_number_unsigned_t>());
19414  break;
19415  case value_t::string:
19416  JSONSerializer<other_string_t>::to_json(*this, val.template get_ref<const other_string_t&>());
19417  break;
19418  case value_t::object:
19419  JSONSerializer<other_object_t>::to_json(*this, val.template get_ref<const other_object_t&>());
19420  break;
19421  case value_t::array:
19422  JSONSerializer<other_array_t>::to_json(*this, val.template get_ref<const other_array_t&>());
19423  break;
19424  case value_t::binary:
19425  JSONSerializer<other_binary_t>::to_json(*this, val.template get_ref<const other_binary_t&>());
19426  break;
19427  case value_t::null:
19428  *this = nullptr;
19429  break;
19430  case value_t::discarded:
19431  m_type = value_t::discarded;
19432  break;
19433  default: // LCOV_EXCL_LINE
19434  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
19435  }
19436  JSON_ASSERT(m_type == val.type());
19437  set_parents();
19438  assert_invariant();
19439  }
19440 
19444  bool type_deduction = true,
19445  value_t manual_type = value_t::array)
19446  {
19447  // check if each element is an array with two elements whose first
19448  // element is a string
19449  bool is_an_object = std::all_of(init.begin(), init.end(),
19450  [](const detail::json_ref<basic_json>& element_ref)
19451  {
19452  return element_ref->is_array() && element_ref->size() == 2 && (*element_ref)[0].is_string();
19453  });
19454 
19455  // adjust type if type deduction is not wanted
19456  if (!type_deduction)
19457  {
19458  // if array is wanted, do not create an object though possible
19459  if (manual_type == value_t::array)
19460  {
19461  is_an_object = false;
19462  }
19463 
19464  // if object is wanted but impossible, throw an exception
19465  if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
19466  {
19467  JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
19468  }
19469  }
19470 
19471  if (is_an_object)
19472  {
19473  // the initializer list is a list of pairs -> create object
19474  m_type = value_t::object;
19476 
19477  for (auto& element_ref : init)
19478  {
19479  auto element = element_ref.moved_or_copied();
19480  m_value.object->emplace(
19481  std::move(*((*element.m_value.array)[0].m_value.string)),
19482  std::move((*element.m_value.array)[1]));
19483  }
19484  }
19485  else
19486  {
19487  // the initializer list describes an array -> create array
19488  m_type = value_t::array;
19489  m_value.array = create<array_t>(init.begin(), init.end());
19490  }
19491 
19492  set_parents();
19493  assert_invariant();
19494  }
19495 
19499  static basic_json binary(const typename binary_t::container_type& init)
19500  {
19501  auto res = basic_json();
19502  res.m_type = value_t::binary;
19503  res.m_value = init;
19504  return res;
19505  }
19506 
19510  static basic_json binary(const typename binary_t::container_type& init, typename binary_t::subtype_type subtype)
19511  {
19512  auto res = basic_json();
19513  res.m_type = value_t::binary;
19514  res.m_value = binary_t(init, subtype);
19515  return res;
19516  }
19517 
19522  {
19523  auto res = basic_json();
19524  res.m_type = value_t::binary;
19525  res.m_value = std::move(init);
19526  return res;
19527  }
19528 
19532  static basic_json binary(typename binary_t::container_type&& init, typename binary_t::subtype_type subtype)
19533  {
19534  auto res = basic_json();
19535  res.m_type = value_t::binary;
19536  res.m_value = binary_t(std::move(init), subtype);
19537  return res;
19538  }
19539 
19544  {
19545  return basic_json(init, false, value_t::array);
19546  }
19547 
19552  {
19553  return basic_json(init, false, value_t::object);
19554  }
19555 
19559  : m_type(value_t::array)
19560  {
19561  m_value.array = create<array_t>(cnt, val);
19562  set_parents();
19563  assert_invariant();
19564  }
19565 
19568  template < class InputIT, typename std::enable_if <
19569  std::is_same<InputIT, typename basic_json_t::iterator>::value ||
19570  std::is_same<InputIT, typename basic_json_t::const_iterator>::value, int >::type = 0 >
19571  basic_json(InputIT first, InputIT last)
19572  {
19573  JSON_ASSERT(first.m_object != nullptr);
19574  JSON_ASSERT(last.m_object != nullptr);
19575 
19576  // make sure iterator fits the current value
19577  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
19578  {
19579  JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
19580  }
19581 
19582  // copy type from first iterator
19583  m_type = first.m_object->m_type;
19584 
19585  // check if iterator range is complete for primitive values
19586  switch (m_type)
19587  {
19588  case value_t::boolean:
19589  case value_t::number_float:
19592  case value_t::string:
19593  {
19594  if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
19595  || !last.m_it.primitive_iterator.is_end()))
19596  {
19597  JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
19598  }
19599  break;
19600  }
19601 
19602  case value_t::null:
19603  case value_t::object:
19604  case value_t::array:
19605  case value_t::binary:
19606  case value_t::discarded:
19607  default:
19608  break;
19609  }
19610 
19611  switch (m_type)
19612  {
19614  {
19615  m_value.number_integer = first.m_object->m_value.number_integer;
19616  break;
19617  }
19618 
19620  {
19621  m_value.number_unsigned = first.m_object->m_value.number_unsigned;
19622  break;
19623  }
19624 
19625  case value_t::number_float:
19626  {
19627  m_value.number_float = first.m_object->m_value.number_float;
19628  break;
19629  }
19630 
19631  case value_t::boolean:
19632  {
19633  m_value.boolean = first.m_object->m_value.boolean;
19634  break;
19635  }
19636 
19637  case value_t::string:
19638  {
19639  m_value = *first.m_object->m_value.string;
19640  break;
19641  }
19642 
19643  case value_t::object:
19644  {
19645  m_value.object = create<object_t>(first.m_it.object_iterator,
19646  last.m_it.object_iterator);
19647  break;
19648  }
19649 
19650  case value_t::array:
19651  {
19652  m_value.array = create<array_t>(first.m_it.array_iterator,
19653  last.m_it.array_iterator);
19654  break;
19655  }
19656 
19657  case value_t::binary:
19658  {
19659  m_value = *first.m_object->m_value.binary;
19660  break;
19661  }
19662 
19663  case value_t::null:
19664  case value_t::discarded:
19665  default:
19666  JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
19667  }
19668 
19669  set_parents();
19670  assert_invariant();
19671  }
19672 
19673 
19675  // other constructors and destructor //
19677 
19678  template<typename JsonRef,
19680  std::is_same<typename JsonRef::value_type, basic_json>>::value, int> = 0 >
19681  basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
19682 
19685  basic_json(const basic_json& other)
19686  : m_type(other.m_type)
19687  {
19688  // check of passed value is valid
19689  other.assert_invariant();
19690 
19691  switch (m_type)
19692  {
19693  case value_t::object:
19694  {
19695  m_value = *other.m_value.object;
19696  break;
19697  }
19698 
19699  case value_t::array:
19700  {
19701  m_value = *other.m_value.array;
19702  break;
19703  }
19704 
19705  case value_t::string:
19706  {
19707  m_value = *other.m_value.string;
19708  break;
19709  }
19710 
19711  case value_t::boolean:
19712  {
19713  m_value = other.m_value.boolean;
19714  break;
19715  }
19716 
19718  {
19719  m_value = other.m_value.number_integer;
19720  break;
19721  }
19722 
19724  {
19725  m_value = other.m_value.number_unsigned;
19726  break;
19727  }
19728 
19729  case value_t::number_float:
19730  {
19731  m_value = other.m_value.number_float;
19732  break;
19733  }
19734 
19735  case value_t::binary:
19736  {
19737  m_value = *other.m_value.binary;
19738  break;
19739  }
19740 
19741  case value_t::null:
19742  case value_t::discarded:
19743  default:
19744  break;
19745  }
19746 
19747  set_parents();
19748  assert_invariant();
19749  }
19750 
19753  basic_json(basic_json&& other) noexcept
19754  : m_type(std::move(other.m_type)),
19755  m_value(std::move(other.m_value))
19756  {
19757  // check that passed value is valid
19758  other.assert_invariant(false);
19759 
19760  // invalidate payload
19761  other.m_type = value_t::null;
19762  other.m_value = {};
19763 
19764  set_parents();
19765  assert_invariant();
19766  }
19767 
19770  basic_json& operator=(basic_json other) noexcept (
19771  std::is_nothrow_move_constructible<value_t>::value&&
19772  std::is_nothrow_move_assignable<value_t>::value&&
19773  std::is_nothrow_move_constructible<json_value>::value&&
19774  std::is_nothrow_move_assignable<json_value>::value
19775  )
19776  {
19777  // check that passed value is valid
19778  other.assert_invariant();
19779 
19780  using std::swap;
19781  swap(m_type, other.m_type);
19782  swap(m_value, other.m_value);
19783 
19784  set_parents();
19785  assert_invariant();
19786  return *this;
19787  }
19788 
19791  ~basic_json() noexcept
19792  {
19793  assert_invariant(false);
19794  m_value.destroy(m_type);
19795  }
19796 
19798 
19799  public:
19801  // object inspection //
19803 
19807 
19810  string_t dump(const int indent = -1,
19811  const char indent_char = ' ',
19812  const bool ensure_ascii = false,
19813  const error_handler_t error_handler = error_handler_t::strict) const
19814  {
19815  string_t result;
19816  serializer s(detail::output_adapter<char, string_t>(result), indent_char, error_handler);
19817 
19818  if (indent >= 0)
19819  {
19820  s.dump(*this, true, ensure_ascii, static_cast<unsigned int>(indent));
19821  }
19822  else
19823  {
19824  s.dump(*this, false, ensure_ascii, 0);
19825  }
19826 
19827  return result;
19828  }
19829 
19832  constexpr value_t type() const noexcept
19833  {
19834  return m_type;
19835  }
19836 
19839  constexpr bool is_primitive() const noexcept
19840  {
19841  return is_null() || is_string() || is_boolean() || is_number() || is_binary();
19842  }
19843 
19846  constexpr bool is_structured() const noexcept
19847  {
19848  return is_array() || is_object();
19849  }
19850 
19853  constexpr bool is_null() const noexcept
19854  {
19855  return m_type == value_t::null;
19856  }
19857 
19860  constexpr bool is_boolean() const noexcept
19861  {
19862  return m_type == value_t::boolean;
19863  }
19864 
19867  constexpr bool is_number() const noexcept
19868  {
19869  return is_number_integer() || is_number_float();
19870  }
19871 
19874  constexpr bool is_number_integer() const noexcept
19875  {
19876  return m_type == value_t::number_integer || m_type == value_t::number_unsigned;
19877  }
19878 
19881  constexpr bool is_number_unsigned() const noexcept
19882  {
19883  return m_type == value_t::number_unsigned;
19884  }
19885 
19888  constexpr bool is_number_float() const noexcept
19889  {
19890  return m_type == value_t::number_float;
19891  }
19892 
19895  constexpr bool is_object() const noexcept
19896  {
19897  return m_type == value_t::object;
19898  }
19899 
19902  constexpr bool is_array() const noexcept
19903  {
19904  return m_type == value_t::array;
19905  }
19906 
19909  constexpr bool is_string() const noexcept
19910  {
19911  return m_type == value_t::string;
19912  }
19913 
19916  constexpr bool is_binary() const noexcept
19917  {
19918  return m_type == value_t::binary;
19919  }
19920 
19923  constexpr bool is_discarded() const noexcept
19924  {
19925  return m_type == value_t::discarded;
19926  }
19927 
19930  constexpr operator value_t() const noexcept
19931  {
19932  return m_type;
19933  }
19934 
19936 
19937  private:
19939  // value access //
19941 
19943  boolean_t get_impl(boolean_t* /*unused*/) const
19944  {
19946  {
19947  return m_value.boolean;
19948  }
19949 
19950  JSON_THROW(type_error::create(302, detail::concat("type must be boolean, but is ", type_name()), this));
19951  }
19952 
19954  object_t* get_impl_ptr(object_t* /*unused*/) noexcept
19955  {
19956  return is_object() ? m_value.object : nullptr;
19957  }
19958 
19960  constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const noexcept
19961  {
19962  return is_object() ? m_value.object : nullptr;
19963  }
19964 
19966  array_t* get_impl_ptr(array_t* /*unused*/) noexcept
19967  {
19968  return is_array() ? m_value.array : nullptr;
19969  }
19970 
19972  constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const noexcept
19973  {
19974  return is_array() ? m_value.array : nullptr;
19975  }
19976 
19978  string_t* get_impl_ptr(string_t* /*unused*/) noexcept
19979  {
19980  return is_string() ? m_value.string : nullptr;
19981  }
19982 
19984  constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const noexcept
19985  {
19986  return is_string() ? m_value.string : nullptr;
19987  }
19988 
19990  boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
19991  {
19992  return is_boolean() ? &m_value.boolean : nullptr;
19993  }
19994 
19996  constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) const noexcept
19997  {
19998  return is_boolean() ? &m_value.boolean : nullptr;
19999  }
20000 
20002  number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
20003  {
20004  return is_number_integer() ? &m_value.number_integer : nullptr;
20005  }
20006 
20008  constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
20009  {
20010  return is_number_integer() ? &m_value.number_integer : nullptr;
20011  }
20012 
20014  number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
20015  {
20016  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20017  }
20018 
20020  constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t* /*unused*/) const noexcept
20021  {
20022  return is_number_unsigned() ? &m_value.number_unsigned : nullptr;
20023  }
20024 
20026  number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
20027  {
20028  return is_number_float() ? &m_value.number_float : nullptr;
20029  }
20030 
20032  constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unused*/) const noexcept
20033  {
20034  return is_number_float() ? &m_value.number_float : nullptr;
20035  }
20036 
20038  binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
20039  {
20040  return is_binary() ? m_value.binary : nullptr;
20041  }
20042 
20044  constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const noexcept
20045  {
20046  return is_binary() ? m_value.binary : nullptr;
20047  }
20048 
20060  template<typename ReferenceType, typename ThisType>
20061  static ReferenceType get_ref_impl(ThisType& obj)
20062  {
20063  // delegate the call to get_ptr<>()
20064  auto* ptr = obj.template get_ptr<typename std::add_pointer<ReferenceType>::type>();
20065 
20066  if (JSON_HEDLEY_LIKELY(ptr != nullptr))
20067  {
20068  return *ptr;
20069  }
20070 
20071  JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
20072  }
20073 
20074  public:
20078 
20081  template<typename PointerType, typename std::enable_if<
20082  std::is_pointer<PointerType>::value, int>::type = 0>
20083  auto get_ptr() noexcept -> decltype(std::declval<basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20084  {
20085  // delegate the call to get_impl_ptr<>()
20086  return get_impl_ptr(static_cast<PointerType>(nullptr));
20087  }
20088 
20091  template < typename PointerType, typename std::enable_if <
20092  std::is_pointer<PointerType>::value&&
20094  constexpr auto get_ptr() const noexcept -> decltype(std::declval<const basic_json_t&>().get_impl_ptr(std::declval<PointerType>()))
20095  {
20096  // delegate the call to get_impl_ptr<>() const
20097  return get_impl_ptr(static_cast<PointerType>(nullptr));
20098  }
20099 
20100  private:
20139  template < typename ValueType,
20143  int > = 0 >
20144  ValueType get_impl(detail::priority_tag<0> /*unused*/) const noexcept(noexcept(
20145  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), std::declval<ValueType&>())))
20146  {
20147  auto ret = ValueType();
20149  return ret;
20150  }
20151 
20182  template < typename ValueType,
20184  detail::has_non_default_from_json<basic_json_t, ValueType>::value,
20185  int > = 0 >
20186  ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(noexcept(
20187  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>())))
20188  {
20190  }
20191 
20207  template < typename BasicJsonType,
20209  detail::is_basic_json<BasicJsonType>::value,
20210  int > = 0 >
20211  BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
20212  {
20213  return *this;
20214  }
20215 
20230  template<typename BasicJsonType,
20232  std::is_same<BasicJsonType, basic_json_t>::value,
20233  int> = 0>
20234  basic_json get_impl(detail::priority_tag<3> /*unused*/) const
20235  {
20236  return *this;
20237  }
20238 
20243  template<typename PointerType,
20245  std::is_pointer<PointerType>::value,
20246  int> = 0>
20247  constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
20248  -> decltype(std::declval<const basic_json_t&>().template get_ptr<PointerType>())
20249  {
20250  // delegate the call to get_ptr
20251  return get_ptr<PointerType>();
20252  }
20253 
20254  public:
20278  template < typename ValueTypeCV, typename ValueType = detail::uncvref_t<ValueTypeCV>>
20279 #if defined(JSON_HAS_CPP_14)
20280  constexpr
20281 #endif
20282  auto get() const noexcept(
20283  noexcept(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {})))
20284  -> decltype(std::declval<const basic_json_t&>().template get_impl<ValueType>(detail::priority_tag<4> {}))
20285  {
20286  // we cannot static_assert on ValueTypeCV being non-const, because
20287  // there is support for get<const basic_json_t>(), which is why we
20288  // still need the uncvref
20289  static_assert(!std::is_reference<ValueTypeCV>::value,
20290  "get() cannot be used with reference types, you might want to use get_ref()");
20291  return get_impl<ValueType>(detail::priority_tag<4> {});
20292  }
20293 
20321  template<typename PointerType, typename std::enable_if<
20322  std::is_pointer<PointerType>::value, int>::type = 0>
20323  auto get() noexcept -> decltype(std::declval<basic_json_t&>().template get_ptr<PointerType>())
20324  {
20325  // delegate the call to get_ptr
20326  return get_ptr<PointerType>();
20327  }
20328 
20331  template < typename ValueType,
20335  int > = 0 >
20336  ValueType & get_to(ValueType& v) const noexcept(noexcept(
20337  JSONSerializer<ValueType>::from_json(std::declval<const basic_json_t&>(), v)))
20338  {
20340  return v;
20341  }
20342 
20343  // specialization to allow calling get_to with a basic_json value
20344  // see https://github.com/nlohmann/json/issues/2175
20345  template<typename ValueType,
20348  int> = 0>
20349  ValueType & get_to(ValueType& v) const
20350  {
20351  v = *this;
20352  return v;
20353  }
20354 
20355  template <
20356  typename T, std::size_t N,
20357  typename Array = T (&)[N], // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20360  Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
20361  noexcept(noexcept(JSONSerializer<Array>::from_json(
20362  std::declval<const basic_json_t&>(), v)))
20363  {
20365  return v;
20366  }
20367 
20370  template<typename ReferenceType, typename std::enable_if<
20371  std::is_reference<ReferenceType>::value, int>::type = 0>
20372  ReferenceType get_ref()
20373  {
20374  // delegate call to get_ref_impl
20375  return get_ref_impl<ReferenceType>(*this);
20376  }
20377 
20380  template < typename ReferenceType, typename std::enable_if <
20381  std::is_reference<ReferenceType>::value&&
20383  ReferenceType get_ref() const
20384  {
20385  // delegate call to get_ref_impl
20386  return get_ref_impl<ReferenceType>(*this);
20387  }
20388 
20418  template < typename ValueType, typename std::enable_if <
20426 #if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
20428 #endif
20429 #if defined(JSON_HAS_CPP_17)
20431 #endif
20433  >::value, int >::type = 0 >
20434  JSON_EXPLICIT operator ValueType() const
20435  {
20436  // delegate the call to get<>() const
20437  return get<ValueType>();
20438  }
20439 
20443  {
20444  if (!is_binary())
20445  {
20446  JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
20447  }
20448 
20449  return *get_ptr<binary_t*>();
20450  }
20451 
20454  const binary_t& get_binary() const
20455  {
20456  if (!is_binary())
20457  {
20458  JSON_THROW(type_error::create(302, detail::concat("type must be binary, but is ", type_name()), this));
20459  }
20460 
20461  return *get_ptr<const binary_t*>();
20462  }
20463 
20465 
20466 
20468  // element access //
20470 
20474 
20478  {
20479  // at only works for arrays
20481  {
20482  JSON_TRY
20483  {
20484  return set_parent(m_value.array->at(idx));
20485  }
20486  JSON_CATCH (std::out_of_range&)
20487  {
20488  // create better exception explanation
20489  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
20490  }
20491  }
20492  else
20493  {
20494  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20495  }
20496  }
20497 
20501  {
20502  // at only works for arrays
20504  {
20505  JSON_TRY
20506  {
20507  return m_value.array->at(idx);
20508  }
20509  JSON_CATCH (std::out_of_range&)
20510  {
20511  // create better exception explanation
20512  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
20513  }
20514  }
20515  else
20516  {
20517  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20518  }
20519  }
20520 
20523  reference at(const typename object_t::key_type& key)
20524  {
20525  // at only works for objects
20527  {
20528  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20529  }
20530 
20531  auto it = m_value.object->find(key);
20532  if (it == m_value.object->end())
20533  {
20534  JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
20535  }
20536  return set_parent(it->second);
20537  }
20538 
20541  template<class KeyType, detail::enable_if_t<
20543  reference at(KeyType && key)
20544  {
20545  // at only works for objects
20547  {
20548  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20549  }
20550 
20551  auto it = m_value.object->find(std::forward<KeyType>(key));
20552  if (it == m_value.object->end())
20553  {
20554  JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
20555  }
20556  return set_parent(it->second);
20557  }
20558 
20561  const_reference at(const typename object_t::key_type& key) const
20562  {
20563  // at only works for objects
20565  {
20566  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20567  }
20568 
20569  auto it = m_value.object->find(key);
20570  if (it == m_value.object->end())
20571  {
20572  JSON_THROW(out_of_range::create(403, detail::concat("key '", key, "' not found"), this));
20573  }
20574  return it->second;
20575  }
20576 
20579  template<class KeyType, detail::enable_if_t<
20581  const_reference at(KeyType && key) const
20582  {
20583  // at only works for objects
20585  {
20586  JSON_THROW(type_error::create(304, detail::concat("cannot use at() with ", type_name()), this));
20587  }
20588 
20589  auto it = m_value.object->find(std::forward<KeyType>(key));
20590  if (it == m_value.object->end())
20591  {
20592  JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(std::forward<KeyType>(key)), "' not found"), this));
20593  }
20594  return it->second;
20595  }
20596 
20600  {
20601  // implicitly convert null value to an empty array
20602  if (is_null())
20603  {
20604  m_type = value_t::array;
20605  m_value.array = create<array_t>();
20606  assert_invariant();
20607  }
20608 
20609  // operator[] only works for arrays
20611  {
20612  // fill up array with null values if given idx is outside range
20613  if (idx >= m_value.array->size())
20614  {
20615 #if JSON_DIAGNOSTICS
20616  // remember array size & capacity before resizing
20617  const auto old_size = m_value.array->size();
20618  const auto old_capacity = m_value.array->capacity();
20619 #endif
20620  m_value.array->resize(idx + 1);
20621 
20622 #if JSON_DIAGNOSTICS
20623  if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity))
20624  {
20625  // capacity has changed: update all parents
20626  set_parents();
20627  }
20628  else
20629  {
20630  // set parent for values added above
20631  set_parents(begin() + static_cast<typename iterator::difference_type>(old_size), static_cast<typename iterator::difference_type>(idx + 1 - old_size));
20632  }
20633 #endif
20634  assert_invariant();
20635  }
20636 
20637  return m_value.array->operator[](idx);
20638  }
20639 
20640  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
20641  }
20642 
20646  {
20647  // const operator[] only works for arrays
20649  {
20650  return m_value.array->operator[](idx);
20651  }
20652 
20653  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a numeric argument with ", type_name()), this));
20654  }
20655 
20658  reference operator[](typename object_t::key_type key)
20659  {
20660  // implicitly convert null value to an empty object
20661  if (is_null())
20662  {
20663  m_type = value_t::object;
20664  m_value.object = create<object_t>();
20665  assert_invariant();
20666  }
20667 
20668  // operator[] only works for objects
20670  {
20671  auto result = m_value.object->emplace(std::move(key), nullptr);
20672  return set_parent(result.first->second);
20673  }
20674 
20675  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20676  }
20677 
20680  const_reference operator[](const typename object_t::key_type& key) const
20681  {
20682  // const operator[] only works for objects
20684  {
20685  auto it = m_value.object->find(key);
20686  JSON_ASSERT(it != m_value.object->end());
20687  return it->second;
20688  }
20689 
20690  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20691  }
20692 
20693  // these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
20694  // (they seemingly cannot be constrained to resolve the ambiguity)
20695  template<typename T>
20697  {
20698  return operator[](typename object_t::key_type(key));
20699  }
20700 
20701  template<typename T>
20703  {
20704  return operator[](typename object_t::key_type(key));
20705  }
20706 
20709  template<class KeyType, detail::enable_if_t<
20711  reference operator[](KeyType && key)
20712  {
20713  // implicitly convert null value to an empty object
20714  if (is_null())
20715  {
20716  m_type = value_t::object;
20717  m_value.object = create<object_t>();
20718  assert_invariant();
20719  }
20720 
20721  // operator[] only works for objects
20723  {
20724  auto result = m_value.object->emplace(std::forward<KeyType>(key), nullptr);
20725  return set_parent(result.first->second);
20726  }
20727 
20728  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20729  }
20730 
20733  template<class KeyType, detail::enable_if_t<
20735  const_reference operator[](KeyType && key) const
20736  {
20737  // const operator[] only works for objects
20739  {
20740  auto it = m_value.object->find(std::forward<KeyType>(key));
20741  JSON_ASSERT(it != m_value.object->end());
20742  return it->second;
20743  }
20744 
20745  JSON_THROW(type_error::create(305, detail::concat("cannot use operator[] with a string argument with ", type_name()), this));
20746  }
20747 
20750  // this is the value(const typename object_t::key_type&) overload
20751  template < class KeyType, class ValueType, detail::enable_if_t <
20752  std::is_same<KeyType, typename object_t::key_type>::value
20754  && !std::is_same<value_t, ValueType>::value, int > = 0 >
20755  typename std::decay<ValueType>::type value(const KeyType& key, ValueType && default_value) const
20756  {
20757  // value only works for objects
20759  {
20760  // if key is found, return value and given default value otherwise
20761  const auto it = find(key);
20762  if (it != end())
20763  {
20764  return it->template get<typename std::decay<ValueType>::type>();
20765  }
20766 
20767  return std::forward<ValueType>(default_value);
20768  }
20769 
20770  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
20771  }
20772 
20776  string_t value(const typename object_t::key_type& key, const char* default_value) const
20777  {
20778  return value(key, string_t(default_value));
20779  }
20780 
20781  // these two functions, in conjunction with value(const KeyType &, ValueType &&),
20782  // resolve an ambiguity that would otherwise occur between the json_pointer and
20783  // typename object_t::key_type & overloads
20784  template < class ValueType, detail::enable_if_t <
20786  && !std::is_same<value_t, ValueType>::value, int > = 0 >
20787  typename std::decay<ValueType>::type value(const char* key, ValueType && default_value) const
20788  {
20789  return value(typename object_t::key_type(key), std::forward<ValueType>(default_value));
20790  }
20791 
20792  string_t value(const char* key, const char* default_value) const
20793  {
20794  return value(typename object_t::key_type(key), string_t(default_value));
20795  }
20796 
20800  template < class KeyType, class ValueType, detail::enable_if_t <
20802  && !std::is_same<value_t, ValueType>::value
20804  typename std::decay<ValueType>::type value(KeyType && key, ValueType && default_value) const
20805  {
20806  // value only works for objects
20808  {
20809  // if key is found, return value and given default value otherwise
20810  const auto it = find(std::forward<KeyType>(key));
20811  if (it != end())
20812  {
20813  return it->template get<typename std::decay<ValueType>::type>();
20814  }
20815 
20816  return std::forward<ValueType>(default_value);
20817  }
20818 
20819  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
20820  }
20821 
20825  template < class KeyType, detail::enable_if_t <
20827  string_t value(KeyType && key, const char* default_value) const
20828  {
20829  return value(std::forward<KeyType>(key), string_t(default_value));
20830  }
20831 
20834  template < class ValueType, detail::enable_if_t <
20836  ValueType value(const json_pointer& ptr, const ValueType& default_value) const
20837  {
20838  // value only works for objects
20840  {
20841  // if pointer resolves a value, return it or use default value
20842  JSON_TRY
20843  {
20844  return ptr.get_checked(this).template get<ValueType>();
20845  }
20847  {
20848  return default_value;
20849  }
20850  }
20851 
20852  JSON_THROW(type_error::create(306, detail::concat("cannot use value() with ", type_name()), this));
20853  }
20854 
20855  template < class ValueType, class BasicJsonType, detail::enable_if_t <
20858  ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, const ValueType& default_value) const
20859  {
20860  return value(ptr.convert(), default_value);
20861  }
20862 
20867  string_t value(const json_pointer& ptr, const char* default_value) const
20868  {
20869  return value(ptr, string_t(default_value));
20870  }
20871 
20872  template<typename BasicJsonType>
20875  string_t value(const typename ::nlohmann::json_pointer<BasicJsonType>& ptr, const char* default_value) const
20876  {
20877  return value(ptr.convert(), default_value);
20878  }
20879 
20882  reference front()
20883  {
20884  return *begin();
20885  }
20886 
20890  {
20891  return *cbegin();
20892  }
20893 
20897  {
20898  auto tmp = end();
20899  --tmp;
20900  return *tmp;
20901  }
20902 
20906  {
20907  auto tmp = cend();
20908  --tmp;
20909  return *tmp;
20910  }
20911 
20914  template < class IteratorType, detail::enable_if_t <
20915  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20916  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
20917  IteratorType erase(IteratorType pos)
20918  {
20919  // make sure iterator fits the current value
20920  if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
20921  {
20922  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
20923  }
20924 
20925  IteratorType result = end();
20926 
20927  switch (m_type)
20928  {
20929  case value_t::boolean:
20930  case value_t::number_float:
20933  case value_t::string:
20934  case value_t::binary:
20935  {
20936  if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
20937  {
20938  JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
20939  }
20940 
20941  if (is_string())
20942  {
20943  AllocatorType<string_t> alloc;
20944  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
20945  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
20946  m_value.string = nullptr;
20947  }
20948  else if (is_binary())
20949  {
20950  AllocatorType<binary_t> alloc;
20951  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
20952  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
20953  m_value.binary = nullptr;
20954  }
20955 
20956  m_type = value_t::null;
20957  assert_invariant();
20958  break;
20959  }
20960 
20961  case value_t::object:
20962  {
20963  result.m_it.object_iterator = m_value.object->erase(pos.m_it.object_iterator);
20964  break;
20965  }
20966 
20967  case value_t::array:
20968  {
20969  result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
20970  break;
20971  }
20972 
20973  case value_t::null:
20974  case value_t::discarded:
20975  default:
20976  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
20977  }
20978 
20979  return result;
20980  }
20981 
20984  template < class IteratorType, detail::enable_if_t <
20985  std::is_same<IteratorType, typename basic_json_t::iterator>::value ||
20986  std::is_same<IteratorType, typename basic_json_t::const_iterator>::value, int > = 0 >
20987  IteratorType erase(IteratorType first, IteratorType last)
20988  {
20989  // make sure iterator fits the current value
20990  if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
20991  {
20992  JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
20993  }
20994 
20995  IteratorType result = end();
20996 
20997  switch (m_type)
20998  {
20999  case value_t::boolean:
21000  case value_t::number_float:
21003  case value_t::string:
21004  case value_t::binary:
21005  {
21006  if (JSON_HEDLEY_LIKELY(!first.m_it.primitive_iterator.is_begin()
21007  || !last.m_it.primitive_iterator.is_end()))
21008  {
21009  JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
21010  }
21011 
21012  if (is_string())
21013  {
21014  AllocatorType<string_t> alloc;
21015  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.string);
21016  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.string, 1);
21017  m_value.string = nullptr;
21018  }
21019  else if (is_binary())
21020  {
21021  AllocatorType<binary_t> alloc;
21022  std::allocator_traits<decltype(alloc)>::destroy(alloc, m_value.binary);
21023  std::allocator_traits<decltype(alloc)>::deallocate(alloc, m_value.binary, 1);
21024  m_value.binary = nullptr;
21025  }
21026 
21027  m_type = value_t::null;
21028  assert_invariant();
21029  break;
21030  }
21031 
21032  case value_t::object:
21033  {
21034  result.m_it.object_iterator = m_value.object->erase(first.m_it.object_iterator,
21035  last.m_it.object_iterator);
21036  break;
21037  }
21038 
21039  case value_t::array:
21040  {
21041  result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
21042  last.m_it.array_iterator);
21043  break;
21044  }
21045 
21046  case value_t::null:
21047  case value_t::discarded:
21048  default:
21049  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21050  }
21051 
21052  return result;
21053  }
21054 
21055  private:
21056  template < typename KeyType, detail::enable_if_t <
21058  size_type erase_internal(KeyType && key)
21059  {
21060  // this erase only works for objects
21062  {
21063  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21064  }
21065 
21066  return m_value.object->erase(std::forward<KeyType>(key));
21067  }
21068 
21069  template < typename KeyType, detail::enable_if_t <
21070  !detail::has_erase_with_key_type<basic_json_t, KeyType>::value, int > = 0 >
21071  size_type erase_internal(KeyType && key)
21072  {
21073  // this erase only works for objects
21075  {
21076  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21077  }
21078 
21079  const auto it = m_value.object->find(std::forward<KeyType>(key));
21080  if (it != m_value.object->end())
21081  {
21082  m_value.object->erase(it);
21083  return 1;
21084  }
21085  return 0;
21086  }
21087 
21088  public:
21089 
21092  size_type erase(const typename object_t::key_type& key)
21093  {
21094  // the indirection via erase_internal() is added to avoid making this
21095  // function a template and thus de-rank it during overload resolution
21096  return erase_internal(key);
21097  }
21098 
21101  template<class KeyType, detail::enable_if_t<
21103  size_type erase(KeyType && key)
21104  {
21105  return erase_internal(std::forward<KeyType>(key));
21106  }
21107 
21110  void erase(const size_type idx)
21111  {
21112  // this erase only works for arrays
21114  {
21115  if (JSON_HEDLEY_UNLIKELY(idx >= size()))
21116  {
21117  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
21118  }
21119 
21120  m_value.array->erase(m_value.array->begin() + static_cast<difference_type>(idx));
21121  }
21122  else
21123  {
21124  JSON_THROW(type_error::create(307, detail::concat("cannot use erase() with ", type_name()), this));
21125  }
21126  }
21127 
21129 
21130 
21132  // lookup //
21134 
21137 
21140  iterator find(const typename object_t::key_type& key)
21141  {
21142  auto result = end();
21143 
21144  if (is_object())
21145  {
21146  result.m_it.object_iterator = m_value.object->find(key);
21147  }
21148 
21149  return result;
21150  }
21151 
21154  const_iterator find(const typename object_t::key_type& key) const
21155  {
21156  auto result = cend();
21157 
21158  if (is_object())
21159  {
21160  result.m_it.object_iterator = m_value.object->find(key);
21161  }
21162 
21163  return result;
21164  }
21165 
21168  template<class KeyType, detail::enable_if_t<
21170  iterator find(KeyType && key)
21171  {
21172  auto result = end();
21173 
21174  if (is_object())
21175  {
21176  result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
21177  }
21178 
21179  return result;
21180  }
21181 
21184  template<class KeyType, detail::enable_if_t<
21186  const_iterator find(KeyType && key) const
21187  {
21188  auto result = cend();
21189 
21190  if (is_object())
21191  {
21192  result.m_it.object_iterator = m_value.object->find(std::forward<KeyType>(key));
21193  }
21194 
21195  return result;
21196  }
21197 
21200  size_type count(const typename object_t::key_type& key) const
21201  {
21202  // return 0 for all nonobject types
21203  return is_object() ? m_value.object->count(key) : 0;
21204  }
21205 
21208  template<class KeyType, detail::enable_if_t<
21210  size_type count(KeyType && key) const
21211  {
21212  // return 0 for all nonobject types
21213  return is_object() ? m_value.object->count(std::forward<KeyType>(key)) : 0;
21214  }
21215 
21218  bool contains(const typename object_t::key_type& key) const
21219  {
21220  return is_object() && m_value.object->find(key) != m_value.object->end();
21221  }
21222 
21225  template<class KeyType, detail::enable_if_t<
21227  bool contains(KeyType && key) const
21228  {
21229  return is_object() && m_value.object->find(std::forward<KeyType>(key)) != m_value.object->end();
21230  }
21231 
21234  bool contains(const json_pointer& ptr) const
21235  {
21236  return ptr.contains(this);
21237  }
21238 
21239  template<typename BasicJsonType>
21241  bool contains(const typename ::nlohmann::json_pointer<BasicJsonType> ptr) const
21242  {
21243  return ptr.contains(this);
21244  }
21245 
21247 
21248 
21250  // iterators //
21252 
21255 
21258  iterator begin() noexcept
21259  {
21260  iterator result(this);
21261  result.set_begin();
21262  return result;
21263  }
21264 
21267  const_iterator begin() const noexcept
21268  {
21269  return cbegin();
21270  }
21271 
21274  const_iterator cbegin() const noexcept
21275  {
21276  const_iterator result(this);
21277  result.set_begin();
21278  return result;
21279  }
21280 
21283  iterator end() noexcept
21284  {
21285  iterator result(this);
21286  result.set_end();
21287  return result;
21288  }
21289 
21292  const_iterator end() const noexcept
21293  {
21294  return cend();
21295  }
21296 
21299  const_iterator cend() const noexcept
21300  {
21301  const_iterator result(this);
21302  result.set_end();
21303  return result;
21304  }
21305 
21308  reverse_iterator rbegin() noexcept
21309  {
21310  return reverse_iterator(end());
21311  }
21312 
21315  const_reverse_iterator rbegin() const noexcept
21316  {
21317  return crbegin();
21318  }
21319 
21322  reverse_iterator rend() noexcept
21323  {
21324  return reverse_iterator(begin());
21325  }
21326 
21329  const_reverse_iterator rend() const noexcept
21330  {
21331  return crend();
21332  }
21333 
21336  const_reverse_iterator crbegin() const noexcept
21337  {
21338  return const_reverse_iterator(cend());
21339  }
21340 
21343  const_reverse_iterator crend() const noexcept
21344  {
21345  return const_reverse_iterator(cbegin());
21346  }
21347 
21348  public:
21354  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21355  static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
21356  {
21357  return ref.items();
21358  }
21359 
21365  JSON_HEDLEY_DEPRECATED_FOR(3.1.0, items())
21366  static iteration_proxy<const_iterator> iterator_wrapper(const_reference ref) noexcept
21367  {
21368  return ref.items();
21369  }
21370 
21373  iteration_proxy<iterator> items() noexcept
21374  {
21375  return iteration_proxy<iterator>(*this);
21376  }
21377 
21380  iteration_proxy<const_iterator> items() const noexcept
21381  {
21382  return iteration_proxy<const_iterator>(*this);
21383  }
21384 
21386 
21387 
21389  // capacity //
21391 
21394 
21397  bool empty() const noexcept
21398  {
21399  switch (m_type)
21400  {
21401  case value_t::null:
21402  {
21403  // null values are empty
21404  return true;
21405  }
21406 
21407  case value_t::array:
21408  {
21409  // delegate call to array_t::empty()
21410  return m_value.array->empty();
21411  }
21412 
21413  case value_t::object:
21414  {
21415  // delegate call to object_t::empty()
21416  return m_value.object->empty();
21417  }
21418 
21419  case value_t::string:
21420  case value_t::boolean:
21423  case value_t::number_float:
21424  case value_t::binary:
21425  case value_t::discarded:
21426  default:
21427  {
21428  // all other types are nonempty
21429  return false;
21430  }
21431  }
21432  }
21433 
21436  size_type size() const noexcept
21437  {
21438  switch (m_type)
21439  {
21440  case value_t::null:
21441  {
21442  // null values are empty
21443  return 0;
21444  }
21445 
21446  case value_t::array:
21447  {
21448  // delegate call to array_t::size()
21449  return m_value.array->size();
21450  }
21451 
21452  case value_t::object:
21453  {
21454  // delegate call to object_t::size()
21455  return m_value.object->size();
21456  }
21457 
21458  case value_t::string:
21459  case value_t::boolean:
21462  case value_t::number_float:
21463  case value_t::binary:
21464  case value_t::discarded:
21465  default:
21466  {
21467  // all other types have size 1
21468  return 1;
21469  }
21470  }
21471  }
21472 
21475  size_type max_size() const noexcept
21476  {
21477  switch (m_type)
21478  {
21479  case value_t::array:
21480  {
21481  // delegate call to array_t::max_size()
21482  return m_value.array->max_size();
21483  }
21484 
21485  case value_t::object:
21486  {
21487  // delegate call to object_t::max_size()
21488  return m_value.object->max_size();
21489  }
21490 
21491  case value_t::null:
21492  case value_t::string:
21493  case value_t::boolean:
21496  case value_t::number_float:
21497  case value_t::binary:
21498  case value_t::discarded:
21499  default:
21500  {
21501  // all other types have max_size() == size()
21502  return size();
21503  }
21504  }
21505  }
21506 
21508 
21509 
21511  // modifiers //
21513 
21516 
21519  void clear() noexcept
21520  {
21521  switch (m_type)
21522  {
21524  {
21525  m_value.number_integer = 0;
21526  break;
21527  }
21528 
21530  {
21531  m_value.number_unsigned = 0;
21532  break;
21533  }
21534 
21535  case value_t::number_float:
21536  {
21537  m_value.number_float = 0.0;
21538  break;
21539  }
21540 
21541  case value_t::boolean:
21542  {
21543  m_value.boolean = false;
21544  break;
21545  }
21546 
21547  case value_t::string:
21548  {
21549  m_value.string->clear();
21550  break;
21551  }
21552 
21553  case value_t::binary:
21554  {
21555  m_value.binary->clear();
21556  break;
21557  }
21558 
21559  case value_t::array:
21560  {
21561  m_value.array->clear();
21562  break;
21563  }
21564 
21565  case value_t::object:
21566  {
21567  m_value.object->clear();
21568  break;
21569  }
21570 
21571  case value_t::null:
21572  case value_t::discarded:
21573  default:
21574  break;
21575  }
21576  }
21577 
21580  void push_back(basic_json&& val)
21581  {
21582  // push_back only works for null objects or arrays
21583  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21584  {
21585  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
21586  }
21587 
21588  // transform null object into an array
21589  if (is_null())
21590  {
21591  m_type = value_t::array;
21593  assert_invariant();
21594  }
21595 
21596  // add element to array (move semantics)
21597  const auto old_capacity = m_value.array->capacity();
21598  m_value.array->push_back(std::move(val));
21599  set_parent(m_value.array->back(), old_capacity);
21600  // if val is moved from, basic_json move constructor marks it null, so we do not call the destructor
21601  }
21602 
21606  {
21607  push_back(std::move(val));
21608  return *this;
21609  }
21610 
21613  void push_back(const basic_json& val)
21614  {
21615  // push_back only works for null objects or arrays
21616  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21617  {
21618  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
21619  }
21620 
21621  // transform null object into an array
21622  if (is_null())
21623  {
21624  m_type = value_t::array;
21626  assert_invariant();
21627  }
21628 
21629  // add element to array
21630  const auto old_capacity = m_value.array->capacity();
21631  m_value.array->push_back(val);
21632  set_parent(m_value.array->back(), old_capacity);
21633  }
21634 
21638  {
21639  push_back(val);
21640  return *this;
21641  }
21642 
21645  void push_back(const typename object_t::value_type& val)
21646  {
21647  // push_back only works for null objects or objects
21648  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21649  {
21650  JSON_THROW(type_error::create(308, detail::concat("cannot use push_back() with ", type_name()), this));
21651  }
21652 
21653  // transform null object into an object
21654  if (is_null())
21655  {
21656  m_type = value_t::object;
21658  assert_invariant();
21659  }
21660 
21661  // add element to object
21662  auto res = m_value.object->insert(val);
21663  set_parent(res.first->second);
21664  }
21665 
21668  reference operator+=(const typename object_t::value_type& val)
21669  {
21670  push_back(val);
21671  return *this;
21672  }
21673 
21677  {
21678  if (is_object() && init.size() == 2 && (*init.begin())->is_string())
21679  {
21680  basic_json&& key = init.begin()->moved_or_copied();
21681  push_back(typename object_t::value_type(
21682  std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
21683  }
21684  else
21685  {
21686  push_back(basic_json(init));
21687  }
21688  }
21689 
21693  {
21694  push_back(init);
21695  return *this;
21696  }
21697 
21700  template<class... Args>
21701  reference emplace_back(Args&& ... args)
21702  {
21703  // emplace_back only works for null objects or arrays
21704  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
21705  {
21706  JSON_THROW(type_error::create(311, detail::concat("cannot use emplace_back() with ", type_name()), this));
21707  }
21708 
21709  // transform null object into an array
21710  if (is_null())
21711  {
21712  m_type = value_t::array;
21714  assert_invariant();
21715  }
21716 
21717  // add element to array (perfect forwarding)
21718  const auto old_capacity = m_value.array->capacity();
21719  m_value.array->emplace_back(std::forward<Args>(args)...);
21720  return set_parent(m_value.array->back(), old_capacity);
21721  }
21722 
21725  template<class... Args>
21726  std::pair<iterator, bool> emplace(Args&& ... args)
21727  {
21728  // emplace only works for null objects or arrays
21729  if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
21730  {
21731  JSON_THROW(type_error::create(311, detail::concat("cannot use emplace() with ", type_name()), this));
21732  }
21733 
21734  // transform null object into an object
21735  if (is_null())
21736  {
21737  m_type = value_t::object;
21739  assert_invariant();
21740  }
21741 
21742  // add element to array (perfect forwarding)
21743  auto res = m_value.object->emplace(std::forward<Args>(args)...);
21744  set_parent(res.first->second);
21745 
21746  // create result iterator and set iterator to the result of emplace
21747  auto it = begin();
21748  it.m_it.object_iterator = res.first;
21749 
21750  // return pair of iterator and boolean
21751  return {it, res.second};
21752  }
21753 
21757  template<typename... Args>
21759  {
21760  iterator result(this);
21761  JSON_ASSERT(m_value.array != nullptr);
21762 
21763  auto insert_pos = std::distance(m_value.array->begin(), pos.m_it.array_iterator);
21764  m_value.array->insert(pos.m_it.array_iterator, std::forward<Args>(args)...);
21765  result.m_it.array_iterator = m_value.array->begin() + insert_pos;
21766 
21767  // This could have been written as:
21768  // result.m_it.array_iterator = m_value.array->insert(pos.m_it.array_iterator, cnt, val);
21769  // but the return value of insert is missing in GCC 4.8, so it is written this way instead.
21770 
21771  set_parents();
21772  return result;
21773  }
21774 
21778  {
21779  // insert only works for arrays
21781  {
21782  // check if iterator pos fits to this JSON value
21783  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21784  {
21785  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21786  }
21787 
21788  // insert to array and return iterator
21789  return insert_iterator(pos, val);
21790  }
21791 
21792  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21793  }
21794 
21798  {
21799  return insert(pos, val);
21800  }
21801 
21805  {
21806  // insert only works for arrays
21808  {
21809  // check if iterator pos fits to this JSON value
21810  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21811  {
21812  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21813  }
21814 
21815  // insert to array and return iterator
21816  return insert_iterator(pos, cnt, val);
21817  }
21818 
21819  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21820  }
21821 
21825  {
21826  // insert only works for arrays
21828  {
21829  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21830  }
21831 
21832  // check if iterator pos fits to this JSON value
21833  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21834  {
21835  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21836  }
21837 
21838  // check if range iterators belong to the same JSON object
21839  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21840  {
21841  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
21842  }
21843 
21844  if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
21845  {
21846  JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
21847  }
21848 
21849  // insert to array and return iterator
21850  return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
21851  }
21852 
21856  {
21857  // insert only works for arrays
21859  {
21860  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21861  }
21862 
21863  // check if iterator pos fits to this JSON value
21864  if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
21865  {
21866  JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
21867  }
21868 
21869  // insert to array and return iterator
21870  return insert_iterator(pos, ilist.begin(), ilist.end());
21871  }
21872 
21876  {
21877  // insert only works for objects
21879  {
21880  JSON_THROW(type_error::create(309, detail::concat("cannot use insert() with ", type_name()), this));
21881  }
21882 
21883  // check if range iterators belong to the same JSON object
21884  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21885  {
21886  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
21887  }
21888 
21889  // passed iterators must belong to objects
21890  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
21891  {
21892  JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
21893  }
21894 
21895  m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
21896  }
21897 
21900  void update(const_reference j, bool merge_objects = false)
21901  {
21902  update(j.begin(), j.end(), merge_objects);
21903  }
21904 
21907  void update(const_iterator first, const_iterator last, bool merge_objects = false)
21908  {
21909  // implicitly convert null value to an empty object
21910  if (is_null())
21911  {
21912  m_type = value_t::object;
21913  m_value.object = create<object_t>();
21914  assert_invariant();
21915  }
21916 
21918  {
21919  JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", type_name()), this));
21920  }
21921 
21922  // check if range iterators belong to the same JSON object
21923  if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
21924  {
21925  JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
21926  }
21927 
21928  // passed iterators must belong to objects
21929  if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
21930  {
21931  JSON_THROW(type_error::create(312, detail::concat("cannot use update() with ", first.m_object->type_name()), first.m_object));
21932  }
21933 
21934  for (auto it = first; it != last; ++it)
21935  {
21936  if (merge_objects && it.value().is_object())
21937  {
21938  auto it2 = m_value.object->find(it.key());
21939  if (it2 != m_value.object->end())
21940  {
21941  it2->second.update(it.value(), true);
21942  continue;
21943  }
21944  }
21945  m_value.object->operator[](it.key()) = it.value();
21946 #if JSON_DIAGNOSTICS
21947  m_value.object->operator[](it.key()).m_parent = this;
21948 #endif
21949  }
21950  }
21951 
21954  void swap(reference other) noexcept (
21955  std::is_nothrow_move_constructible<value_t>::value&&
21956  std::is_nothrow_move_assignable<value_t>::value&&
21957  std::is_nothrow_move_constructible<json_value>::value&&
21958  std::is_nothrow_move_assignable<json_value>::value
21959  )
21960  {
21961  std::swap(m_type, other.m_type);
21962  std::swap(m_value, other.m_value);
21963 
21964  set_parents();
21965  other.set_parents();
21966  assert_invariant();
21967  }
21968 
21971  friend void swap(reference left, reference right) noexcept (
21972  std::is_nothrow_move_constructible<value_t>::value&&
21973  std::is_nothrow_move_assignable<value_t>::value&&
21974  std::is_nothrow_move_constructible<json_value>::value&&
21975  std::is_nothrow_move_assignable<json_value>::value
21976  )
21977  {
21978  left.swap(right);
21979  }
21980 
21983  void swap(array_t& other) // NOLINT(bugprone-exception-escape)
21984  {
21985  // swap only works for arrays
21987  {
21988  std::swap(*(m_value.array), other);
21989  }
21990  else
21991  {
21992  JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
21993  }
21994  }
21995 
21998  void swap(object_t& other) // NOLINT(bugprone-exception-escape)
21999  {
22000  // swap only works for objects
22002  {
22003  std::swap(*(m_value.object), other);
22004  }
22005  else
22006  {
22007  JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
22008  }
22009  }
22010 
22013  void swap(string_t& other) // NOLINT(bugprone-exception-escape)
22014  {
22015  // swap only works for strings
22017  {
22018  std::swap(*(m_value.string), other);
22019  }
22020  else
22021  {
22022  JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
22023  }
22024  }
22025 
22028  void swap(binary_t& other) // NOLINT(bugprone-exception-escape)
22029  {
22030  // swap only works for strings
22032  {
22033  std::swap(*(m_value.binary), other);
22034  }
22035  else
22036  {
22037  JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
22038  }
22039  }
22040 
22043  void swap(typename binary_t::container_type& other) // NOLINT(bugprone-exception-escape)
22044  {
22045  // swap only works for strings
22047  {
22048  std::swap(*(m_value.binary), other);
22049  }
22050  else
22051  {
22052  JSON_THROW(type_error::create(310, detail::concat("cannot use swap() with ", type_name()), this));
22053  }
22054  }
22055 
22057 
22059  // lexicographical comparison operators //
22061 
22064 
22065  // note parentheses around operands are necessary; see
22066  // https://github.com/nlohmann/json/issues/1530
22067 #define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result) \
22068  const auto lhs_type = lhs.type(); \
22069  const auto rhs_type = rhs.type(); \
22070  \
22071  if (lhs_type == rhs_type) /* NOLINT(readability/braces) */ \
22072  { \
22073  switch (lhs_type) \
22074  { \
22075  case value_t::array: \
22076  return (*lhs.m_value.array) op (*rhs.m_value.array); \
22077  \
22078  case value_t::object: \
22079  return (*lhs.m_value.object) op (*rhs.m_value.object); \
22080  \
22081  case value_t::null: \
22082  return (null_result); \
22083  \
22084  case value_t::string: \
22085  return (*lhs.m_value.string) op (*rhs.m_value.string); \
22086  \
22087  case value_t::boolean: \
22088  return (lhs.m_value.boolean) op (rhs.m_value.boolean); \
22089  \
22090  case value_t::number_integer: \
22091  return (lhs.m_value.number_integer) op (rhs.m_value.number_integer); \
22092  \
22093  case value_t::number_unsigned: \
22094  return (lhs.m_value.number_unsigned) op (rhs.m_value.number_unsigned); \
22095  \
22096  case value_t::number_float: \
22097  return (lhs.m_value.number_float) op (rhs.m_value.number_float); \
22098  \
22099  case value_t::binary: \
22100  return (*lhs.m_value.binary) op (*rhs.m_value.binary); \
22101  \
22102  case value_t::discarded: \
22103  default: \
22104  return (unordered_result); \
22105  } \
22106  } \
22107  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_float) \
22108  { \
22109  return static_cast<number_float_t>(lhs.m_value.number_integer) op rhs.m_value.number_float; \
22110  } \
22111  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_integer) \
22112  { \
22113  return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_integer); \
22114  } \
22115  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_float) \
22116  { \
22117  return static_cast<number_float_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_float; \
22118  } \
22119  else if (lhs_type == value_t::number_float && rhs_type == value_t::number_unsigned) \
22120  { \
22121  return lhs.m_value.number_float op static_cast<number_float_t>(rhs.m_value.number_unsigned); \
22122  } \
22123  else if (lhs_type == value_t::number_unsigned && rhs_type == value_t::number_integer) \
22124  { \
22125  return static_cast<number_integer_t>(lhs.m_value.number_unsigned) op rhs.m_value.number_integer; \
22126  } \
22127  else if (lhs_type == value_t::number_integer && rhs_type == value_t::number_unsigned) \
22128  { \
22129  return lhs.m_value.number_integer op static_cast<number_integer_t>(rhs.m_value.number_unsigned); \
22130  } \
22131  else if(compares_unordered(lhs, rhs))\
22132  {\
22133  return (unordered_result);\
22134  }\
22135  \
22136  return (default_result);
22137 
22139  // returns true if:
22140  // - any operand is NaN and the other operand is of number type
22141  // - any operand is discarded
22142  // in legacy mode, discarded values are considered ordered if
22143  // an operation is computed as an odd number of inverses of others
22144  static bool compares_unordered(const_reference lhs, const_reference rhs, bool inverse = false) noexcept
22145  {
22146  if ((lhs.is_number_float() && std::isnan(lhs.m_value.number_float) && rhs.is_number())
22147  || (rhs.is_number_float() && std::isnan(rhs.m_value.number_float) && lhs.is_number()))
22148  {
22149  return true;
22150  }
22151 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22152  return (lhs.is_discarded() || rhs.is_discarded()) && !inverse;
22153 #else
22154  static_cast<void>(inverse);
22155  return lhs.is_discarded() || rhs.is_discarded();
22156 #endif
22157  }
22158 
22159  private:
22160  bool compares_unordered(const_reference rhs, bool inverse = false) const noexcept
22161  {
22162  return compares_unordered(*this, rhs, inverse);
22163  }
22164 
22165  public:
22166 #if JSON_HAS_THREE_WAY_COMPARISON
22169  bool operator==(const_reference rhs) const noexcept
22170  {
22171 #ifdef __GNUC__
22172 #pragma GCC diagnostic push
22173 #pragma GCC diagnostic ignored "-Wfloat-equal"
22174 #endif
22175  const_reference lhs = *this;
22176  JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
22177 #ifdef __GNUC__
22178 #pragma GCC diagnostic pop
22179 #endif
22180  }
22181 
22184  template<typename ScalarType>
22185  requires std::is_scalar_v<ScalarType>
22186  bool operator==(ScalarType rhs) const noexcept
22187  {
22188  return *this == basic_json(rhs);
22189  }
22190 
22193  bool operator!=(const_reference rhs) const noexcept
22194  {
22195  if (compares_unordered(rhs, true))
22196  {
22197  return false;
22198  }
22199  return !operator==(rhs);
22200  }
22201 
22204  std::partial_ordering operator<=>(const_reference rhs) const noexcept // *NOPAD*
22205  {
22206  const_reference lhs = *this;
22207  // default_result is used if we cannot compare values. In that case,
22208  // we compare types.
22209  JSON_IMPLEMENT_OPERATOR(<=>, // *NOPAD*
22210  std::partial_ordering::equivalent,
22211  std::partial_ordering::unordered,
22212  lhs_type <=> rhs_type) // *NOPAD*
22213  }
22214 
22217  template<typename ScalarType>
22218  requires std::is_scalar_v<ScalarType>
22219  std::partial_ordering operator<=>(ScalarType rhs) const noexcept // *NOPAD*
22220  {
22221  return *this <=> basic_json(rhs); // *NOPAD*
22222  }
22223 
22224 #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
22225  // all operators that are computed as an odd number of inverses of others
22226  // need to be overloaded to emulate the legacy comparison behavior
22227 
22231  bool operator<=(const_reference rhs) const noexcept
22232  {
22233  if (compares_unordered(rhs, true))
22234  {
22235  return false;
22236  }
22237  return !(rhs < *this);
22238  }
22239 
22242  template<typename ScalarType>
22243  requires std::is_scalar_v<ScalarType>
22244  bool operator<=(ScalarType rhs) const noexcept
22245  {
22246  return *this <= basic_json(rhs);
22247  }
22248 
22252  bool operator>=(const_reference rhs) const noexcept
22253  {
22254  if (compares_unordered(rhs, true))
22255  {
22256  return false;
22257  }
22258  return !(*this < rhs);
22259  }
22260 
22263  template<typename ScalarType>
22264  requires std::is_scalar_v<ScalarType>
22265  bool operator>=(ScalarType rhs) const noexcept
22266  {
22267  return *this >= basic_json(rhs);
22268  }
22269 #endif
22270 #else
22273  friend bool operator==(const_reference lhs, const_reference rhs) noexcept
22274  {
22275 #ifdef __GNUC__
22276 #pragma GCC diagnostic push
22277 #pragma GCC diagnostic ignored "-Wfloat-equal"
22278 #endif
22279  JSON_IMPLEMENT_OPERATOR( ==, true, false, false)
22280 #ifdef __GNUC__
22281 #pragma GCC diagnostic pop
22282 #endif
22283  }
22284 
22287  template<typename ScalarType, typename std::enable_if<
22288  std::is_scalar<ScalarType>::value, int>::type = 0>
22289  friend bool operator==(const_reference lhs, ScalarType rhs) noexcept
22290  {
22291  return lhs == basic_json(rhs);
22292  }
22293 
22296  template<typename ScalarType, typename std::enable_if<
22297  std::is_scalar<ScalarType>::value, int>::type = 0>
22298  friend bool operator==(ScalarType lhs, const_reference rhs) noexcept
22299  {
22300  return basic_json(lhs) == rhs;
22301  }
22302 
22305  friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
22306  {
22307  if (compares_unordered(lhs, rhs, true))
22308  {
22309  return false;
22310  }
22311  return !(lhs == rhs);
22312  }
22313 
22316  template<typename ScalarType, typename std::enable_if<
22317  std::is_scalar<ScalarType>::value, int>::type = 0>
22318  friend bool operator!=(const_reference lhs, ScalarType rhs) noexcept
22319  {
22320  return lhs != basic_json(rhs);
22321  }
22322 
22325  template<typename ScalarType, typename std::enable_if<
22326  std::is_scalar<ScalarType>::value, int>::type = 0>
22327  friend bool operator!=(ScalarType lhs, const_reference rhs) noexcept
22328  {
22329  return basic_json(lhs) != rhs;
22330  }
22331 
22334  friend bool operator<(const_reference lhs, const_reference rhs) noexcept
22335  {
22336  // default_result is used if we cannot compare values. In that case,
22337  // we compare types. Note we have to call the operator explicitly,
22338  // because MSVC has problems otherwise.
22339  JSON_IMPLEMENT_OPERATOR( <, false, false, operator<(lhs_type, rhs_type))
22340  }
22341 
22344  template<typename ScalarType, typename std::enable_if<
22345  std::is_scalar<ScalarType>::value, int>::type = 0>
22346  friend bool operator<(const_reference lhs, ScalarType rhs) noexcept
22347  {
22348  return lhs < basic_json(rhs);
22349  }
22350 
22353  template<typename ScalarType, typename std::enable_if<
22354  std::is_scalar<ScalarType>::value, int>::type = 0>
22355  friend bool operator<(ScalarType lhs, const_reference rhs) noexcept
22356  {
22357  return basic_json(lhs) < rhs;
22358  }
22359 
22362  friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
22363  {
22364  if (compares_unordered(lhs, rhs, true))
22365  {
22366  return false;
22367  }
22368  return !(rhs < lhs);
22369  }
22370 
22373  template<typename ScalarType, typename std::enable_if<
22374  std::is_scalar<ScalarType>::value, int>::type = 0>
22375  friend bool operator<=(const_reference lhs, ScalarType rhs) noexcept
22376  {
22377  return lhs <= basic_json(rhs);
22378  }
22379 
22382  template<typename ScalarType, typename std::enable_if<
22383  std::is_scalar<ScalarType>::value, int>::type = 0>
22384  friend bool operator<=(ScalarType lhs, const_reference rhs) noexcept
22385  {
22386  return basic_json(lhs) <= rhs;
22387  }
22388 
22391  friend bool operator>(const_reference lhs, const_reference rhs) noexcept
22392  {
22393  // double inverse
22394  if (compares_unordered(lhs, rhs))
22395  {
22396  return false;
22397  }
22398  return !(lhs <= rhs);
22399  }
22400 
22403  template<typename ScalarType, typename std::enable_if<
22404  std::is_scalar<ScalarType>::value, int>::type = 0>
22405  friend bool operator>(const_reference lhs, ScalarType rhs) noexcept
22406  {
22407  return lhs > basic_json(rhs);
22408  }
22409 
22412  template<typename ScalarType, typename std::enable_if<
22413  std::is_scalar<ScalarType>::value, int>::type = 0>
22414  friend bool operator>(ScalarType lhs, const_reference rhs) noexcept
22415  {
22416  return basic_json(lhs) > rhs;
22417  }
22418 
22421  friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
22422  {
22423  if (compares_unordered(lhs, rhs, true))
22424  {
22425  return false;
22426  }
22427  return !(lhs < rhs);
22428  }
22429 
22432  template<typename ScalarType, typename std::enable_if<
22433  std::is_scalar<ScalarType>::value, int>::type = 0>
22434  friend bool operator>=(const_reference lhs, ScalarType rhs) noexcept
22435  {
22436  return lhs >= basic_json(rhs);
22437  }
22438 
22441  template<typename ScalarType, typename std::enable_if<
22442  std::is_scalar<ScalarType>::value, int>::type = 0>
22443  friend bool operator>=(ScalarType lhs, const_reference rhs) noexcept
22444  {
22445  return basic_json(lhs) >= rhs;
22446  }
22447 #endif
22448 
22449 #undef JSON_IMPLEMENT_OPERATOR
22450 
22452 
22454  // serialization //
22456 
22459 #ifndef JSON_NO_IO
22462  friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
22463  {
22464  // read width member and use it as indentation parameter if nonzero
22465  const bool pretty_print = o.width() > 0;
22466  const auto indentation = pretty_print ? o.width() : 0;
22467 
22468  // reset width to 0 for subsequent calls to this stream
22469  o.width(0);
22470 
22471  // do the actual serialization
22472  serializer s(detail::output_adapter<char>(o), o.fill());
22473  s.dump(j, pretty_print, false, static_cast<unsigned int>(indentation));
22474  return o;
22475  }
22476 
22483  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator<<(std::ostream&, const basic_json&))
22484  friend std::ostream& operator>>(const basic_json& j, std::ostream& o)
22485  {
22486  return o << j;
22487  }
22488 #endif // JSON_NO_IO
22490 
22491 
22493  // deserialization //
22495 
22498 
22501  template<typename InputType>
22503  static basic_json parse(InputType&& i,
22504  const parser_callback_t cb = nullptr,
22505  const bool allow_exceptions = true,
22506  const bool ignore_comments = false)
22507  {
22508  basic_json result;
22509  parser(detail::input_adapter(std::forward<InputType>(i)), cb, allow_exceptions, ignore_comments).parse(true, result);
22510  return result;
22511  }
22512 
22515  template<typename IteratorType>
22517  static basic_json parse(IteratorType first,
22518  IteratorType last,
22519  const parser_callback_t cb = nullptr,
22520  const bool allow_exceptions = true,
22521  const bool ignore_comments = false)
22522  {
22523  basic_json result;
22524  parser(detail::input_adapter(std::move(first), std::move(last)), cb, allow_exceptions, ignore_comments).parse(true, result);
22525  return result;
22526  }
22527 
22529  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, parse(ptr, ptr + len))
22530  static basic_json parse(detail::span_input_adapter&& i,
22531  const parser_callback_t cb = nullptr,
22532  const bool allow_exceptions = true,
22533  const bool ignore_comments = false)
22534  {
22535  basic_json result;
22536  parser(i.get(), cb, allow_exceptions, ignore_comments).parse(true, result);
22537  return result;
22538  }
22539 
22542  template<typename InputType>
22543  static bool accept(InputType&& i,
22544  const bool ignore_comments = false)
22545  {
22546  return parser(detail::input_adapter(std::forward<InputType>(i)), nullptr, false, ignore_comments).accept(true);
22547  }
22548 
22551  template<typename IteratorType>
22552  static bool accept(IteratorType first, IteratorType last,
22553  const bool ignore_comments = false)
22554  {
22555  return parser(detail::input_adapter(std::move(first), std::move(last)), nullptr, false, ignore_comments).accept(true);
22556  }
22557 
22559  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, accept(ptr, ptr + len))
22560  static bool accept(detail::span_input_adapter&& i,
22561  const bool ignore_comments = false)
22562  {
22563  return parser(i.get(), nullptr, false, ignore_comments).accept(true);
22564  }
22565 
22568  template <typename InputType, typename SAX>
22570  static bool sax_parse(InputType&& i, SAX* sax,
22572  const bool strict = true,
22573  const bool ignore_comments = false)
22574  {
22575  auto ia = detail::input_adapter(std::forward<InputType>(i));
22576  return format == input_format_t::json
22577  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
22578  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
22579  }
22580 
22583  template<class IteratorType, class SAX>
22585  static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
22587  const bool strict = true,
22588  const bool ignore_comments = false)
22589  {
22590  auto ia = detail::input_adapter(std::move(first), std::move(last));
22591  return format == input_format_t::json
22592  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
22593  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
22594  }
22595 
22601  template <typename SAX>
22602  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...))
22604  static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
22606  const bool strict = true,
22607  const bool ignore_comments = false)
22608  {
22609  auto ia = i.get();
22610  return format == input_format_t::json
22611  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22612  ? parser(std::move(ia), nullptr, true, ignore_comments).sax_parse(sax, strict)
22613  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22614  : detail::binary_reader<basic_json, decltype(ia), SAX>(std::move(ia), format).sax_parse(format, sax, strict);
22615  }
22616 #ifndef JSON_NO_IO
22623  JSON_HEDLEY_DEPRECATED_FOR(3.0.0, operator>>(std::istream&, basic_json&))
22624  friend std::istream& operator<<(basic_json& j, std::istream& i)
22625  {
22626  return operator>>(i, j);
22627  }
22628 
22631  friend std::istream& operator>>(std::istream& i, basic_json& j)
22632  {
22633  parser(detail::input_adapter(i)).parse(false, j);
22634  return i;
22635  }
22636 #endif // JSON_NO_IO
22638 
22640  // convenience functions //
22642 
22646  const char* type_name() const noexcept
22647  {
22648  switch (m_type)
22649  {
22650  case value_t::null:
22651  return "null";
22652  case value_t::object:
22653  return "object";
22654  case value_t::array:
22655  return "array";
22656  case value_t::string:
22657  return "string";
22658  case value_t::boolean:
22659  return "boolean";
22660  case value_t::binary:
22661  return "binary";
22662  case value_t::discarded:
22663  return "discarded";
22666  case value_t::number_float:
22667  default:
22668  return "number";
22669  }
22670  }
22671 
22672 
22675  // member variables //
22677 
22679  value_t m_type = value_t::null;
22680 
22682  json_value m_value = {};
22683 
22684 #if JSON_DIAGNOSTICS
22686  basic_json* m_parent = nullptr;
22687 #endif
22688 
22690  // binary serialization/deserialization //
22692 
22695 
22696  public:
22699  static std::vector<std::uint8_t> to_cbor(const basic_json& j)
22700  {
22701  std::vector<std::uint8_t> result;
22702  to_cbor(j, result);
22703  return result;
22704  }
22705 
22709  {
22711  }
22712 
22716  {
22718  }
22719 
22722  static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
22723  {
22724  std::vector<std::uint8_t> result;
22725  to_msgpack(j, result);
22726  return result;
22727  }
22728 
22732  {
22734  }
22735 
22739  {
22741  }
22742 
22745  static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
22746  const bool use_size = false,
22747  const bool use_type = false)
22748  {
22749  std::vector<std::uint8_t> result;
22750  to_ubjson(j, result, use_size, use_type);
22751  return result;
22752  }
22753 
22757  const bool use_size = false, const bool use_type = false)
22758  {
22759  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type);
22760  }
22761 
22765  const bool use_size = false, const bool use_type = false)
22766  {
22767  binary_writer<char>(o).write_ubjson(j, use_size, use_type);
22768  }
22769 
22772  static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
22773  const bool use_size = false,
22774  const bool use_type = false)
22775  {
22776  std::vector<std::uint8_t> result;
22777  to_bjdata(j, result, use_size, use_type);
22778  return result;
22779  }
22780 
22784  const bool use_size = false, const bool use_type = false)
22785  {
22786  binary_writer<std::uint8_t>(o).write_ubjson(j, use_size, use_type, true, true);
22787  }
22788 
22792  const bool use_size = false, const bool use_type = false)
22793  {
22794  binary_writer<char>(o).write_ubjson(j, use_size, use_type, true, true);
22795  }
22796 
22799  static std::vector<std::uint8_t> to_bson(const basic_json& j)
22800  {
22801  std::vector<std::uint8_t> result;
22802  to_bson(j, result);
22803  return result;
22804  }
22805 
22809  {
22811  }
22812 
22816  {
22818  }
22819 
22822  template<typename InputType>
22824  static basic_json from_cbor(InputType&& i,
22825  const bool strict = true,
22826  const bool allow_exceptions = true,
22827  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22828  {
22829  basic_json result;
22830  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22831  auto ia = detail::input_adapter(std::forward<InputType>(i));
22832  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
22833  return res ? result : basic_json(value_t::discarded);
22834  }
22835 
22838  template<typename IteratorType>
22840  static basic_json from_cbor(IteratorType first, IteratorType last,
22841  const bool strict = true,
22842  const bool allow_exceptions = true,
22843  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22844  {
22845  basic_json result;
22846  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22847  auto ia = detail::input_adapter(std::move(first), std::move(last));
22848  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
22849  return res ? result : basic_json(value_t::discarded);
22850  }
22851 
22852  template<typename T>
22854  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
22855  static basic_json from_cbor(const T* ptr, std::size_t len,
22856  const bool strict = true,
22857  const bool allow_exceptions = true,
22858  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22859  {
22860  return from_cbor(ptr, ptr + len, strict, allow_exceptions, tag_handler);
22861  }
22862 
22863 
22865  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_cbor(ptr, ptr + len))
22866  static basic_json from_cbor(detail::span_input_adapter&& i,
22867  const bool strict = true,
22868  const bool allow_exceptions = true,
22869  const cbor_tag_handler_t tag_handler = cbor_tag_handler_t::error)
22870  {
22871  basic_json result;
22872  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22873  auto ia = i.get();
22874  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22875  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::cbor).sax_parse(input_format_t::cbor, &sdp, strict, tag_handler);
22876  return res ? result : basic_json(value_t::discarded);
22877  }
22878 
22881  template<typename InputType>
22883  static basic_json from_msgpack(InputType&& i,
22884  const bool strict = true,
22885  const bool allow_exceptions = true)
22886  {
22887  basic_json result;
22888  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22889  auto ia = detail::input_adapter(std::forward<InputType>(i));
22890  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
22891  return res ? result : basic_json(value_t::discarded);
22892  }
22893 
22896  template<typename IteratorType>
22898  static basic_json from_msgpack(IteratorType first, IteratorType last,
22899  const bool strict = true,
22900  const bool allow_exceptions = true)
22901  {
22902  basic_json result;
22903  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22904  auto ia = detail::input_adapter(std::move(first), std::move(last));
22905  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
22906  return res ? result : basic_json(value_t::discarded);
22907  }
22908 
22909  template<typename T>
22911  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
22912  static basic_json from_msgpack(const T* ptr, std::size_t len,
22913  const bool strict = true,
22914  const bool allow_exceptions = true)
22915  {
22916  return from_msgpack(ptr, ptr + len, strict, allow_exceptions);
22917  }
22918 
22920  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_msgpack(ptr, ptr + len))
22921  static basic_json from_msgpack(detail::span_input_adapter&& i,
22922  const bool strict = true,
22923  const bool allow_exceptions = true)
22924  {
22925  basic_json result;
22926  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22927  auto ia = i.get();
22928  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22929  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::msgpack).sax_parse(input_format_t::msgpack, &sdp, strict);
22930  return res ? result : basic_json(value_t::discarded);
22931  }
22932 
22935  template<typename InputType>
22937  static basic_json from_ubjson(InputType&& i,
22938  const bool strict = true,
22939  const bool allow_exceptions = true)
22940  {
22941  basic_json result;
22942  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22943  auto ia = detail::input_adapter(std::forward<InputType>(i));
22944  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
22945  return res ? result : basic_json(value_t::discarded);
22946  }
22947 
22950  template<typename IteratorType>
22952  static basic_json from_ubjson(IteratorType first, IteratorType last,
22953  const bool strict = true,
22954  const bool allow_exceptions = true)
22955  {
22956  basic_json result;
22957  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22958  auto ia = detail::input_adapter(std::move(first), std::move(last));
22959  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
22960  return res ? result : basic_json(value_t::discarded);
22961  }
22962 
22963  template<typename T>
22965  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
22966  static basic_json from_ubjson(const T* ptr, std::size_t len,
22967  const bool strict = true,
22968  const bool allow_exceptions = true)
22969  {
22970  return from_ubjson(ptr, ptr + len, strict, allow_exceptions);
22971  }
22972 
22974  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_ubjson(ptr, ptr + len))
22975  static basic_json from_ubjson(detail::span_input_adapter&& i,
22976  const bool strict = true,
22977  const bool allow_exceptions = true)
22978  {
22979  basic_json result;
22980  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22981  auto ia = i.get();
22982  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
22983  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::ubjson).sax_parse(input_format_t::ubjson, &sdp, strict);
22984  return res ? result : basic_json(value_t::discarded);
22985  }
22986 
22987 
22990  template<typename InputType>
22992  static basic_json from_bjdata(InputType&& i,
22993  const bool strict = true,
22994  const bool allow_exceptions = true)
22995  {
22996  basic_json result;
22997  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
22998  auto ia = detail::input_adapter(std::forward<InputType>(i));
22999  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23000  return res ? result : basic_json(value_t::discarded);
23001  }
23002 
23005  template<typename IteratorType>
23007  static basic_json from_bjdata(IteratorType first, IteratorType last,
23008  const bool strict = true,
23009  const bool allow_exceptions = true)
23010  {
23011  basic_json result;
23012  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23013  auto ia = detail::input_adapter(std::move(first), std::move(last));
23014  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bjdata).sax_parse(input_format_t::bjdata, &sdp, strict);
23015  return res ? result : basic_json(value_t::discarded);
23016  }
23017 
23020  template<typename InputType>
23022  static basic_json from_bson(InputType&& i,
23023  const bool strict = true,
23024  const bool allow_exceptions = true)
23025  {
23026  basic_json result;
23027  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23028  auto ia = detail::input_adapter(std::forward<InputType>(i));
23029  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23030  return res ? result : basic_json(value_t::discarded);
23031  }
23032 
23035  template<typename IteratorType>
23037  static basic_json from_bson(IteratorType first, IteratorType last,
23038  const bool strict = true,
23039  const bool allow_exceptions = true)
23040  {
23041  basic_json result;
23042  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23043  auto ia = detail::input_adapter(std::move(first), std::move(last));
23044  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23045  return res ? result : basic_json(value_t::discarded);
23046  }
23047 
23048  template<typename T>
23050  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23051  static basic_json from_bson(const T* ptr, std::size_t len,
23052  const bool strict = true,
23053  const bool allow_exceptions = true)
23054  {
23055  return from_bson(ptr, ptr + len, strict, allow_exceptions);
23056  }
23057 
23059  JSON_HEDLEY_DEPRECATED_FOR(3.8.0, from_bson(ptr, ptr + len))
23060  static basic_json from_bson(detail::span_input_adapter&& i,
23061  const bool strict = true,
23062  const bool allow_exceptions = true)
23063  {
23064  basic_json result;
23065  detail::json_sax_dom_parser<basic_json> sdp(result, allow_exceptions);
23066  auto ia = i.get();
23067  // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg)
23068  const bool res = binary_reader<decltype(ia)>(std::move(ia), input_format_t::bson).sax_parse(input_format_t::bson, &sdp, strict);
23069  return res ? result : basic_json(value_t::discarded);
23070  }
23072 
23074  // JSON Pointer support //
23076 
23079 
23083  {
23084  return ptr.get_unchecked(this);
23085  }
23086 
23087  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23089  reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23090  {
23091  return ptr.get_unchecked(this);
23092  }
23093 
23097  {
23098  return ptr.get_unchecked(this);
23099  }
23100 
23101  template<typename BasicJsonType, detail::enable_if_t<detail::is_basic_json<BasicJsonType>::value, int> = 0>
23103  const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23104  {
23105  return ptr.get_unchecked(this);
23106  }
23107 
23110  reference at(const json_pointer& ptr)
23111  {
23112  return ptr.get_checked(this);
23113  }
23114 
23115  template<typename BasicJsonType>
23117  reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
23118  {
23119  return ptr.get_checked(this);
23120  }
23121 
23124  const_reference at(const json_pointer& ptr) const
23125  {
23126  return ptr.get_checked(this);
23127  }
23128 
23129  template<typename BasicJsonType>
23131  const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) const
23132  {
23133  return ptr.get_checked(this);
23134  }
23135 
23138  basic_json flatten() const
23139  {
23140  basic_json result(value_t::object);
23141  json_pointer::flatten("", *this, result);
23142  return result;
23143  }
23144 
23147  basic_json unflatten() const
23148  {
23149  return json_pointer::unflatten(*this);
23150  }
23151 
23153 
23155  // JSON Patch functions //
23157 
23160 
23163  basic_json patch(const basic_json& json_patch) const
23164  {
23165  // make a working copy to apply the patch to
23166  basic_json result = *this;
23167 
23168  // the valid JSON Patch operations
23169  enum class patch_operations {add, remove, replace, move, copy, test, invalid};
23170 
23171  const auto get_op = [](const std::string & op)
23172  {
23173  if (op == "add")
23174  {
23175  return patch_operations::add;
23176  }
23177  if (op == "remove")
23178  {
23179  return patch_operations::remove;
23180  }
23181  if (op == "replace")
23182  {
23183  return patch_operations::replace;
23184  }
23185  if (op == "move")
23186  {
23187  return patch_operations::move;
23188  }
23189  if (op == "copy")
23190  {
23191  return patch_operations::copy;
23192  }
23193  if (op == "test")
23194  {
23195  return patch_operations::test;
23196  }
23197 
23198  return patch_operations::invalid;
23199  };
23200 
23201  // wrapper for "add" operation; add value at ptr
23202  const auto operation_add = [&result](json_pointer & ptr, basic_json val)
23203  {
23204  // adding to the root of the target document means replacing it
23205  if (ptr.empty())
23206  {
23207  result = val;
23208  return;
23209  }
23210 
23211  // make sure the top element of the pointer exists
23212  json_pointer top_pointer = ptr.top();
23213  if (top_pointer != ptr)
23214  {
23215  result.at(top_pointer);
23216  }
23217 
23218  // get reference to parent of JSON pointer ptr
23219  const auto last_path = ptr.back();
23220  ptr.pop_back();
23221  basic_json& parent = result[ptr];
23222 
23223  switch (parent.m_type)
23224  {
23225  case value_t::null:
23226  case value_t::object:
23227  {
23228  // use operator[] to add value
23229  parent[last_path] = val;
23230  break;
23231  }
23232 
23233  case value_t::array:
23234  {
23235  if (last_path == "-")
23236  {
23237  // special case: append to back
23238  parent.push_back(val);
23239  }
23240  else
23241  {
23242  const auto idx = json_pointer::template array_index<basic_json_t>(last_path);
23243  if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
23244  {
23245  // avoid undefined behavior
23246  JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
23247  }
23248 
23249  // default case: insert add offset
23250  parent.insert(parent.begin() + static_cast<difference_type>(idx), val);
23251  }
23252  break;
23253  }
23254 
23255  // if there exists a parent it cannot be primitive
23256  case value_t::string: // LCOV_EXCL_LINE
23257  case value_t::boolean: // LCOV_EXCL_LINE
23258  case value_t::number_integer: // LCOV_EXCL_LINE
23259  case value_t::number_unsigned: // LCOV_EXCL_LINE
23260  case value_t::number_float: // LCOV_EXCL_LINE
23261  case value_t::binary: // LCOV_EXCL_LINE
23262  case value_t::discarded: // LCOV_EXCL_LINE
23263  default: // LCOV_EXCL_LINE
23264  JSON_ASSERT(false); // NOLINT(cert-dcl03-c,hicpp-static-assert,misc-static-assert) LCOV_EXCL_LINE
23265  }
23266  };
23267 
23268  // wrapper for "remove" operation; remove value at ptr
23269  const auto operation_remove = [this, &result](json_pointer & ptr)
23270  {
23271  // get reference to parent of JSON pointer ptr
23272  const auto last_path = ptr.back();
23273  ptr.pop_back();
23274  basic_json& parent = result.at(ptr);
23275 
23276  // remove child
23277  if (parent.is_object())
23278  {
23279  // perform range check
23280  auto it = parent.find(last_path);
23281  if (JSON_HEDLEY_LIKELY(it != parent.end()))
23282  {
23283  parent.erase(it);
23284  }
23285  else
23286  {
23287  JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
23288  }
23289  }
23290  else if (parent.is_array())
23291  {
23292  // note erase performs range check
23293  parent.erase(json_pointer::template array_index<basic_json_t>(last_path));
23294  }
23295  };
23296 
23297  // type check: top level value must be an array
23298  if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
23299  {
23300  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
23301  }
23302 
23303  // iterate and apply the operations
23304  for (const auto& val : json_patch)
23305  {
23306  // wrapper to get a value for an operation
23307  const auto get_value = [&val](const std::string & op,
23308  const std::string & member,
23309  bool string_type) -> basic_json &
23310  {
23311  // find value
23312  auto it = val.m_value.object->find(member);
23313 
23314  // context-sensitive error message
23315  const auto error_msg = (op == "op") ? "operation" : detail::concat("operation '", op, '\'');
23316 
23317  // check if desired value is present
23318  if (JSON_HEDLEY_UNLIKELY(it == val.m_value.object->end()))
23319  {
23320  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
23321  JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
23322  }
23323 
23324  // check if result is of type string
23325  if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
23326  {
23327  // NOLINTNEXTLINE(performance-inefficient-string-concatenation)
23328  JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
23329  }
23330 
23331  // no error: return value
23332  return it->second;
23333  };
23334 
23335  // type check: every element of the array must be an object
23336  if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
23337  {
23338  JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
23339  }
23340 
23341  // collect mandatory members
23342  const auto op = get_value("op", "op", true).template get<std::string>();
23343  const auto path = get_value(op, "path", true).template get<std::string>();
23344  json_pointer ptr(path);
23345 
23346  switch (get_op(op))
23347  {
23348  case patch_operations::add:
23349  {
23350  operation_add(ptr, get_value("add", "value", false));
23351  break;
23352  }
23353 
23354  case patch_operations::remove:
23355  {
23356  operation_remove(ptr);
23357  break;
23358  }
23359 
23360  case patch_operations::replace:
23361  {
23362  // the "path" location must exist - use at()
23363  result.at(ptr) = get_value("replace", "value", false);
23364  break;
23365  }
23366 
23367  case patch_operations::move:
23368  {
23369  const auto from_path = get_value("move", "from", true).template get<std::string>();
23370  json_pointer from_ptr(from_path);
23371 
23372  // the "from" location must exist - use at()
23373  basic_json v = result.at(from_ptr);
23374 
23375  // The move operation is functionally identical to a
23376  // "remove" operation on the "from" location, followed
23377  // immediately by an "add" operation at the target
23378  // location with the value that was just removed.
23379  operation_remove(from_ptr);
23380  operation_add(ptr, v);
23381  break;
23382  }
23383 
23384  case patch_operations::copy:
23385  {
23386  const auto from_path = get_value("copy", "from", true).template get<std::string>();
23387  const json_pointer from_ptr(from_path);
23388 
23389  // the "from" location must exist - use at()
23390  basic_json v = result.at(from_ptr);
23391 
23392  // The copy is functionally identical to an "add"
23393  // operation at the target location using the value
23394  // specified in the "from" member.
23395  operation_add(ptr, v);
23396  break;
23397  }
23398 
23399  case patch_operations::test:
23400  {
23401  bool success = false;
23402  JSON_TRY
23403  {
23404  // check if "value" matches the one at "path"
23405  // the "path" location must exist - use at()
23406  success = (result.at(ptr) == get_value("test", "value", false));
23407  }
23409  {
23410  // ignore out of range errors: success remains false
23411  }
23412 
23413  // throw an exception if test fails
23414  if (JSON_HEDLEY_UNLIKELY(!success))
23415  {
23416  JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
23417  }
23418 
23419  break;
23420  }
23421 
23422  case patch_operations::invalid:
23423  default:
23424  {
23425  // op must be "add", "remove", "replace", "move", "copy", or
23426  // "test"
23427  JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
23428  }
23429  }
23430  }
23431 
23432  return result;
23433  }
23434 
23438  static basic_json diff(const basic_json& source, const basic_json& target,
23439  const std::string& path = "")
23440  {
23441  // the patch
23442  basic_json result(value_t::array);
23443 
23444  // if the values are the same, return empty patch
23445  if (source == target)
23446  {
23447  return result;
23448  }
23449 
23450  if (source.type() != target.type())
23451  {
23452  // different types: replace value
23453  result.push_back(
23454  {
23455  {"op", "replace"}, {"path", path}, {"value", target}
23456  });
23457  return result;
23458  }
23459 
23460  switch (source.type())
23461  {
23462  case value_t::array:
23463  {
23464  // first pass: traverse common elements
23465  std::size_t i = 0;
23466  while (i < source.size() && i < target.size())
23467  {
23468  // recursive call to compare array values at index i
23469  auto temp_diff = diff(source[i], target[i], detail::concat(path, '/', std::to_string(i)));
23470  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
23471  ++i;
23472  }
23473 
23474  // We now reached the end of at least one array
23475  // in a second pass, traverse the remaining elements
23476 
23477  // remove my remaining elements
23478  const auto end_index = static_cast<difference_type>(result.size());
23479  while (i < source.size())
23480  {
23481  // add operations in reverse order to avoid invalid
23482  // indices
23483  result.insert(result.begin() + end_index, object(
23484  {
23485  {"op", "remove"},
23486  {"path", detail::concat(path, '/', std::to_string(i))}
23487  }));
23488  ++i;
23489  }
23490 
23491  // add other remaining elements
23492  while (i < target.size())
23493  {
23494  result.push_back(
23495  {
23496  {"op", "add"},
23497  {"path", detail::concat(path, "/-")},
23498  {"value", target[i]}
23499  });
23500  ++i;
23501  }
23502 
23503  break;
23504  }
23505 
23506  case value_t::object:
23507  {
23508  // first pass: traverse this object's elements
23509  for (auto it = source.cbegin(); it != source.cend(); ++it)
23510  {
23511  // escape the key name to be used in a JSON patch
23512  const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
23513 
23514  if (target.find(it.key()) != target.end())
23515  {
23516  // recursive call to compare object values at key it
23517  auto temp_diff = diff(it.value(), target[it.key()], path_key);
23518  result.insert(result.end(), temp_diff.begin(), temp_diff.end());
23519  }
23520  else
23521  {
23522  // found a key that is not in o -> remove it
23523  result.push_back(object(
23524  {
23525  {"op", "remove"}, {"path", path_key}
23526  }));
23527  }
23528  }
23529 
23530  // second pass: traverse other object's elements
23531  for (auto it = target.cbegin(); it != target.cend(); ++it)
23532  {
23533  if (source.find(it.key()) == source.end())
23534  {
23535  // found a key that is not in this -> add it
23536  const auto path_key = detail::concat(path, '/', detail::escape(it.key()));
23537  result.push_back(
23538  {
23539  {"op", "add"}, {"path", path_key},
23540  {"value", it.value()}
23541  });
23542  }
23543  }
23544 
23545  break;
23546  }
23547 
23548  case value_t::null:
23549  case value_t::string:
23550  case value_t::boolean:
23553  case value_t::number_float:
23554  case value_t::binary:
23555  case value_t::discarded:
23556  default:
23557  {
23558  // both primitive type: replace value
23559  result.push_back(
23560  {
23561  {"op", "replace"}, {"path", path}, {"value", target}
23562  });
23563  break;
23564  }
23565  }
23566 
23567  return result;
23568  }
23569 
23571 
23573  // JSON Merge Patch functions //
23575 
23578 
23581  void merge_patch(const basic_json& apply_patch)
23582  {
23583  if (apply_patch.is_object())
23584  {
23585  if (!is_object())
23586  {
23587  *this = object();
23588  }
23589  for (auto it = apply_patch.begin(); it != apply_patch.end(); ++it)
23590  {
23591  if (it.value().is_null())
23592  {
23593  erase(it.key());
23594  }
23595  else
23596  {
23597  operator[](it.key()).merge_patch(it.value());
23598  }
23599  }
23600  }
23601  else
23602  {
23603  *this = apply_patch;
23604  }
23605  }
23606 
23608 };
23609 
23613 std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
23614 {
23615  return j.dump();
23616 }
23617 
23618 } // namespace nlohmann
23619 
23621 // nonmember support //
23623 
23624 namespace std // NOLINT(cert-dcl58-cpp)
23625 {
23626 
23631 {
23632  std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const
23633  {
23634  return nlohmann::detail::hash(j);
23635  }
23636 };
23637 
23638 // specialization for std::less<value_t>
23639 template<>
23640 struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', see https://github.com/nlohmann/json/pull/679
23641 {
23647  ::nlohmann::detail::value_t rhs) const noexcept
23648  {
23649 #if JSON_HAS_THREE_WAY_COMPARISON
23650  return std::is_lt(lhs <=> rhs); // *NOPAD*
23651 #else
23653 #endif
23654  }
23655 };
23656 
23657 // C++20 prohibit function specialization in the std namespace.
23658 #ifndef JSON_HAS_CPP_20
23659 
23663 inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name)
23664  is_nothrow_move_constructible<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value&& // NOLINT(misc-redundant-expression)
23665  is_nothrow_move_assignable<nlohmann::NLOHMANN_BASIC_JSON_TPL>::value)
23666 {
23667  j1.swap(j2);
23668 }
23669 
23670 #endif
23671 
23672 } // namespace std
23673 
23677 inline nlohmann::json operator "" _json(const char* s, std::size_t n)
23678 {
23679  return nlohmann::json::parse(s, s + n);
23680 }
23681 
23685 inline nlohmann::json::json_pointer operator "" _json_pointer(const char* s, std::size_t n)
23686 {
23687  return nlohmann::json::json_pointer(std::string(s, n));
23688 }
23689 
23690 // #include <nlohmann/detail/macro_unscope.hpp>
23691 
23692 
23693 // restore clang diagnostic settings
23694 #if defined(__clang__)
23695  #pragma clang diagnostic pop
23696 #endif
23697 
23698 // clean up
23699 #undef JSON_ASSERT
23700 #undef JSON_INTERNAL_CATCH
23701 #undef JSON_THROW
23702 #undef JSON_PRIVATE_UNLESS_TESTED
23703 #undef NLOHMANN_BASIC_JSON_TPL_DECLARATION
23704 #undef NLOHMANN_BASIC_JSON_TPL
23705 #undef JSON_EXPLICIT
23706 #undef NLOHMANN_CAN_CALL_STD_FUNC_IMPL
23707 #undef JSON_INLINE_VARIABLE
23708 #undef JSON_NO_UNIQUE_ADDRESS
23709 #undef JSON_DISABLE_ENUM_SERIALIZATION
23710 
23711 #ifndef JSON_TEST_KEEP_MACROS
23712  #undef JSON_CATCH
23713  #undef JSON_TRY
23714  #undef JSON_HAS_CPP_11
23715  #undef JSON_HAS_CPP_14
23716  #undef JSON_HAS_CPP_17
23717  #undef JSON_HAS_CPP_20
23718  #undef JSON_HAS_FILESYSTEM
23719  #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
23720  #undef JSON_HAS_THREE_WAY_COMPARISON
23721  #undef JSON_HAS_RANGES
23722  #undef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
23723 #endif
23724 
23725 // #include <nlohmann/thirdparty/hedley/hedley_undef.hpp>
23726 
23727 
23728 #undef JSON_HEDLEY_ALWAYS_INLINE
23729 #undef JSON_HEDLEY_ARM_VERSION
23730 #undef JSON_HEDLEY_ARM_VERSION_CHECK
23731 #undef JSON_HEDLEY_ARRAY_PARAM
23732 #undef JSON_HEDLEY_ASSUME
23733 #undef JSON_HEDLEY_BEGIN_C_DECLS
23734 #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE
23735 #undef JSON_HEDLEY_CLANG_HAS_BUILTIN
23736 #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE
23737 #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE
23738 #undef JSON_HEDLEY_CLANG_HAS_EXTENSION
23739 #undef JSON_HEDLEY_CLANG_HAS_FEATURE
23740 #undef JSON_HEDLEY_CLANG_HAS_WARNING
23741 #undef JSON_HEDLEY_COMPCERT_VERSION
23742 #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK
23743 #undef JSON_HEDLEY_CONCAT
23744 #undef JSON_HEDLEY_CONCAT3
23745 #undef JSON_HEDLEY_CONCAT3_EX
23746 #undef JSON_HEDLEY_CONCAT_EX
23747 #undef JSON_HEDLEY_CONST
23748 #undef JSON_HEDLEY_CONSTEXPR
23749 #undef JSON_HEDLEY_CONST_CAST
23750 #undef JSON_HEDLEY_CPP_CAST
23751 #undef JSON_HEDLEY_CRAY_VERSION
23752 #undef JSON_HEDLEY_CRAY_VERSION_CHECK
23753 #undef JSON_HEDLEY_C_DECL
23754 #undef JSON_HEDLEY_DEPRECATED
23755 #undef JSON_HEDLEY_DEPRECATED_FOR
23756 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL
23757 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_
23758 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
23759 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES
23760 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS
23761 #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION
23762 #undef JSON_HEDLEY_DIAGNOSTIC_POP
23763 #undef JSON_HEDLEY_DIAGNOSTIC_PUSH
23764 #undef JSON_HEDLEY_DMC_VERSION
23765 #undef JSON_HEDLEY_DMC_VERSION_CHECK
23766 #undef JSON_HEDLEY_EMPTY_BASES
23767 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION
23768 #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK
23769 #undef JSON_HEDLEY_END_C_DECLS
23770 #undef JSON_HEDLEY_FLAGS
23771 #undef JSON_HEDLEY_FLAGS_CAST
23772 #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE
23773 #undef JSON_HEDLEY_GCC_HAS_BUILTIN
23774 #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE
23775 #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE
23776 #undef JSON_HEDLEY_GCC_HAS_EXTENSION
23777 #undef JSON_HEDLEY_GCC_HAS_FEATURE
23778 #undef JSON_HEDLEY_GCC_HAS_WARNING
23779 #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK
23780 #undef JSON_HEDLEY_GCC_VERSION
23781 #undef JSON_HEDLEY_GCC_VERSION_CHECK
23782 #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE
23783 #undef JSON_HEDLEY_GNUC_HAS_BUILTIN
23784 #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE
23785 #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE
23786 #undef JSON_HEDLEY_GNUC_HAS_EXTENSION
23787 #undef JSON_HEDLEY_GNUC_HAS_FEATURE
23788 #undef JSON_HEDLEY_GNUC_HAS_WARNING
23789 #undef JSON_HEDLEY_GNUC_VERSION
23790 #undef JSON_HEDLEY_GNUC_VERSION_CHECK
23791 #undef JSON_HEDLEY_HAS_ATTRIBUTE
23792 #undef JSON_HEDLEY_HAS_BUILTIN
23793 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE
23794 #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS
23795 #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE
23796 #undef JSON_HEDLEY_HAS_EXTENSION
23797 #undef JSON_HEDLEY_HAS_FEATURE
23798 #undef JSON_HEDLEY_HAS_WARNING
23799 #undef JSON_HEDLEY_IAR_VERSION
23800 #undef JSON_HEDLEY_IAR_VERSION_CHECK
23801 #undef JSON_HEDLEY_IBM_VERSION
23802 #undef JSON_HEDLEY_IBM_VERSION_CHECK
23803 #undef JSON_HEDLEY_IMPORT
23804 #undef JSON_HEDLEY_INLINE
23805 #undef JSON_HEDLEY_INTEL_CL_VERSION
23806 #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK
23807 #undef JSON_HEDLEY_INTEL_VERSION
23808 #undef JSON_HEDLEY_INTEL_VERSION_CHECK
23809 #undef JSON_HEDLEY_IS_CONSTANT
23810 #undef JSON_HEDLEY_IS_CONSTEXPR_
23811 #undef JSON_HEDLEY_LIKELY
23812 #undef JSON_HEDLEY_MALLOC
23813 #undef JSON_HEDLEY_MCST_LCC_VERSION
23814 #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK
23815 #undef JSON_HEDLEY_MESSAGE
23816 #undef JSON_HEDLEY_MSVC_VERSION
23817 #undef JSON_HEDLEY_MSVC_VERSION_CHECK
23818 #undef JSON_HEDLEY_NEVER_INLINE
23819 #undef JSON_HEDLEY_NON_NULL
23820 #undef JSON_HEDLEY_NO_ESCAPE
23821 #undef JSON_HEDLEY_NO_RETURN
23822 #undef JSON_HEDLEY_NO_THROW
23823 #undef JSON_HEDLEY_NULL
23824 #undef JSON_HEDLEY_PELLES_VERSION
23825 #undef JSON_HEDLEY_PELLES_VERSION_CHECK
23826 #undef JSON_HEDLEY_PGI_VERSION
23827 #undef JSON_HEDLEY_PGI_VERSION_CHECK
23828 #undef JSON_HEDLEY_PREDICT
23829 #undef JSON_HEDLEY_PRINTF_FORMAT
23830 #undef JSON_HEDLEY_PRIVATE
23831 #undef JSON_HEDLEY_PUBLIC
23832 #undef JSON_HEDLEY_PURE
23833 #undef JSON_HEDLEY_REINTERPRET_CAST
23834 #undef JSON_HEDLEY_REQUIRE
23835 #undef JSON_HEDLEY_REQUIRE_CONSTEXPR
23836 #undef JSON_HEDLEY_REQUIRE_MSG
23837 #undef JSON_HEDLEY_RESTRICT
23838 #undef JSON_HEDLEY_RETURNS_NON_NULL
23839 #undef JSON_HEDLEY_SENTINEL
23840 #undef JSON_HEDLEY_STATIC_ASSERT
23841 #undef JSON_HEDLEY_STATIC_CAST
23842 #undef JSON_HEDLEY_STRINGIFY
23843 #undef JSON_HEDLEY_STRINGIFY_EX
23844 #undef JSON_HEDLEY_SUNPRO_VERSION
23845 #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK
23846 #undef JSON_HEDLEY_TINYC_VERSION
23847 #undef JSON_HEDLEY_TINYC_VERSION_CHECK
23848 #undef JSON_HEDLEY_TI_ARMCL_VERSION
23849 #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK
23850 #undef JSON_HEDLEY_TI_CL2000_VERSION
23851 #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK
23852 #undef JSON_HEDLEY_TI_CL430_VERSION
23853 #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK
23854 #undef JSON_HEDLEY_TI_CL6X_VERSION
23855 #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK
23856 #undef JSON_HEDLEY_TI_CL7X_VERSION
23857 #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK
23858 #undef JSON_HEDLEY_TI_CLPRU_VERSION
23859 #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK
23860 #undef JSON_HEDLEY_TI_VERSION
23861 #undef JSON_HEDLEY_TI_VERSION_CHECK
23862 #undef JSON_HEDLEY_UNAVAILABLE
23863 #undef JSON_HEDLEY_UNLIKELY
23864 #undef JSON_HEDLEY_UNPREDICTABLE
23865 #undef JSON_HEDLEY_UNREACHABLE
23866 #undef JSON_HEDLEY_UNREACHABLE_RETURN
23867 #undef JSON_HEDLEY_VERSION
23868 #undef JSON_HEDLEY_VERSION_DECODE_MAJOR
23869 #undef JSON_HEDLEY_VERSION_DECODE_MINOR
23870 #undef JSON_HEDLEY_VERSION_DECODE_REVISION
23871 #undef JSON_HEDLEY_VERSION_ENCODE
23872 #undef JSON_HEDLEY_WARNING
23873 #undef JSON_HEDLEY_WARN_UNUSED_RESULT
23874 #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG
23875 #undef JSON_HEDLEY_FALL_THROUGH
23876 
23877 
23878 
23879 #endif // INCLUDE_NLOHMANN_JSON_HPP_
a class to store JSON values
Definition: json.h:18647
void insert(const_iterator first, const_iterator last)
inserts range of elements into object
Definition: json.h:21875
detail::parser_callback_t< basic_json > parser_callback_t
per-element parser callback type
Definition: json.h:19343
const_reference operator[](const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.h:23096
reference operator[](const json_pointer &ptr)
access specified element via JSON Pointer
Definition: json.h:23082
constexpr bool is_number_float() const noexcept
return whether value is a floating-point number
Definition: json.h:19888
const_reference operator[](T *key) const
Definition: json.h:20702
NumberIntegerType number_integer_t
a type for a number (integer)
Definition: json.h:18904
void update(const_reference j, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.h:21900
::nlohmann::json_pointer< StringType > json_pointer
JSON Pointer, see nlohmann::json_pointer.
Definition: json.h:18713
ReferenceType get_ref()
get a reference value (implicit)
Definition: json.h:20372
reference emplace_back(Args &&... args)
add an object to an array
Definition: json.h:21701
basic_json(const value_t v)
create an empty value with a given type
Definition: json.h:19356
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.h:19770
iterator find(KeyType &&key)
find an element in a JSON object
Definition: json.h:21170
value_type & reference
the type of an element reference
Definition: json.h:18758
void erase(const size_type idx)
remove element from a JSON array given an index
Definition: json.h:21110
detail::out_of_range out_of_range
Definition: json.h:18739
const_reference at(const typename object_t::key_type &key) const
access specified object element with bounds checking
Definition: json.h:20561
reference at(const typename object_t::key_type &key)
access specified object element with bounds checking
Definition: json.h:20523
basic_json(InputIT first, InputIT last)
construct a JSON container given an iterator range
Definition: json.h:19571
basic_json(const JsonRef &ref)
Definition: json.h:19681
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.h:22745
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json array(initializer_list_t init={})
explicitly create an array from an initializer list
Definition: json.h:19543
reference back()
access the last element
Definition: json.h:20896
static void to_bjdata(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.h:22791
StringType string_t
a type for a string
Definition: json.h:18896
void push_back(const basic_json &val)
add an object to an array
Definition: json.h:21613
reference at(KeyType &&key)
access specified object element with bounds checking
Definition: json.h:20543
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json meta()
returns version information on the library
Definition: json.h:18797
ValueType value(const json_pointer &ptr, const ValueType &default_value) const
access specified object element via JSON Pointer with default value
Definition: json.h:20836
ObjectType< StringType, basic_json, default_object_comparator_t, AllocatorType< std::pair< const StringType, basic_json > >> object_t
a type for an object
Definition: json.h:18888
std::size_t size_type
a type to represent container sizes
Definition: json.h:18765
std::ptrdiff_t difference_type
a type to represent differences between iterators
Definition: json.h:18763
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.h:19499
reference operator+=(basic_json &&val)
add an object to an array
Definition: json.h:21605
basic_json(const BasicJsonType &val)
create a JSON value from an existing one
Definition: json.h:19390
typename std::allocator_traits< allocator_type >::const_pointer const_pointer
the type of an element const pointer
Definition: json.h:18773
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.h:23037
size_type count(const typename object_t::key_type &key) const
returns the number of occurrences of a key in a JSON object
Definition: json.h:21200
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(InputType &&i, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.h:22992
typename std::allocator_traits< allocator_type >::pointer pointer
the type of an element pointer
Definition: json.h:18771
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.h:22824
BooleanType boolean_t
a type for a boolean
Definition: json.h:18900
void push_back(initializer_list_t init)
add an object to an object
Definition: json.h:21676
JSON_HEDLEY_RETURNS_NON_NULL const char * type_name() const noexcept
return the type as string
Definition: json.h:22646
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.h:19810
reference operator[](typename object_t::key_type key)
access specified object element
Definition: json.h:20658
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.h:20917
const_iterator find(const typename object_t::key_type &key) const
find an element in a JSON object
Definition: json.h:21154
static void to_bson(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a BSON serialization of a given JSON value
Definition: json.h:22808
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.h:23022
constexpr bool is_structured() const noexcept
return whether type is structured
Definition: json.h:19846
void update(const_iterator first, const_iterator last, bool merge_objects=false)
updates a JSON object from another object, overwriting existing keys
Definition: json.h:21907
JSON_PRIVATE_UNLESS_TESTED const_reference bool static SAX bool sax_parse(InputType &&i, SAX *sax, input_format_t format=input_format_t::json, const bool strict=true, const bool ignore_comments=false)
Definition: json.h:22570
reference at(size_type idx)
access specified array element with bounds checking
Definition: json.h:20477
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.h:19532
constexpr bool is_primitive() const noexcept
return whether type is primitive
Definition: json.h:19839
constexpr bool is_number_unsigned() const noexcept
return whether value is an unsigned integer number
Definition: json.h:19881
static void to_cbor(const basic_json &j, detail::output_adapter< char > o)
create a CBOR serialization of a given JSON value
Definition: json.h:22715
void swap(object_t &other)
exchanges the values
Definition: json.h:21998
constexpr bool is_object() const noexcept
return whether value is an object
Definition: json.h:19895
bool contains(KeyType &&key) const
check the existence of an element in a JSON object
Definition: json.h:21227
reference operator[](KeyType &&key)
access specified object element
Definition: json.h:20711
const_reference front() const
access the first element
Definition: json.h:20889
static std::vector< std::uint8_t > to_bson(const basic_json &j)
create a BSON serialization of a given JSON value
Definition: json.h:22799
constexpr value_t type() const noexcept
return the type of the JSON value (explicit)
Definition: json.h:19832
NumberFloatType number_float_t
a type for a number (floating-point)
Definition: json.h:18912
json_reverse_iterator< typename basic_json::iterator > reverse_iterator
a reverse iterator for a basic_json container
Definition: json.h:18780
basic_json(const basic_json &other)
copy constructor
Definition: json.h:19685
~basic_json() noexcept
destructor
Definition: json.h:19791
friend std::istream & operator<<(basic_json &j, std::istream &i)
deserialize from stream
Definition: json.h:22624
const_iterator find(KeyType &&key) const
find an element in a JSON object
Definition: json.h:21186
basic_json(basic_json &&other) noexcept
move constructor
Definition: json.h:19753
bool contains(const typename object_t::key_type &key) const
check the existence of an element in a JSON object
Definition: json.h:21218
static void to_ubjson(const basic_json &j, detail::output_adapter< char > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.h:22764
static std::vector< std::uint8_t > to_bjdata(const basic_json &j, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.h:22772
iterator insert(const_iterator pos, size_type cnt, const basic_json &val)
inserts copies of element into array
Definition: json.h:21804
json_value m_value
the value of the current element
Definition: json.h:22682
void swap(typename binary_t::container_type &other)
exchanges the values
Definition: json.h:22043
void swap(array_t &other)
exchanges the values
Definition: json.h:21983
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.h:19510
static std::vector< std::uint8_t > to_cbor(const basic_json &j)
create a CBOR serialization of a given JSON value
Definition: json.h:22699
std::less< StringType > default_object_comparator_t
default object key comparator type The actual object key comparator type (object_comparator_t) may be...
Definition: json.h:18879
ReferenceType get_ref() const
get a reference value (implicit)
Definition: json.h:20383
const_reference at(KeyType &&key) const
access specified object element with bounds checking
Definition: json.h:20581
std::decay< ValueType >::type value(const KeyType &key, ValueType &&default_value) const
access specified object element with default value
Definition: json.h:20755
iterator insert(const_iterator pos, const_iterator first, const_iterator last)
inserts range of elements into array
Definition: json.h:21824
auto get() noexcept -> decltype(std::declval< basic_json_t & >().template get_ptr< PointerType >())
get a pointer value (explicit)
Definition: json.h:20323
const_reference at(const json_pointer &ptr) const
access specified element via JSON Pointer
Definition: json.h:23124
void merge_patch(const basic_json &apply_patch)
applies a JSON Merge Patch
Definition: json.h:23581
auto get_ptr() noexcept -> decltype(std::declval< basic_json_t & >().get_impl_ptr(std::declval< PointerType >()))
get a pointer value (implicit)
Definition: json.h:20083
iterator insert(const_iterator pos, initializer_list_t ilist)
inserts elements from initializer list into array
Definition: json.h:21855
ArrayType< basic_json, AllocatorType< basic_json > > array_t
a type for an array
Definition: json.h:18892
Array get_to(T(&v)[N]) const noexcept(noexcept(JSONSerializer< Array >::from_json(std::declval< const basic_json_t & >(), v)))
Definition: json.h:20360
const_reference operator[](KeyType &&key) const
access specified object element
Definition: json.h:20735
IteratorType erase(IteratorType first, IteratorType last)
remove elements given an iterator range
Definition: json.h:20987
constexpr bool is_boolean() const noexcept
return whether value is a boolean
Definition: json.h:19860
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.h:21954
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.h:22898
constexpr bool is_binary() const noexcept
return whether value is a binary array
Definition: json.h:19916
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) const _reference operator[](const
access specified element via JSON Pointer
Definition: json.h:23102
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json object(initializer_list_t init={})
explicitly create an object from an initializer list
Definition: json.h:19551
iterator insert(const_iterator pos, basic_json &&val)
inserts element into array
Definition: json.h:21797
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.h:22952
reference operator[](size_type idx)
access specified array element
Definition: json.h:20599
static void to_bson(const basic_json &j, detail::output_adapter< char > o)
create a BSON serialization of a given JSON value
Definition: json.h:22815
string_t value(KeyType &&key, const char *default_value) const
access specified object element with default value
Definition: json.h:20827
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.h:20336
void swap(binary_t &other)
exchanges the values
Definition: json.h:22028
iter_impl< basic_json > iterator
an iterator for a basic_json container
Definition: json.h:18776
json_reverse_iterator< typename basic_json::const_iterator > const_reverse_iterator
a const reverse iterator for a basic_json container
Definition: json.h:18782
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.h:22937
static void to_ubjson(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a UBJSON serialization of a given JSON value
Definition: json.h:22756
binary_t & get_binary()
get a binary value
Definition: json.h:20442
string_t value(const char *key, const char *default_value) const
Definition: json.h:20792
size_type count(KeyType &&key) const
returns the number of occurrences of a key in a JSON object
Definition: json.h:21210
void swap(string_t &other)
exchanges the values
Definition: json.h:22013
const_reference back() const
access the last element
Definition: json.h:20905
friend std::istream & operator>>(std::istream &i, basic_json &j)
deserialize from stream
Definition: json.h:22631
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json binary(typename binary_t::container_type &&init)
explicitly create a binary array
Definition: json.h:19521
constexpr bool is_string() const noexcept
return whether value is a string
Definition: json.h:19909
constexpr bool is_array() const noexcept
return whether value is an array
Definition: json.h:19902
iterator insert_iterator(const_iterator pos, Args &&... args)
Definition: json.h:21758
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) ValueType value(const
access specified object element via JSON Pointer with default value
Definition: json.h:20857
const value_type & const_reference
the type of an element const reference
Definition: json.h:18760
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.h:22840
const binary_t & get_binary() const
get a binary value
Definition: json.h:20454
reference operator[](T *key)
Definition: json.h:20696
constexpr bool is_number() const noexcept
return whether value is a number
Definition: json.h:19867
std::pair< iterator, bool > emplace(Args &&... args)
add an object to an object if key does not exist
Definition: json.h:21726
reference operator+=(initializer_list_t init)
add an object to an object
Definition: json.h:21692
constexpr bool is_number_integer() const noexcept
return whether value is an integer number
Definition: json.h:19874
std::initializer_list< detail::json_ref< basic_json > > initializer_list_t
helper type for initializer lists of basic_json values
Definition: json.h:18721
static void to_cbor(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a CBOR serialization of a given JSON value
Definition: json.h:22708
detail::value_t value_t
Definition: json.h:18711
ValueType & get_to(ValueType &v) const
Definition: json.h:20349
size_type erase(KeyType &&key)
remove element from a JSON object given a key
Definition: json.h:21103
static void to_msgpack(const basic_json &j, detail::output_adapter< char > o)
create a MessagePack serialization of a given JSON value
Definition: json.h:22738
const_reference operator[](const typename object_t::key_type &key) const
access specified object element
Definition: json.h:20680
std::decay< ValueType >::type value(const char *key, ValueType &&default_value) const
Definition: json.h:20787
detail::actual_object_comparator_t< basic_json > object_comparator_t
object key comparator type
Definition: json.h:18920
basic_json(std::nullptr_t=nullptr) noexcept
create a null object
Definition: json.h:19364
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json from_bjdata(IteratorType first, IteratorType last, const bool strict=true, const bool allow_exceptions=true)
create a JSON value from an input in BJData format
Definition: json.h:23007
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) reference operator[](const
Definition: json.h:23088
const_reference operator[](size_type idx) const
access specified array element
Definition: json.h:20645
AllocatorType< basic_json > allocator_type
the allocator type
Definition: json.h:18768
nlohmann::byte_container_with_subtype< BinaryType > binary_t
a type for a packed binary type
Definition: json.h:18916
JSONSerializer< T, SFINAE > json_serializer
Definition: json.h:18715
void push_back(const typename object_t::value_type &val)
add an object to an object
Definition: json.h:21645
JSON_HEDLEY_DEPRECATED_FOR(3.11.0, basic_json::json_pointer or nlohmann::json_pointer< basic_json::string_t >) reference at(const
Definition: json.h:23116
JSON_PRIVATE_UNLESS_TESTED const_reference rhs
Definition: json.h:22144
bool contains(const json_pointer &ptr) const
check the existence of an element in a JSON object given a JSON pointer
Definition: json.h:21234
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.h:22883
string_t value(const typename object_t::key_type &key, const char *default_value) const
access specified object element with default value
Definition: json.h:20776
std::decay< ValueType >::type value(KeyType &&key, ValueType &&default_value) const
access specified object element with default value
Definition: json.h:20804
basic_json(CompatibleType &&val) noexcept(noexcept(//NOLINT(bugprone-forwarding-reference-overload, bugprone-exception-escape) JSONSerializer< U >::to_json(std::declval< basic_json_t & >(), std::forward< CompatibleType >(val))))
create a JSON value from compatible types
Definition: json.h:19376
NumberUnsignedType number_unsigned_t
a type for a number (unsigned)
Definition: json.h:18908
iterator find(const typename object_t::key_type &key)
find an element in a JSON object
Definition: json.h:21140
reference operator+=(const typename object_t::value_type &val)
add an object to an object
Definition: json.h:21668
static std::vector< std::uint8_t > to_msgpack(const basic_json &j)
create a MessagePack serialization of a given JSON value
Definition: json.h:22722
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.h:19443
const_reference at(size_type idx) const
access specified array element with bounds checking
Definition: json.h:20500
iterator insert(const_iterator pos, const basic_json &val)
inserts element into array
Definition: json.h:21777
iter_impl< const basic_json > const_iterator
a const iterator for a basic_json container
Definition: json.h:18778
constexpr bool is_discarded() const noexcept
return whether value is discarded
Definition: json.h:19923
constexpr bool is_null() const noexcept
return whether value is null
Definition: json.h:19853
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.h:21971
static void to_bjdata(const basic_json &j, detail::output_adapter< std::uint8_t > o, const bool use_size=false, const bool use_type=false)
create a BJData serialization of a given JSON value
Definition: json.h:22783
JSON_PRIVATE_UNLESS_TESTED const_reference bool inverse
Definition: json.h:22144
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.h:20282
static void to_msgpack(const basic_json &j, detail::output_adapter< std::uint8_t > o)
create a MessagePack serialization of a given JSON value
Definition: json.h:22731
reference operator+=(const basic_json &val)
add an object to an array
Definition: json.h:21637
size_type erase(const typename object_t::key_type &key)
remove element from a JSON object given a key
Definition: json.h:21092
basic_json(size_type cnt, const basic_json &val)
construct an array with count copies of given value
Definition: json.h:19558
static allocator_type get_allocator()
returns the allocator associated with the container
Definition: json.h:18789
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.h:20094
an internal type for a backed binary type
Definition: json.h:5494
byte_container_with_subtype(const container_type &b, subtype_type subtype_) noexcept(noexcept(container_type(b)))
Definition: json.h:5515
byte_container_with_subtype(const container_type &b) noexcept(noexcept(container_type(b)))
Definition: json.h:5505
byte_container_with_subtype(container_type &&b) noexcept(noexcept(container_type(std::move(b))))
Definition: json.h:5510
bool operator!=(const byte_container_with_subtype &rhs) const
Definition: json.h:5534
void clear_subtype() noexcept
clears the binary subtype
Definition: json.h:5563
byte_container_with_subtype() noexcept(noexcept(container_type()))
Definition: json.h:5500
byte_container_with_subtype(container_type &&b, subtype_type subtype_) noexcept(noexcept(container_type(std::move(b))))
Definition: json.h:5522
constexpr bool has_subtype() const noexcept
return whether the value has a subtype
Definition: json.h:5556
void set_subtype(subtype_type subtype_) noexcept
sets the binary subtype
Definition: json.h:5541
constexpr subtype_type subtype() const noexcept
return the binary subtype
Definition: json.h:5549
bool operator==(const byte_container_with_subtype &rhs) const
Definition: json.h:5528
deserialization of CBOR, MessagePack, and UBJSON values
Definition: json.h:8765
binary_reader(InputAdapterType &&adapter, const input_format_t format=input_format_t::json) noexcept
create a binary reader
Definition: json.h:8781
binary_reader & operator=(const binary_reader &)=delete
binary_reader(const binary_reader &)=delete
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.h:8802
binary_reader(binary_reader &&)=default
binary_reader & operator=(binary_reader &&)=default
serialization to CBOR and MessagePack values
Definition: json.h:14353
void write_ubjson(const BasicJsonType &j, const bool use_count, const bool use_type, const bool add_prefix=true, const bool use_bjdata=false)
Definition: json.h:15052
static constexpr CharType to_char_type(InputCharType x) noexcept
Definition: json.h:16137
binary_writer(output_adapter_t< CharType > adapter)
create a binary writer
Definition: json.h:14364
static CharType to_char_type(std::uint8_t x) noexcept
Definition: json.h:16115
void write_bson(const BasicJsonType &j)
Definition: json.h:14373
void write_cbor(const BasicJsonType &j)
Definition: json.h:14402
static constexpr CharType to_char_type(std::uint8_t x) noexcept
Definition: json.h:16108
void write_msgpack(const BasicJsonType &j)
Definition: json.h:14726
general exception of the basic_json class
Definition: json.h:4032
const char * what() const noexcept override
returns the explanatory string
Definition: json.h:4035
const int id
the id of the exception
Definition: json.h:4041
static std::string diagnostics(std::nullptr_t)
Definition: json.h:4052
static std::string diagnostics(const BasicJsonType *leaf_element)
Definition: json.h:4058
static std::string name(const std::string &ename, int id_)
Definition: json.h:4047
std::char_traits< char >::int_type get_character() noexcept
Definition: json.h:5783
file_input_adapter(const file_input_adapter &)=delete
file_input_adapter(file_input_adapter &&) noexcept=default
input_stream_adapter(input_stream_adapter &&rhs) noexcept
Definition: json.h:5827
input_stream_adapter & operator=(input_stream_adapter &&)=delete
input_stream_adapter(const input_stream_adapter &)=delete
std::char_traits< char >::int_type get_character()
Definition: json.h:5837
input_stream_adapter & operator=(input_stream_adapter &)=delete
input_stream_adapter(std::istream &i)
Definition: json.h:5818
exception indicating errors with iterators
Definition: json.h:4183
static invalid_iterator create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.h:4186
a template for a bidirectional iterator for the basic_json class This class implements a both iterato...
Definition: json.h:12383
bool operator<(const iter_impl &other) const
comparison: smaller
Definition: json.h:12849
iter_impl operator-(difference_type i) const
subtract from iterator
Definition: json.h:12979
const object_t::key_type & key() const
return the key of an object iterator
Definition: json.h:13057
bool operator!=(const IterImpl &other) const
comparison: not equal
Definition: json.h:12840
void set_end() noexcept
set the iterator past the last value
Definition: json.h:12576
typename BasicJsonType::difference_type difference_type
a type to represent differences between iterators
Definition: json.h:12413
iter_impl & operator+=(difference_type i)
add to iterator
Definition: json.h:12911
difference_type operator-(const iter_impl &other) const
return difference
Definition: json.h:12990
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.h:12422
reference operator*() const
return a reference to the value pointed to by the iterator
Definition: json.h:12615
iter_impl(iter_impl &&) noexcept=default
bool operator>=(const iter_impl &other) const
comparison: greater than or equal
Definition: json.h:12902
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.h:12417
pointer operator->() const
dereference the iterator
Definition: json.h:12659
iter_impl & operator=(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting assignment
Definition: json.h:12520
iter_impl(const iter_impl< const BasicJsonType > &other) noexcept
const copy constructor
Definition: json.h:12485
iter_impl & operator--()
pre-decrement (–it)
Definition: json.h:12763
iter_impl(const iter_impl< typename std::remove_const< BasicJsonType >::type > &other) noexcept
converting constructor
Definition: json.h:12510
internal_iterator< typename std::remove_const< BasicJsonType >::type > m_it
the actual iterator of the associated instance
Definition: json.h:13082
iter_impl operator+(difference_type i) const
add to iterator
Definition: json.h:12957
friend iter_impl operator+(difference_type i, const iter_impl &it)
addition of distance and iterator
Definition: json.h:12968
iter_impl & operator=(const iter_impl< const BasicJsonType > &other) noexcept
converting assignment
Definition: json.h:12495
bool operator==(const IterImpl &other) const
comparison: equal
Definition: json.h:12804
bool operator>(const iter_impl &other) const
comparison: greater than
Definition: json.h:12893
typename BasicJsonType::value_type value_type
the type of the values when the iterator is dereferenced
Definition: json.h:12411
reference value() const
return the value of an iterator
Definition: json.h:13073
iter_impl & operator-=(difference_type i)
subtract from iterator
Definition: json.h:12948
iter_impl & operator++()
pre-increment (++it)
Definition: json.h:12712
reference operator[](difference_type n) const
access to successor
Definition: json.h:13019
bool operator<=(const iter_impl &other) const
comparison: less than or equal
Definition: json.h:12884
iter_impl operator++(int) &
post-increment (it++)
Definition: json.h:12701
std::bidirectional_iterator_tag iterator_category
Definition: json.h:12408
iter_impl operator--(int) &
post-decrement (it–)
Definition: json.h:12752
std::input_iterator_tag iterator_category
Definition: json.h:4803
typename std::remove_cv< typename std::remove_reference< decltype(std::declval< IteratorType >().key()) >::type >::type string_type
Definition: json.h:4804
iteration_proxy_value(iteration_proxy_value const &)=default
bool operator!=(const iteration_proxy_value &o) const
inequality operator (needed for range-based for)
Definition: json.h:4868
iteration_proxy_value(IteratorType it, std::size_t array_index_=0) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_default_constructible< string_type >::value)
Definition: json.h:4820
iteration_proxy_value operator++(int) &
Definition: json.h:4853
IteratorType::reference value() const
return value of the iterator
Definition: json.h:4910
iteration_proxy_value & operator++()
increment operator (needed for range-based for)
Definition: json.h:4845
iteration_proxy_value & operator=(iteration_proxy_value const &)=default
const string_type & key() const
return key of the iterator
Definition: json.h:4874
bool operator==(const iteration_proxy_value &o) const
equality operator (needed for InputIterator)
Definition: json.h:4862
iteration_proxy_value(iteration_proxy_value &&) noexcept(std::is_nothrow_move_constructible< IteratorType >::value &&std::is_nothrow_move_constructible< string_type >::value)=default
proxy class for the items() function
Definition: json.h:4918
iteration_proxy(iteration_proxy &&) noexcept=default
iteration_proxy_value< IteratorType > end() const noexcept
return iterator end (needed for range-based for)
Definition: json.h:4943
iteration_proxy_value< IteratorType > begin() const noexcept
return iterator begin (needed for range-based for)
Definition: json.h:4937
iteration_proxy & operator=(iteration_proxy const &)=default
iteration_proxy(iteration_proxy const &)=default
iteration_proxy(typename IteratorType::reference cont) noexcept
construct iteration proxy from a container
Definition: json.h:4927
std::char_traits< char_type >::int_type get_character()
Definition: json.h:5867
typename std::iterator_traits< IteratorType >::value_type char_type
Definition: json.h:5861
iterator_input_adapter(IteratorType first, IteratorType last)
Definition: json.h:5863
json_ref(json_ref &&) noexcept=default
BasicJsonType value_type
Definition: json.h:14114
json_ref(Args &&... args)
Definition: json.h:14131
json_ref(const value_type &value)
Definition: json.h:14120
value_type const & operator*() const
Definition: json.h:14151
value_type const * operator->() const
Definition: json.h:14156
json_ref(std::initializer_list< json_ref > init)
Definition: json.h:14124
json_ref(value_type &&value)
Definition: json.h:14116
value_type moved_or_copied() const
Definition: json.h:14142
a template for a reverse iterator class
Definition: json.h:13124
json_reverse_iterator(const typename base_iterator::iterator_type &it) noexcept
create reverse iterator from iterator
Definition: json.h:13133
json_reverse_iterator & operator--()
pre-decrement (–it)
Definition: json.h:13158
json_reverse_iterator & operator++()
pre-increment (++it)
Definition: json.h:13146
typename Base::reference reference
the reference type for the pointed-to element
Definition: json.h:13130
json_reverse_iterator & operator+=(difference_type i)
add to iterator
Definition: json.h:13164
json_reverse_iterator operator-(difference_type i) const
subtract from iterator
Definition: json.h:13176
std::reverse_iterator< Base > base_iterator
shortcut to the reverse iterator adapter
Definition: json.h:13128
json_reverse_iterator(const base_iterator &it) noexcept
create reverse iterator from base class
Definition: json.h:13137
reference operator[](difference_type n) const
access to successor
Definition: json.h:13188
json_reverse_iterator operator--(int) &
post-decrement (it–)
Definition: json.h:13152
difference_type operator-(const json_reverse_iterator &other) const
return difference
Definition: json.h:13182
json_reverse_iterator operator+(difference_type i) const
add to iterator
Definition: json.h:13170
json_reverse_iterator operator++(int) &
post-increment (it++)
Definition: json.h:13140
auto key() const -> decltype(std::declval< Base >().key())
return the key of an object iterator
Definition: json.h:13194
reference value() const
return the value of an iterator
Definition: json.h:13201
bool start_object(std::size_t=static_cast< std::size_t >(-1))
Definition: json.h:6906
typename BasicJsonType::string_t string_t
Definition: json.h:6868
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.h:6865
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:6867
typename BasicJsonType::binary_t binary_t
Definition: json.h:6869
bool start_array(std::size_t=static_cast< std::size_t >(-1))
Definition: json.h:6921
bool parse_error(std::size_t, const std::string &, const detail::exception &)
Definition: json.h:6931
bool number_integer(number_integer_t)
Definition: json.h:6881
bool number_unsigned(number_unsigned_t)
Definition: json.h:6886
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.h:6866
bool number_float(number_float_t, const string_t &)
Definition: json.h:6891
typename BasicJsonType::string_t string_t
Definition: json.h:6561
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.h:6559
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.h:6558
typename BasicJsonType::parser_callback_t parser_callback_t
Definition: json.h:6563
json_sax_dom_callback_parser(const json_sax_dom_callback_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition: json.h:6562
json_sax_dom_callback_parser & operator=(const json_sax_dom_callback_parser &)=delete
json_sax_dom_callback_parser & operator=(json_sax_dom_callback_parser &&)=default
bool number_integer(number_integer_t val)
Definition: json.h:6593
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:6560
typename BasicJsonType::parse_event_t parse_event_t
Definition: json.h:6564
bool number_unsigned(number_unsigned_t val)
Definition: json.h:6599
bool number_float(number_float_t val, const string_t &)
Definition: json.h:6605
json_sax_dom_callback_parser(json_sax_dom_callback_parser &&)=default
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.h:6744
json_sax_dom_callback_parser(BasicJsonType &r, const parser_callback_t cb, const bool allow_exceptions_=true)
Definition: json.h:6566
SAX implementation to create a JSON value from SAX events.
Definition: json.h:6373
bool start_array(std::size_t len)
Definition: json.h:6471
json_sax_dom_parser(const json_sax_dom_parser &)=delete
typename BasicJsonType::binary_t binary_t
Definition: json.h:6379
bool number_unsigned(number_unsigned_t val)
Definition: json.h:6415
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.h:6375
bool parse_error(std::size_t, const std::string &, const Exception &ex)
Definition: json.h:6494
bool string(string_t &val)
Definition: json.h:6427
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.h:6376
json_sax_dom_parser & operator=(const json_sax_dom_parser &)=delete
bool start_object(std::size_t len)
Definition: json.h:6439
bool binary(binary_t &val)
Definition: json.h:6433
constexpr bool is_errored() const
Definition: json.h:6506
json_sax_dom_parser(json_sax_dom_parser &&)=default
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:6377
bool number_float(number_float_t val, const string_t &)
Definition: json.h:6421
json_sax_dom_parser(BasicJsonType &r, const bool allow_exceptions_=true)
Definition: json.h:6386
typename BasicJsonType::string_t string_t
Definition: json.h:6378
bool number_integer(number_integer_t val)
Definition: json.h:6409
json_sax_dom_parser & operator=(json_sax_dom_parser &&)=default
token_type
token types for the parser
Definition: json.h:6974
@ 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)
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.h:6997
lexical analysis
Definition: json.h:7047
lexer & operator=(lexer &&)=default
token_type scan()
Definition: json.h:8444
void skip_whitespace()
Definition: json.h:8435
string_t & get_string()
return current string value (implicitly resets the token; useful only once)
Definition: json.h:8365
bool skip_bom()
skip the UTF-8 byte order mark
Definition: json.h:8421
lexer(InputAdapterType &&adapter, bool ignore_comments_=false) noexcept
Definition: json.h:7058
constexpr position_t get_position() const noexcept
return position of last read token
Definition: json.h:8375
constexpr number_integer_t get_number_integer() const noexcept
return integer value
Definition: json.h:8347
constexpr JSON_HEDLEY_RETURNS_NON_NULL const char * get_error_message() const noexcept
return syntax error message
Definition: json.h:8408
typename lexer_base< BasicJsonType >::token_type token_type
Definition: json.h:7056
lexer(const lexer &)=delete
constexpr number_unsigned_t get_number_unsigned() const noexcept
return unsigned integer value
Definition: json.h:8353
constexpr number_float_t get_number_float() const noexcept
return floating-point value
Definition: json.h:8359
std::string get_token_string() const
Definition: json.h:8383
lexer(lexer &&)=default
lexer & operator=(lexer &)=delete
exception indicating other library errors
Definition: json.h:4235
static other_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.h:4238
exception indicating access out of the defined range
Definition: json.h:4218
static out_of_range create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.h:4221
output_adapter(std::basic_ostream< CharType > &s)
Definition: json.h:14319
output_adapter(std::vector< CharType, AllocatorType > &vec)
Definition: json.h:14315
output_adapter(StringType &s)
Definition: json.h:14323
output adapter for output streams
Definition: json.h:14264
void write_character(CharType c) override
Definition: json.h:14270
output_stream_adapter(std::basic_ostream< CharType > &s) noexcept
Definition: json.h:14266
output adapter for basic_string
Definition: json.h:14289
void write_character(CharType c) override
Definition: json.h:14295
output_string_adapter(StringType &s) noexcept
Definition: json.h:14291
output adapter for byte vectors
Definition: json.h:14239
output_vector_adapter(std::vector< CharType, AllocatorType > &vec) noexcept
Definition: json.h:14241
void write_character(CharType c) override
Definition: json.h:14245
exception indicating a parse error
Definition: json.h:4130
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, BasicJsonContext context)
create a parse error exception
Definition: json.h:4142
static parse_error create(int id_, std::size_t byte_, const std::string &what_arg, BasicJsonContext context)
Definition: json.h:4150
const std::size_t byte
byte index of the parse error
Definition: json.h:4167
syntax analysis
Definition: json.h:11736
bool sax_parse(SAX *sax, const bool strict=true)
Definition: json.h:11836
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.h:11746
bool accept(const bool strict=true)
public accept interface
Definition: json.h:11828
void parse(const bool strict, BasicJsonType &result)
public parser interface
Definition: json.h:11768
primitive_iterator_t operator+(difference_type n) noexcept
Definition: json.h:12260
primitive_iterator_t & operator-=(difference_type n) noexcept
Definition: json.h:12304
constexpr bool is_end() const noexcept
return whether the iterator is at end
Definition: json.h:12245
constexpr friend bool operator<(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.h:12255
constexpr friend difference_type operator-(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.h:12267
constexpr bool is_begin() const noexcept
return whether the iterator can be dereferenced
Definition: json.h:12239
primitive_iterator_t operator++(int) &noexcept
Definition: json.h:12278
void set_begin() noexcept
set iterator to a defined beginning
Definition: json.h:12227
primitive_iterator_t & operator--() noexcept
Definition: json.h:12285
primitive_iterator_t & operator++() noexcept
Definition: json.h:12272
void set_end() noexcept
set iterator to a defined past the end
Definition: json.h:12233
constexpr difference_type get_value() const noexcept
Definition: json.h:12221
primitive_iterator_t & operator+=(difference_type n) noexcept
Definition: json.h:12298
primitive_iterator_t operator--(int) &noexcept
Definition: json.h:12291
constexpr friend bool operator==(primitive_iterator_t lhs, primitive_iterator_t rhs) noexcept
Definition: json.h:12250
const error_handler_t error_handler
error_handler how to react on decoding errors
Definition: json.h:18248
const std::lconv * loc
the locale
Definition: json.h:18233
std::array< char, 64 > number_buffer
a (hopefully) large enough character buffer
Definition: json.h:18230
serializer(serializer &&)=delete
const char decimal_point
the locale's decimal point character
Definition: json.h:18237
serializer & operator=(const serializer &)=delete
const char thousands_sep
the locale's thousand separator character
Definition: json.h:18235
std::size_t undumped_chars
Definition: json.h:17663
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.h:17371
const char indent_char
the indentation character
Definition: json.h:18243
std::size_t bytes_after_last_accept
Definition: json.h:17662
std::array< char, 512 > string_buffer
string buffer
Definition: json.h:18240
JSON_PRIVATE_UNLESS_TESTED const bool ensure_ascii
Definition: json.h:17656
serializer(output_adapter_t< char > s, const char ichar, error_handler_t error_handler_=error_handler_t::strict)
Definition: json.h:17331
serializer & operator=(serializer &&)=delete
serializer(const serializer &)=delete
string_t indent_string
the indentation string
Definition: json.h:18245
span_input_adapter(CharT b, std::size_t l)
Definition: json.h:6193
contiguous_bytes_input_adapter && get()
Definition: json.h:6203
span_input_adapter(IteratorType first, IteratorType last)
Definition: json.h:6200
exception indicating executing a member function with a wrong type
Definition: json.h:4201
static type_error create(int id_, const std::string &what_arg, BasicJsonContext context)
Definition: json.h:4204
std::char_traits< char >::int_type get_character() noexcept
Definition: json.h:6026
wide_string_input_adapter(BaseInputAdapter base)
Definition: json.h:6023
JSON Pointer defines a string syntax for identifying a specific value within a JSON document.
Definition: json.h:13243
friend json_pointer operator/(const json_pointer &lhs, string_t token)
create a new JSON pointer by appending the unescaped token at the end of the JSON pointer
Definition: json.h:13327
json_pointer & operator/=(const json_pointer &ptr)
append another JSON pointer at the end of this JSON pointer
Definition: json.h:13294
void pop_back()
remove last reference token
Definition: json.h:13355
json_pointer & operator/=(std::size_t array_idx)
append an array index at the end of this JSON pointer
Definition: json.h:13312
friend json_pointer operator/(const json_pointer &lhs, std::size_t array_idx)
create a new JSON pointer by appending the array-index-token at the end of the JSON pointer
Definition: json.h:13334
json_pointer parent_pointer() const
returns the parent of this JSON pointer
Definition: json.h:13341
bool empty() const noexcept
return whether pointer points to the root document
Definition: json.h:13393
const string_t & back() const
return last reference token
Definition: json.h:13367
void push_back(const string_t &token)
append an unescaped token at the end of the reference pointer
Definition: json.h:13379
typename string_t_helper< RefStringType >::type string_t
Definition: json.h:13265
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.h:13319
friend class json_pointer
Definition: json.h:13249
string_t to_string() const
return a string representation of the JSON pointer
Definition: json.h:13275
friend bool operator==(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
compares two JSON pointers for equality
Definition: json.h:14083
friend bool operator!=(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
compares two JSON pointers for inequality
Definition: json.h:14090
json_pointer(const string_t &s="")
create JSON pointer
Definition: json.h:13269
void push_back(string_t &&token)
append an unescaped token at the end of the reference pointer
Definition: json.h:13386
json_pointer & operator/=(string_t token)
append an unescaped reference token at the end of this JSON pointer
Definition: json.h:13304
decltype(get< N >(std::declval< ::nlohmann::detail::iteration_proxy_value< IteratorType > >())) type
Definition: json.h:4989
double max(void)
int errno
double min(void)
#define NLOHMANN_BASIC_JSON_TPL_DECLARATION
Definition: json.h:2453
#define JSON_HEDLEY_CONST
Definition: json.h:1609
#define JSON_HEDLEY_DIAGNOSTIC_PUSH
Definition: json.h:893
#define JSON_INLINE_VARIABLE
Definition: json.h:2356
#define JSON_HEDLEY_WARN_UNUSED_RESULT
Definition: json.h:1239
#define JSON_PRIVATE_UNLESS_TESTED
Definition: json.h:2416
#define NLOHMANN_JSON_VERSION_PATCH
Definition: json.h:52
#define JSON_HEDLEY_LIKELY(expr)
Definition: json.h:1504
#define JSON_HEDLEY_NON_NULL(...)
Definition: json.h:1397
#define JSON_INTERNAL_CATCH(exception)
Definition: json.h:2383
#define JSON_HEDLEY_RETURNS_NON_NULL
Definition: json.h:1838
#define JSON_CATCH(exception)
Definition: json.h:2382
#define JSON_ASSERT(x)
Definition: json.h:2409
#define JSON_THROW(exception)
Definition: json.h:2380
#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON
Definition: json.h:2684
#define NLOHMANN_JSON_VERSION_MAJOR
Definition: json.h:50
#define NLOHMANN_BASIC_JSON_TPL
Definition: json.h:2462
#define JSON_HEDLEY_UNLIKELY(expr)
Definition: json.h:1505
#define JSON_TRY
Definition: json.h:2381
#define JSON_NO_UNIQUE_ADDRESS
Definition: json.h:2362
#define NLOHMANN_JSON_VERSION_MINOR
Definition: json.h:51
#define JSON_HEDLEY_DIAGNOSTIC_POP
Definition: json.h:894
#define JSON_EXPLICIT
Definition: json.h:2674
#define JSON_HEDLEY_PURE
Definition: json.h:1578
#define JSON_IMPLEMENT_OPERATOR(op, null_result, unordered_result, default_result)
Definition: json.h:22067
std::vector< uint8_t > buffer
Target
The Target enum Specifies the target device of the command.
void grisu2(char *buf, int &len, int &decimal_exponent, diyfp m_minus, diyfp v, diyfp m_plus)
Definition: json.h:16991
Target reinterpret_bits(const Source source)
Definition: json.h:16211
boundaries compute_boundaries(FloatType value)
Definition: json.h:16352
int find_largest_pow10(const std::uint32_t n, std::uint32_t &pow10)
Definition: json.h:16655
constexpr int kGamma
Definition: json.h:16475
void grisu2_round(char *buf, int len, std::uint64_t dist, std::uint64_t delta, std::uint64_t rest, std::uint64_t ten_k)
Definition: json.h:16709
void grisu2_digit_gen(char *buffer, int &length, int &decimal_exponent, diyfp M_minus, diyfp w, diyfp M_plus)
Definition: json.h:16750
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.h:17143
constexpr int kAlpha
Definition: json.h:16474
JSON_HEDLEY_RETURNS_NON_NULL char * append_exponent(char *buf, int e)
appends a decimal representation of e to buf
Definition: json.h:17091
cached_power get_cached_power_for_binary_exponent(int e)
Definition: json.h:16491
detail namespace with internal helper functions
Definition: json.h:2167
std::integral_constant< bool, all_signed< Types... >::value||all_unsigned< Types... >::value > same_sign
Definition: json.h:3790
typename std::enable_if< B, T >::type enable_if_t
Definition: json.h:2922
typename T::reference reference_t
Definition: json.h:3285
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().data(), std::declval< const Arg & >().size())) string_can_append_data
Definition: json.h:3946
bool operator<(const value_t lhs, const value_t rhs) noexcept
comparison operator for JSON types
Definition: json.h:2757
typename actual_object_comparator< BasicJsonType >::type actual_object_comparator_t
Definition: json.h:3370
typename T::key_compare detect_key_compare
Definition: json.h:3354
std::integral_constant< bool,(std::is_signed< OfType >::value &&(sizeof(T)< sizeof(OfType)))||(same_sign< OfType, T >::value &&sizeof(OfType)==sizeof(T)) > never_out_of_range
Definition: json.h:3795
decltype(T::from_json(std::declval< Args >()...)) from_json_function
Definition: json.h:3294
is_detected< string_can_append_iter, StringType, Arg > detect_string_can_append_iter
Definition: json.h:3943
void to_json(BasicJsonType &j, T b) noexcept
Definition: json.h:5260
value_type_t< iterator_traits< iterator_t< T > >> range_value_t
Definition: json.h:3466
value_t
the JSON type enumeration
Definition: json.h:2728
@ number_integer
number value (signed integer)
@ discarded
discarded by the parser callback function
@ binary
binary array (ordered collection of bytes)
@ object
object (unordered set of name/value pairs)
@ number_float
number value (floating-point)
@ number_unsigned
number value (unsigned integer)
@ array
array (ordered collection of values)
void from_json(const BasicJsonType &j, typename std::nullptr_t &n)
Definition: json.h:4294
typename std::conditional< is_usable_as_key_type< typename BasicJsonType::object_comparator_t, typename BasicJsonType::object_t::key_type, KeyTypeCVRef, RequireTransparentComparator, ExcludeObjectKeyType >::value &&!is_json_iterator_of< BasicJsonType, KeyType >::value, std::true_type, std::false_type >::type is_usable_as_basic_json_key_type
Definition: json.h:3733
make_index_sequence< sizeof...(Ts)> index_sequence_for
Definition: json.h:3026
decltype(std::declval< T & >().parse_error(std::declval< std::size_t >(), std::declval< const std::string & >(), std::declval< const Exception & >())) parse_error_function_t
Definition: json.h:8634
typename T::pointer pointer_t
Definition: json.h:3282
decltype(std::declval< T & >().string(std::declval< String & >())) string_function_t
Definition: json.h:8607
is_detected< string_can_append, StringType, Arg > detect_string_can_append
Definition: json.h:3931
std::function< bool(int, parse_event_t, BasicJsonType &)> parser_callback_t
Definition: json.h:11727
typename T::difference_type difference_type_t
Definition: json.h:3279
typename detector< nonesuch, void, Op, Args... >::type detected_t
Definition: json.h:2216
void int_to_string(string_type &target, std::size_t value)
Definition: json.h:4790
void from_json_array_impl(const BasicJsonType &j, typename BasicJsonType::array_t &arr, priority_tag< 3 >)
Definition: json.h:4450
integer_sequence< size_t, Ints... > index_sequence
Definition: json.h:2964
decltype(std::declval< T & >().key(std::declval< String & >())) key_function_t
Definition: json.h:8619
decltype(std::declval< T & >().boolean(std::declval< bool >())) boolean_function_t
Definition: json.h:8591
decltype(std::declval< T & >().binary(std::declval< Binary & >())) binary_function_t
Definition: json.h:8611
decltype(std::declval< T & >().number_integer(std::declval< Integer >())) number_integer_function_t
Definition: json.h:8595
void to_json_tuple_impl(BasicJsonType &j, const Tuple &t, index_sequence< Idx... >)
Definition: json.h:5392
enable_if_t< is_range< R >::value, result_of_begin< decltype(std::declval< R & >())> > iterator_t
Definition: json.h:3463
std::is_convertible< detected_t< Op, Args... >, To > is_detected_convertible
Definition: json.h:2229
typename std::remove_cv< typename std::remove_reference< T >::type >::type uncvref_t
Definition: json.h:2908
decltype(std::declval< StringType & >().append(std::declval< Arg && >())) string_can_append
Definition: json.h:3928
cbor_tag_handler_t
how to treat CBOR tags
Definition: json.h:8737
@ 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.h:17308
@ strict
throw a type_error exception in case of invalid UTF-8
@ ignore
ignore invalid UTF-8 sequences
@ replace
replace invalid UTF-8 sequences with U+FFFD
decltype(std::declval< T & >().start_object(std::declval< std::size_t >())) start_object_function_t
Definition: json.h:8615
typename std::conditional< is_detected< detect_erase_with_key_type, typename BasicJsonType::object_t, KeyType >::value, std::true_type, std::false_type >::type has_erase_with_key_type
Definition: json.h:3745
typename T::key_type key_type_t
Definition: json.h:3273
std::size_t combine(std::size_t seed, std::size_t h) noexcept
Definition: json.h:5600
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.h:5618
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.h:17228
StringType escape(StringType s)
string escaping as described in RFC 6901 (Sect. 4)
Definition: json.h:2837
typename utility_internal::Gen< T, N >::type make_integer_sequence
Definition: json.h:3010
decltype(std::declval< T & >().number_unsigned(std::declval< Unsigned >())) number_unsigned_function_t
Definition: json.h:8599
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Definition: json.h:2225
typename std::conditional< is_comparable< Comparator, ObjectKeyType, KeyTypeCVRef >::value &&!(ExcludeObjectKeyType &&std::is_same< KeyType, ObjectKeyType >::value) &&(!RequireTransparentComparator||is_detected< detect_is_transparent, Comparator >::value) &&!is_json_pointer< KeyType >::value, std::true_type, std::false_type >::type is_usable_as_key_type
Definition: json.h:3717
typename detected_or< Default, Op, Args... >::type detected_or_t
Definition: json.h:2222
decltype(std::declval< T & >().start_array(std::declval< std::size_t >())) start_array_function_t
Definition: json.h:8626
constexpr bool value_in_range_of(T val)
Definition: json.h:3868
void concat_into(OutStringType &)
Definition: json.h:3924
void get_arithmetic_value(const BasicJsonType &j, ArithmeticType &val)
Definition: json.h:4308
void replace_substring(StringType &s, const StringType &f, const StringType &t)
replace all occurrences of a substring by another string
Definition: json.h:2818
std::array< T, sizeof...(Idx)> from_json_inplace_array_impl(BasicJsonType &&j, identity_tag< std::array< T, sizeof...(Idx)>>, index_sequence< Idx... >)
Definition: json.h:4533
typename detector< nonesuch, void, Op, Args... >::value_t is_detected
Definition: json.h:2210
is_detected< string_can_append_data, StringType, Arg > detect_string_can_append_data
Definition: json.h:3949
typename make_void< Ts... >::type void_t
Definition: json.h:2172
OutStringType concat(Args &&... args)
Definition: json.h:4008
make_integer_sequence< size_t, N > make_index_sequence
Definition: json.h:3018
std::shared_ptr< output_adapter_protocol< CharType > > output_adapter_t
a type to simplify interfaces
Definition: json.h:14234
typename T::mapped_type mapped_type_t
Definition: json.h:3270
input_format_t
the supported input formats
Definition: json.h:5755
void to_json(BasicJsonType &j, const T &b)
Definition: json.h:5386
std::tuple< Args... > from_json_tuple_impl_base(BasicJsonType &&j, index_sequence< Idx... >)
Definition: json.h:4633
decltype(std::declval< T >().template get< U >()) get_template_function
Definition: json.h:3297
decltype(std::declval< ObjectType & >().erase(std::declval< KeyType >())) detect_erase_with_key_type
Definition: json.h:3736
decltype(std::declval< StringType & >().append(std::declval< const Arg & >().begin(), std::declval< const Arg & >().end())) string_can_append_iter
Definition: json.h:3940
decltype(input_adapter(std::declval< const char * >(), std::declval< const char * >())) contiguous_bytes_input_adapter
Definition: json.h:6158
typename T::is_transparent detect_is_transparent
Definition: json.h:3703
decltype(std::declval< T & >().null()) null_function_t
Definition: json.h:8587
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.h:4953
iterator_input_adapter_factory< IteratorType >::adapter_type input_adapter(IteratorType first, IteratorType last)
Definition: json.h:6101
typename T::iterator_category iterator_category_t
Definition: json.h:3288
decltype(std::declval< T & >().number_float(std::declval< Float >(), std::declval< const String & >())) number_float_function_t
Definition: json.h:8603
std::size_t concat_length()
Definition: json.h:3893
is_detected< string_can_append_op, StringType, Arg > detect_string_can_append_op
Definition: json.h:3937
decltype(std::declval< StringType & >()+=std::declval< Arg && >()) string_can_append_op
Definition: json.h:3934
decltype(std::declval< T & >().end_array()) end_array_function_t
Definition: json.h:8629
void from_json(const BasicJsonType &j, std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > &m)
Definition: json.h:4698
std::pair< A1, A2 > from_json_tuple_impl(BasicJsonType &&j, identity_tag< std::pair< A1, A2 >>, priority_tag< 0 >)
Definition: json.h:4639
decltype(std::declval< T & >().end_object()) end_object_function_t
Definition: json.h:8622
T conditional_static_cast(U value)
Definition: json.h:3767
decltype(T::to_json(std::declval< Args >()...)) to_json_function
Definition: json.h:3291
typename T::value_type value_type_t
Definition: json.h:3276
namespace for Niels Lohmann
Definition: json.h:2165
basic_json<> json
default specialization
Definition: json.h:3196
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.h:23613
NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin)
bool operator!=(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
Definition: json.h:14090
bool operator==(json_pointer< RefStringTypeLhs > const &lhs, json_pointer< RefStringTypeRhs > const &rhs) noexcept
Definition: json.h:14083
Definition: json.h:4973
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects
Definition: json.h:23663
__le16 type
Definition: pwc-ioctl.h:0
default JSONSerializer template argument
Definition: json.h:5447
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.h:5451
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.h:5461
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.h:5471
typename BasicJsonType::default_object_comparator_t object_comparator_t
Definition: json.h:3364
typename std::conditional< has_key_compare< object_t >::value, typename object_t::key_compare, object_comparator_t >::type type
Definition: json.h:3366
typename BasicJsonType::object_t object_t
Definition: json.h:3363
std::false_type value_t
Definition: json.h:2198
static constexpr int kPrecision
Definition: json.h:16222
static diyfp normalize(diyfp x) noexcept
normalize x such that the significand is >= 2^(q-1)
Definition: json.h:16310
static diyfp normalize_to(const diyfp &x, const int target_exponent) noexcept
normalize x such that the result has the exponent E
Definition: json.h:16327
static diyfp mul(const diyfp &x, const diyfp &y) noexcept
returns x * y
Definition: json.h:16245
constexpr diyfp(std::uint64_t f_, int e_) noexcept
Definition: json.h:16227
static diyfp sub(const diyfp &x, const diyfp &y) noexcept
returns x - y
Definition: json.h:16233
static void construct(BasicJsonType &j, const CompatibleArrayType &arr)
Definition: json.h:5172
static void construct(BasicJsonType &j, const std::valarray< T > &arr)
Definition: json.h:5201
static void construct(BasicJsonType &j, const std::vector< bool > &arr)
Definition: json.h:5185
static void construct(BasicJsonType &j, typename BasicJsonType::array_t &&arr)
Definition: json.h:5160
static void construct(BasicJsonType &j, const typename BasicJsonType::array_t &arr)
Definition: json.h:5150
static void construct(BasicJsonType &j, const typename BasicJsonType::binary_t &b)
Definition: json.h:5089
static void construct(BasicJsonType &j, typename BasicJsonType::binary_t &&b)
Definition: json.h:5098
static void construct(BasicJsonType &j, typename BasicJsonType::boolean_t b) noexcept
Definition: json.h:5043
static void construct(BasicJsonType &j, typename BasicJsonType::number_float_t val) noexcept
Definition: json.h:5111
static void construct(BasicJsonType &j, typename BasicJsonType::number_integer_t val) noexcept
Definition: json.h:5137
static void construct(BasicJsonType &j, typename BasicJsonType::number_unsigned_t val) noexcept
Definition: json.h:5124
static void construct(BasicJsonType &j, typename BasicJsonType::object_t &&obj)
Definition: json.h:5230
static void construct(BasicJsonType &j, const typename BasicJsonType::object_t &obj)
Definition: json.h:5220
static void construct(BasicJsonType &j, const CompatibleObjectType &obj)
Definition: json.h:5241
static void construct(BasicJsonType &j, typename BasicJsonType::string_t &&s)
Definition: json.h:5065
static void construct(BasicJsonType &j, const CompatibleStringType &str)
Definition: json.h:5076
static void construct(BasicJsonType &j, const typename BasicJsonType::string_t &s)
Definition: json.h:5056
auto operator()(const BasicJsonType &j, T &&val) const noexcept(noexcept(from_json(j, std::forward< T >(val)))) -> decltype(from_json(j, std::forward< T >(val)))
Definition: json.h:4730
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.h:3316
typename BasicJsonType::template json_serializer< T, void > serializer
Definition: json.h:3346
static constexpr std::size_t size() noexcept
Definition: json.h:2952
primitive_iterator_t primitive_iterator
generic iterator for all other types
Definition: json.h:12331
BasicJsonType::array_t::iterator array_iterator
iterator for JSON arrays
Definition: json.h:12329
BasicJsonType::object_t::iterator object_iterator
iterator for JSON objects
Definition: json.h:12327
ConstructibleStringType laundered_type
Definition: json.h:3549
static constexpr bool value
Definition: json.h:3310
typename std::iterator_traits< T >::value_type value_type
Definition: json.h:6078
static one test(decltype(&C::capacity))
static constexpr bool value
Definition: json.h:3459
static constexpr bool value
Definition: json.h:8651
typename std::iterator_traits< iterator_type >::value_type char_type
Definition: json.h:6066
static adapter_type create(IteratorType first, IteratorType last)
Definition: json.h:6069
iterator_input_adapter< iterator_type > adapter_type
Definition: json.h:6067
nonesuch(nonesuch const &)=delete
void operator=(nonesuch &&)=delete
nonesuch(nonesuch const &&)=delete
void operator=(nonesuch const &)=delete
abstract output adapter interface
Definition: json.h:14220
virtual void write_characters(const CharType *s, std::size_t length)=0
virtual void write_character(CharType c)=0
output_adapter_protocol(output_adapter_protocol &&) noexcept=default
output_adapter_protocol(const output_adapter_protocol &)=default
struct to capture the start position of the current token
Definition: json.h:2872
std::size_t lines_read
the number of lines read
Definition: json.h:2878
std::size_t chars_read_current_line
the number of characters read in the current line
Definition: json.h:2876
std::size_t chars_read_total
the total number of characters read
Definition: json.h:2874
static constexpr T value
Definition: json.h:3040
auto operator()(BasicJsonType &j, T &&val) const noexcept(noexcept(to_json(j, std::forward< T >(val)))) -> decltype(to_json(j, std::forward< T >(val)), void())
Definition: json.h:5414
typename Extend< typename Gen< T, N/2 >::type, N/2, N % 2 >::type type
Definition: json.h:2991
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.h:5958
static void fill_buffer(BaseInputAdapter &input, std::array< std::char_traits< char >::int_type, 4 > &utf8_bytes, size_t &utf8_bytes_index, size_t &utf8_bytes_filled)
Definition: json.h:5900
SAX interface.
Definition: json.h:6242
virtual bool start_object(std::size_t elements)=0
the beginning of an object was read
virtual bool string(string_t &val)=0
a string value was read
typename BasicJsonType::number_integer_t number_integer_t
Definition: json.h:6243
typename BasicJsonType::binary_t binary_t
Definition: json.h:6247
virtual bool end_array()=0
the end of an array was read
virtual bool key(string_t &val)=0
an object key was read
typename BasicJsonType::number_unsigned_t number_unsigned_t
Definition: json.h:6244
virtual bool binary(binary_t &val)=0
a binary value was read
typename BasicJsonType::number_float_t number_float_t
Definition: json.h:6245
virtual bool start_array(std::size_t elements)=0
the beginning of an array was read
virtual bool parse_error(std::size_t position, const std::string &last_token, const detail::exception &ex)=0
a parse error occurred
json_sax(json_sax &&) noexcept=default
virtual bool boolean(bool val)=0
a boolean value was read
json_sax(const json_sax &)=default
virtual bool end_object()=0
the end of an object was read
virtual bool number_unsigned(number_unsigned_t val)=0
an unsigned integer number was read
typename BasicJsonType::string_t string_t
Definition: json.h:6246
virtual bool number_float(number_float_t val, const string_t &s)=0
a floating-point number was read
virtual bool number_integer(number_integer_t val)=0
an integer number was read
a minimal map-like container that preserves insertion order
Definition: json.h:18282
std::pair< iterator, bool > insert(const value_type &value)
Definition: json.h:18581
std::vector< std::pair< const Key, T >, Allocator > Container
Definition: json.h:18285
const_iterator find(const key_type &key) const
Definition: json.h:18564
iterator erase(iterator pos)
Definition: json.h:18454
void insert(InputIt first, InputIt last)
Definition: json.h:18599
size_type count(const key_type &key) const
Definition: json.h:18512
std::pair< iterator, bool > emplace(const key_type &key, T &&t)
Definition: json.h:18306
std::pair< iterator, bool > insert(value_type &&value)
Definition: json.h:18576
iterator erase(iterator first, iterator last)
Definition: json.h:18459
iterator find(KeyType &&key)
Definition: json.h:18552
typename Container::const_iterator const_iterator
Definition: json.h:18287
typename std::enable_if< std::is_convertible< typename std::iterator_traits< InputIt >::iterator_category, std::input_iterator_tag >::value >::type require_input_iter
Definition: json.h:18596
const T & at(const key_type &key) const
Definition: json.h:18386
T & at(KeyType &&key)
Definition: json.h:18373
T & at(const key_type &key)
Definition: json.h:18358
ordered_map(It first, It last, const Allocator &alloc=Allocator())
Definition: json.h:18301
std::equal_to< Key > key_compare
Definition: json.h:18293
const T & operator[](KeyType &&key) const
Definition: json.h:18353
ordered_map(const Allocator &alloc) noexcept(noexcept(Container(alloc)))
Definition: json.h:18299
typename Container::size_type size_type
Definition: json.h:18288
size_type erase(const key_type &key)
Definition: json.h:18414
typename Container::value_type value_type
Definition: json.h:18289
iterator find(const key_type &key)
Definition: json.h:18538
const T & operator[](const key_type &key) const
Definition: json.h:18346
T & operator[](KeyType &&key)
Definition: json.h:18341
T & operator[](const key_type &key)
Definition: json.h:18334
ordered_map(std::initializer_list< value_type > init, const Allocator &alloc=Allocator())
Definition: json.h:18303
ordered_map() noexcept(noexcept(Container()))
Definition: json.h:18298
size_type count(KeyType &&key) const
Definition: json.h:18526
const T & at(KeyType &&key) const
Definition: json.h:18401
std::pair< iterator, bool > emplace(KeyType &&key, T &&t)
Definition: json.h:18321
typename Container::iterator iterator
Definition: json.h:18286
size_type erase(KeyType &&key)
Definition: json.h:18435
std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL &j) const
Definition: json.h:23632
bool operator()(::nlohmann::detail::value_t lhs, ::nlohmann::detail::value_t rhs) const noexcept
compare two value_t enum values
Definition: json.h:23646
unsigned char byte
Definition: stvdriver.h:175